From 9f6e82720d415aba1e1ea5786d66a93ad3b85b10 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 12 May 2022 09:58:17 -0600 Subject: [PATCH 01/18] WIP: Enhance tracing in Peer - Add a bunch of events to Peer's async connection handling logic - Use an EnvFilter to allow more control over the verbosity level of tracing on a per-module basis - Wire up logging to emit trace events (we actually probably want to do this the other way around) Co-Authored-By: Antonio Scandurra --- Cargo.lock | 32 ++++++- crates/collab/Cargo.toml | 5 +- crates/collab/k8s/environments/production.sh | 3 +- crates/collab/k8s/environments/staging.sh | 3 +- crates/collab/k8s/manifest.template.yml | 2 - crates/collab/src/main.rs | 68 +++++++-------- crates/rpc/Cargo.toml | 1 + crates/rpc/src/peer.rs | 87 ++++++++++++++++++-- 8 files changed, 148 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57dcade5b9..8e9934e357 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -876,6 +876,7 @@ dependencies = [ "tonic", "tower", "tracing", + "tracing-log", "tracing-opentelemetry", "tracing-subscriber", "util", @@ -2588,6 +2589,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + [[package]] name = "matches" version = "0.1.8" @@ -3734,6 +3744,15 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.6.25" @@ -3856,6 +3875,7 @@ dependencies = [ "smol", "smol-timeout", "tempdir", + "tracing", "util", "zstd", ] @@ -5244,9 +5264,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.26" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" dependencies = [ "cfg-if 1.0.0", "log", @@ -5257,9 +5277,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.15" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" dependencies = [ "proc-macro2", "quote", @@ -5317,9 +5337,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596" dependencies = [ "ansi_term 0.12.1", + "lazy_static", + "matchers", + "regex", "sharded-slab", "smallvec", "thread_local", + "tracing", "tracing-core", "tracing-log", ] diff --git a/crates/collab/Cargo.toml b/crates/collab/Cargo.toml index a5541990d3..9fdab47d3e 100644 --- a/crates/collab/Cargo.toml +++ b/crates/collab/Cargo.toml @@ -44,9 +44,10 @@ tokio-tungstenite = "0.17" tonic = "0.6" tower = "0.4" toml = "0.5.8" -tracing = "0.1" +tracing = "0.1.34" +tracing-log = "0.1.3" tracing-opentelemetry = "0.17" -tracing-subscriber = "0.3" +tracing-subscriber = { version = "0.3.11", features = ["env-filter"] } [dependencies.sqlx] version = "0.5.2" diff --git a/crates/collab/k8s/environments/production.sh b/crates/collab/k8s/environments/production.sh index bac7fbedf7..039c1f60a5 100644 --- a/crates/collab/k8s/environments/production.sh +++ b/crates/collab/k8s/environments/production.sh @@ -1,3 +1,2 @@ ZED_ENVIRONMENT=production -RUST_LOG=info -TRACE_LEVEL=debug +RUST_LOG=info,rpc=debug diff --git a/crates/collab/k8s/environments/staging.sh b/crates/collab/k8s/environments/staging.sh index ed7121715d..ece0851ea1 100644 --- a/crates/collab/k8s/environments/staging.sh +++ b/crates/collab/k8s/environments/staging.sh @@ -1,3 +1,2 @@ ZED_ENVIRONMENT=staging -RUST_LOG=info -TRACE_LEVEL=debug +RUST_LOG=info,rpc=debug diff --git a/crates/collab/k8s/manifest.template.yml b/crates/collab/k8s/manifest.template.yml index 2e9f0ae298..73b20409fd 100644 --- a/crates/collab/k8s/manifest.template.yml +++ b/crates/collab/k8s/manifest.template.yml @@ -83,8 +83,6 @@ spec: key: token - name: RUST_LOG value: ${RUST_LOG} - - name: TRACE_LEVEL - value: ${TRACE_LEVEL} - name: HONEYCOMB_DATASET value: "collab" - name: HONEYCOMB_API_KEY diff --git a/crates/collab/src/main.rs b/crates/collab/src/main.rs index d7f8905a9a..772a518853 100644 --- a/crates/collab/src/main.rs +++ b/crates/collab/src/main.rs @@ -11,7 +11,9 @@ use std::{ net::{SocketAddr, TcpListener}, sync::Arc, }; -use tracing::metadata::LevelFilter; +use tracing_log::LogTracer; +use tracing_subscriber::filter::EnvFilter; +use util::ResultExt; #[derive(Default, Deserialize)] pub struct Config { @@ -20,7 +22,7 @@ pub struct Config { pub api_token: String, pub honeycomb_api_key: Option, pub honeycomb_dataset: Option, - pub trace_level: Option, + pub rust_log: Option, } pub struct AppState { @@ -41,8 +43,6 @@ impl AppState { #[tokio::main] async fn main() -> Result<()> { - env_logger::init(); - if let Err(error) = env::load_dotenv() { log::error!( "error loading .env.toml (this is expected in production): {}", @@ -119,42 +119,44 @@ pub fn init_tracing(config: &Config) -> Option<()> { use std::str::FromStr; use tracing_opentelemetry::OpenTelemetryLayer; use tracing_subscriber::layer::SubscriberExt; + let rust_trace = config.rust_log.clone()?; - let (honeycomb_api_key, honeycomb_dataset) = config + LogTracer::init().log_err()?; + + let open_telemetry_layer = config .honeycomb_api_key .clone() - .zip(config.honeycomb_dataset.clone())?; + .zip(config.honeycomb_dataset.clone()) + .map(|(honeycomb_api_key, honeycomb_dataset)| { + let mut metadata = tonic::metadata::MetadataMap::new(); + metadata.insert("x-honeycomb-team", honeycomb_api_key.parse().unwrap()); + let tracer = opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter( + opentelemetry_otlp::new_exporter() + .tonic() + .with_endpoint("https://api.honeycomb.io") + .with_metadata(metadata), + ) + .with_trace_config(opentelemetry::sdk::trace::config().with_resource( + opentelemetry::sdk::Resource::new(vec![KeyValue::new( + "service.name", + honeycomb_dataset, + )]), + )) + .install_batch(opentelemetry::runtime::Tokio) + .expect("failed to initialize tracing"); - let mut metadata = tonic::metadata::MetadataMap::new(); - metadata.insert("x-honeycomb-team", honeycomb_api_key.parse().unwrap()); - let tracer = opentelemetry_otlp::new_pipeline() - .tracing() - .with_exporter( - opentelemetry_otlp::new_exporter() - .tonic() - .with_endpoint("https://api.honeycomb.io") - .with_metadata(metadata), - ) - .with_trace_config(opentelemetry::sdk::trace::config().with_resource( - opentelemetry::sdk::Resource::new(vec![KeyValue::new( - "service.name", - honeycomb_dataset, - )]), - )) - .install_batch(opentelemetry::runtime::Tokio) - .expect("failed to initialize tracing"); + OpenTelemetryLayer::new(tracer) + }); let subscriber = tracing_subscriber::Registry::default() - .with(OpenTelemetryLayer::new(tracer)) - .with(tracing_subscriber::fmt::layer()) + .with(open_telemetry_layer) .with( - config - .trace_level - .as_ref() - .map_or(LevelFilter::INFO, |level| { - LevelFilter::from_str(level).unwrap() - }), - ); + tracing_subscriber::fmt::layer() + .event_format(tracing_subscriber::fmt::format().pretty()), + ) + .with(EnvFilter::from_str(rust_trace.as_str()).log_err()?); tracing::subscriber::set_global_default(subscriber).unwrap(); diff --git a/crates/rpc/Cargo.toml b/crates/rpc/Cargo.toml index 2750d9078f..7421a66312 100644 --- a/crates/rpc/Cargo.toml +++ b/crates/rpc/Cargo.toml @@ -28,6 +28,7 @@ rand = "0.8" rsa = "0.4" serde = { version = "1", features = ["derive"] } smol-timeout = "0.6" +tracing = "0.1.34" zstd = "0.9" [build-dependencies] diff --git a/crates/rpc/src/peer.rs b/crates/rpc/src/peer.rs index 7d7d1c7194..05f4b33f0e 100644 --- a/crates/rpc/src/peer.rs +++ b/crates/rpc/src/peer.rs @@ -9,6 +9,7 @@ use futures::{ stream::BoxStream, FutureExt, SinkExt, StreamExt, }; +use log::as_debug; use parking_lot::{Mutex, RwLock}; use smol_timeout::TimeoutExt; use std::sync::atomic::Ordering::SeqCst; @@ -22,6 +23,7 @@ use std::{ }, time::Duration, }; +use tracing::instrument; #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub struct ConnectionId(pub u32); @@ -108,6 +110,7 @@ impl Peer { }) } + #[instrument(skip_all)] pub async fn add_connection( self: &Arc, connection: Connection, @@ -145,9 +148,12 @@ impl Peer { let this = self.clone(); let response_channels = connection_state.response_channels.clone(); let handle_io = async move { + log::debug!(connection_id = connection_id.0; "handle io future: start"); + let _end_connection = util::defer(|| { response_channels.lock().take(); this.connections.write().remove(&connection_id); + log::debug!(connection_id = connection_id.0; "handle io future: end"); }); // Send messages on this frequency so the connection isn't closed. @@ -159,49 +165,68 @@ impl Peer { futures::pin_mut!(receive_timeout); loop { + log::debug!(connection_id = connection_id.0; "outer loop iteration start"); let read_message = reader.read().fuse(); futures::pin_mut!(read_message); loop { + log::debug!(connection_id = connection_id.0; "inner loop iteration start"); futures::select_biased! { outgoing = outgoing_rx.next().fuse() => match outgoing { Some(outgoing) => { + log::debug!(connection_id = connection_id.0; "outgoing rpc message: writing"); if let Some(result) = writer.write(outgoing).timeout(WRITE_TIMEOUT).await { + log::debug!(connection_id = connection_id.0; "outgoing rpc message: done writing"); result.context("failed to write RPC message")?; + log::debug!(connection_id = connection_id.0; "keepalive interval: resetting after sending message"); keepalive_timer.set(create_timer(KEEPALIVE_INTERVAL).fuse()); } else { + log::debug!(connection_id = connection_id.0; "outgoing rpc message: writing timed out"); Err(anyhow!("timed out writing message"))?; } } None => { - log::info!("outgoing channel closed"); + log::debug!(connection_id = connection_id.0; "outgoing rpc message: channel closed"); return Ok(()) }, }, incoming = read_message => { + log::debug!(connection_id = connection_id.0; "incoming rpc message: received"); let incoming = incoming.context("received invalid RPC message")?; + log::debug!(connection_id = connection_id.0; "receive timeout: resetting"); receive_timeout.set(create_timer(RECEIVE_TIMEOUT).fuse()); if let proto::Message::Envelope(incoming) = incoming { + log::debug!(connection_id = connection_id.0; "incoming rpc message: processing"); match incoming_tx.send(incoming).timeout(RECEIVE_TIMEOUT).await { - Some(Ok(_)) => {}, + Some(Ok(_)) => { + log::debug!(connection_id = connection_id.0; "incoming rpc message: processed"); + }, Some(Err(_)) => { - log::info!("incoming channel closed"); + log::debug!(connection_id = connection_id.0; "incoming rpc message: channel closed"); return Ok(()) }, - None => Err(anyhow!("timed out processing incoming message"))?, + None => { + log::debug!(connection_id = connection_id.0; "incoming rpc message: processing timed out"); + Err(anyhow!("timed out processing incoming message"))? + }, } } break; }, _ = keepalive_timer => { + log::debug!(connection_id = connection_id.0; "keepalive interval: pinging"); if let Some(result) = writer.write(proto::Message::Ping).timeout(WRITE_TIMEOUT).await { + log::debug!(connection_id = connection_id.0; "keepalive interval: done pinging"); result.context("failed to send keepalive")?; + log::debug!(connection_id = connection_id.0; "keepalive interval: resetting after pinging"); keepalive_timer.set(create_timer(KEEPALIVE_INTERVAL).fuse()); } else { + log::debug!(connection_id = connection_id.0; "keepalive interval: pinging timed out"); Err(anyhow!("timed out sending keepalive"))?; } } _ = receive_timeout => { + log::debug!(connection_id = connection_id.0; "receive timeout: delay between messages too long"); Err(anyhow!("delay between messages too long"))? } } @@ -217,25 +242,71 @@ impl Peer { let incoming_rx = incoming_rx.filter_map(move |incoming| { let response_channels = response_channels.clone(); async move { + let message_id = incoming.id; + log::debug!(incoming = as_debug!(&incoming); "incoming message future: start"); + let _end = util::defer(move || { + log::debug!( + connection_id = connection_id.0, + message_id = message_id; + "incoming message future: end" + ); + }); + if let Some(responding_to) = incoming.responding_to { + log::debug!( + connection_id = connection_id.0, + message_id = message_id, + responding_to = responding_to; + "incoming response: received" + ); let channel = response_channels.lock().as_mut()?.remove(&responding_to); if let Some(tx) = channel { let requester_resumed = oneshot::channel(); if let Err(error) = tx.send((incoming, requester_resumed.0)) { log::debug!( - "received RPC but request future was dropped {:?}", - error.0 + connection_id = connection_id.0, + message_id = message_id, + responding_to = responding_to, + error = as_debug!(error); + "incoming response: request future dropped", ); } + + log::debug!( + connection_id = connection_id.0, + message_id = message_id, + responding_to = responding_to; + "incoming response: waiting to resume requester" + ); let _ = requester_resumed.1.await; + log::debug!( + connection_id = connection_id.0, + message_id = message_id, + responding_to = responding_to; + "incoming response: requester resumed" + ); } else { - log::warn!("received RPC response to unknown request {}", responding_to); + log::warn!( + connection_id = connection_id.0, + message_id = message_id, + responding_to = responding_to; + "incoming response: unknown request" + ); } None } else { + log::debug!( + connection_id = connection_id.0, + message_id = message_id; + "incoming message: received" + ); proto::build_typed_envelope(connection_id, incoming).or_else(|| { - log::error!("unable to construct a typed envelope"); + log::error!( + connection_id = connection_id.0, + message_id = message_id; + "unable to construct a typed envelope" + ); None }) } From 9ca6e29a1762cff7895d598998b49685ae263b2b Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 12 May 2022 10:05:49 -0600 Subject: [PATCH 02/18] Use tracing instead of log in collab and rpc crates Co-Authored-By: Antonio Scandurra --- Cargo.lock | 1 - crates/collab/Cargo.toml | 3 +- crates/collab/src/main.rs | 2 +- crates/rpc/Cargo.toml | 1 - crates/rpc/src/peer.rs | 101 +++++++++++++++++++------------------- 5 files changed, 52 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e9934e357..9107bb287a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3865,7 +3865,6 @@ dependencies = [ "collections", "futures", "gpui", - "log", "parking_lot", "prost 0.8.0", "prost-build 0.8.0", diff --git a/crates/collab/Cargo.toml b/crates/collab/Cargo.toml index 9fdab47d3e..3ed2beca14 100644 --- a/crates/collab/Cargo.toml +++ b/crates/collab/Cargo.toml @@ -24,11 +24,9 @@ axum = { version = "0.5", features = ["json", "headers", "ws"] } base64 = "0.13" clap = { version = "3.1", features = ["derive"], optional = true } envy = "0.4.2" -env_logger = "0.8" futures = "0.3" lazy_static = "1.4" lipsum = { version = "0.8", optional = true } -log = { version = "0.4.16", features = ["kv_unstable_serde"] } opentelemetry = { version = "0.17", features = ["rt-tokio"] } opentelemetry-otlp = { version = "0.10", features = ["tls-roots"] } parking_lot = "0.11.1" @@ -60,6 +58,7 @@ rpc = { path = "../rpc", features = ["test-support"] } client = { path = "../client", features = ["test-support"] } editor = { path = "../editor", features = ["test-support"] } language = { path = "../language", features = ["test-support"] } +log = { version = "0.4.16", features = ["kv_unstable_serde"] } lsp = { path = "../lsp", features = ["test-support"] } project = { path = "../project", features = ["test-support"] } settings = { path = "../settings", features = ["test-support"] } diff --git a/crates/collab/src/main.rs b/crates/collab/src/main.rs index 772a518853..88cf98d64e 100644 --- a/crates/collab/src/main.rs +++ b/crates/collab/src/main.rs @@ -44,7 +44,7 @@ impl AppState { #[tokio::main] async fn main() -> Result<()> { if let Err(error) = env::load_dotenv() { - log::error!( + eprintln!( "error loading .env.toml (this is expected in production): {}", error ); diff --git a/crates/rpc/Cargo.toml b/crates/rpc/Cargo.toml index 7421a66312..ce24ede4ee 100644 --- a/crates/rpc/Cargo.toml +++ b/crates/rpc/Cargo.toml @@ -21,7 +21,6 @@ async-lock = "2.4" async-tungstenite = "0.16" base64 = "0.13" futures = "0.3" -log = { version = "0.4.16", features = ["kv_unstable_serde"] } parking_lot = "0.11.1" prost = "0.8" rand = "0.8" diff --git a/crates/rpc/src/peer.rs b/crates/rpc/src/peer.rs index 05f4b33f0e..7c183a98e6 100644 --- a/crates/rpc/src/peer.rs +++ b/crates/rpc/src/peer.rs @@ -9,7 +9,6 @@ use futures::{ stream::BoxStream, FutureExt, SinkExt, StreamExt, }; -use log::as_debug; use parking_lot::{Mutex, RwLock}; use smol_timeout::TimeoutExt; use std::sync::atomic::Ordering::SeqCst; @@ -148,12 +147,12 @@ impl Peer { let this = self.clone(); let response_channels = connection_state.response_channels.clone(); let handle_io = async move { - log::debug!(connection_id = connection_id.0; "handle io future: start"); + tracing::debug!(%connection_id, "handle io future: start"); let _end_connection = util::defer(|| { response_channels.lock().take(); this.connections.write().remove(&connection_id); - log::debug!(connection_id = connection_id.0; "handle io future: end"); + tracing::debug!(%connection_id, "handle io future: end"); }); // Send messages on this frequency so the connection isn't closed. @@ -165,48 +164,48 @@ impl Peer { futures::pin_mut!(receive_timeout); loop { - log::debug!(connection_id = connection_id.0; "outer loop iteration start"); + tracing::debug!(%connection_id, "outer loop iteration start"); let read_message = reader.read().fuse(); futures::pin_mut!(read_message); loop { - log::debug!(connection_id = connection_id.0; "inner loop iteration start"); + tracing::debug!(%connection_id, "inner loop iteration start"); futures::select_biased! { outgoing = outgoing_rx.next().fuse() => match outgoing { Some(outgoing) => { - log::debug!(connection_id = connection_id.0; "outgoing rpc message: writing"); + tracing::debug!(%connection_id, "outgoing rpc message: writing"); if let Some(result) = writer.write(outgoing).timeout(WRITE_TIMEOUT).await { - log::debug!(connection_id = connection_id.0; "outgoing rpc message: done writing"); + tracing::debug!(%connection_id, "outgoing rpc message: done writing"); result.context("failed to write RPC message")?; - log::debug!(connection_id = connection_id.0; "keepalive interval: resetting after sending message"); + tracing::debug!(%connection_id, "keepalive interval: resetting after sending message"); keepalive_timer.set(create_timer(KEEPALIVE_INTERVAL).fuse()); } else { - log::debug!(connection_id = connection_id.0; "outgoing rpc message: writing timed out"); + tracing::debug!(%connection_id, "outgoing rpc message: writing timed out"); Err(anyhow!("timed out writing message"))?; } } None => { - log::debug!(connection_id = connection_id.0; "outgoing rpc message: channel closed"); + tracing::debug!(%connection_id, "outgoing rpc message: channel closed"); return Ok(()) }, }, incoming = read_message => { - log::debug!(connection_id = connection_id.0; "incoming rpc message: received"); + tracing::debug!(%connection_id, "incoming rpc message: received"); let incoming = incoming.context("received invalid RPC message")?; - log::debug!(connection_id = connection_id.0; "receive timeout: resetting"); + tracing::debug!(%connection_id, "receive timeout: resetting"); receive_timeout.set(create_timer(RECEIVE_TIMEOUT).fuse()); if let proto::Message::Envelope(incoming) = incoming { - log::debug!(connection_id = connection_id.0; "incoming rpc message: processing"); + tracing::debug!(%connection_id, "incoming rpc message: processing"); match incoming_tx.send(incoming).timeout(RECEIVE_TIMEOUT).await { Some(Ok(_)) => { - log::debug!(connection_id = connection_id.0; "incoming rpc message: processed"); + tracing::debug!(%connection_id, "incoming rpc message: processed"); }, Some(Err(_)) => { - log::debug!(connection_id = connection_id.0; "incoming rpc message: channel closed"); + tracing::debug!(%connection_id, "incoming rpc message: channel closed"); return Ok(()) }, None => { - log::debug!(connection_id = connection_id.0; "incoming rpc message: processing timed out"); + tracing::debug!(%connection_id, "incoming rpc message: processing timed out"); Err(anyhow!("timed out processing incoming message"))? }, } @@ -214,19 +213,19 @@ impl Peer { break; }, _ = keepalive_timer => { - log::debug!(connection_id = connection_id.0; "keepalive interval: pinging"); + tracing::debug!(%connection_id, "keepalive interval: pinging"); if let Some(result) = writer.write(proto::Message::Ping).timeout(WRITE_TIMEOUT).await { - log::debug!(connection_id = connection_id.0; "keepalive interval: done pinging"); + tracing::debug!(%connection_id, "keepalive interval: done pinging"); result.context("failed to send keepalive")?; - log::debug!(connection_id = connection_id.0; "keepalive interval: resetting after pinging"); + tracing::debug!(%connection_id, "keepalive interval: resetting after pinging"); keepalive_timer.set(create_timer(KEEPALIVE_INTERVAL).fuse()); } else { - log::debug!(connection_id = connection_id.0; "keepalive interval: pinging timed out"); + tracing::debug!(%connection_id, "keepalive interval: pinging timed out"); Err(anyhow!("timed out sending keepalive"))?; } } _ = receive_timeout => { - log::debug!(connection_id = connection_id.0; "receive timeout: delay between messages too long"); + tracing::debug!(%connection_id, "receive timeout: delay between messages too long"); Err(anyhow!("delay between messages too long"))? } } @@ -243,68 +242,68 @@ impl Peer { let response_channels = response_channels.clone(); async move { let message_id = incoming.id; - log::debug!(incoming = as_debug!(&incoming); "incoming message future: start"); + tracing::debug!(?incoming, "incoming message future: start"); let _end = util::defer(move || { - log::debug!( - connection_id = connection_id.0, - message_id = message_id; + tracing::debug!( + %connection_id, + message_id, "incoming message future: end" ); }); if let Some(responding_to) = incoming.responding_to { - log::debug!( - connection_id = connection_id.0, - message_id = message_id, - responding_to = responding_to; + tracing::debug!( + %connection_id, + message_id, + responding_to, "incoming response: received" ); let channel = response_channels.lock().as_mut()?.remove(&responding_to); if let Some(tx) = channel { let requester_resumed = oneshot::channel(); if let Err(error) = tx.send((incoming, requester_resumed.0)) { - log::debug!( - connection_id = connection_id.0, - message_id = message_id, + tracing::debug!( + %connection_id, + message_id, responding_to = responding_to, - error = as_debug!(error); + ?error, "incoming response: request future dropped", ); } - log::debug!( - connection_id = connection_id.0, - message_id = message_id, - responding_to = responding_to; + tracing::debug!( + %connection_id, + message_id, + responding_to, "incoming response: waiting to resume requester" ); let _ = requester_resumed.1.await; - log::debug!( - connection_id = connection_id.0, - message_id = message_id, - responding_to = responding_to; + tracing::debug!( + %connection_id, + message_id, + responding_to, "incoming response: requester resumed" ); } else { - log::warn!( - connection_id = connection_id.0, - message_id = message_id, - responding_to = responding_to; + tracing::warn!( + %connection_id, + message_id, + responding_to, "incoming response: unknown request" ); } None } else { - log::debug!( - connection_id = connection_id.0, - message_id = message_id; + tracing::debug!( + %connection_id, + message_id, "incoming message: received" ); proto::build_typed_envelope(connection_id, incoming).or_else(|| { - log::error!( - connection_id = connection_id.0, - message_id = message_id; + tracing::error!( + %connection_id, + message_id, "unable to construct a typed envelope" ); None From e795a7a578679caf509a602dc38271527b3c1978 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 12 May 2022 10:16:50 -0600 Subject: [PATCH 03/18] =?UTF-8?q?=F0=9F=92=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Antonio Scandurra Co-Authored-By: Max Brunsfeld --- crates/collab/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/collab/src/main.rs b/crates/collab/src/main.rs index 88cf98d64e..bd9f8fd69d 100644 --- a/crates/collab/src/main.rs +++ b/crates/collab/src/main.rs @@ -119,7 +119,7 @@ pub fn init_tracing(config: &Config) -> Option<()> { use std::str::FromStr; use tracing_opentelemetry::OpenTelemetryLayer; use tracing_subscriber::layer::SubscriberExt; - let rust_trace = config.rust_log.clone()?; + let rust_log = config.rust_log.clone()?; LogTracer::init().log_err()?; @@ -156,7 +156,7 @@ pub fn init_tracing(config: &Config) -> Option<()> { tracing_subscriber::fmt::layer() .event_format(tracing_subscriber::fmt::format().pretty()), ) - .with(EnvFilter::from_str(rust_trace.as_str()).log_err()?); + .with(EnvFilter::from_str(rust_log.as_str()).log_err()?); tracing::subscriber::set_global_default(subscriber).unwrap(); From de555e3423d7769c1dc50496e8360f2ed28dfa46 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 12 May 2022 10:17:37 -0600 Subject: [PATCH 04/18] Enable logging of rpc crate trace events when no subscriber is present This allows these events to be logged in the Zed client (until we setup tracing there). Co-Authored-By: Antonio Scandurra Co-Authored-By: Max Brunsfeld --- crates/rpc/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/Cargo.toml b/crates/rpc/Cargo.toml index ce24ede4ee..da01816931 100644 --- a/crates/rpc/Cargo.toml +++ b/crates/rpc/Cargo.toml @@ -27,7 +27,7 @@ rand = "0.8" rsa = "0.4" serde = { version = "1", features = ["derive"] } smol-timeout = "0.6" -tracing = "0.1.34" +tracing = { version = "0.1.34", features = ["log"] } zstd = "0.9" [build-dependencies] From 3226e07dcc9dc9ec880b32b58b44834844158fc7 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 12 May 2022 11:37:33 -0600 Subject: [PATCH 05/18] Remove commented method --- crates/collab/src/rpc.rs | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index ecd3847945..9de8db1fb8 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -1116,29 +1116,6 @@ impl Server { Ok(()) } - // #[instrument(skip(self, state, user_ids))] - // fn update_contacts_for_users<'a>( - // self: &Arc, - // state: &Store, - // user_ids: impl IntoIterator, - // ) { - // for user_id in user_ids { - // let contacts = state.contacts_for_user(*user_id); - // for connection_id in state.connection_ids_for_user(*user_id) { - // self.peer - // .send( - // connection_id, - // proto::UpdateContacts { - // contacts: contacts.clone(), - // pending_requests_from_user_ids: Default::default(), - // pending_requests_to_user_ids: Default::default(), - // }, - // ) - // .trace_err(); - // } - // } - // } - async fn join_channel( self: Arc, request: TypedEnvelope, From a3b9ad75b0fac966c37a93cc290d3032fd6e03d9 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 12 May 2022 12:06:06 -0600 Subject: [PATCH 06/18] Include login in connection-related tracing spans/events Also, include metadata on more events and add an event called "signing out" with all this metadata to make it easier to search for. --- crates/collab/src/auth.rs | 9 +++++++-- crates/collab/src/rpc.rs | 33 ++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/crates/collab/src/auth.rs b/crates/collab/src/auth.rs index aad331faec..686a07bbf5 100644 --- a/crates/collab/src/auth.rs +++ b/crates/collab/src/auth.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use super::db::{self, UserId}; use crate::{AppState, Error}; -use anyhow::{Context, Result}; +use anyhow::{anyhow, Context, Result}; use axum::{ http::{self, Request, StatusCode}, middleware::Next, @@ -51,7 +51,12 @@ pub async fn validate_header(mut req: Request, next: Next) -> impl Into } if credentials_valid { - req.extensions_mut().insert(user_id); + let user = state + .db + .get_user_by_id(user_id) + .await? + .ok_or_else(|| anyhow!("user {} not found", user_id))?; + req.extensions_mut().insert(user); Ok::<_, Error>(next.run(req).await) } else { Err(Error::Http( diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 9de8db1fb8..06e2b6e228 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -2,7 +2,7 @@ mod store; use crate::{ auth, - db::{self, ChannelId, MessageId, UserId}, + db::{self, ChannelId, MessageId, User, UserId}, AppState, Result, }; use anyhow::anyhow; @@ -49,7 +49,7 @@ use tokio::{ time::Sleep, }; use tower::ServiceBuilder; -use tracing::{info_span, Instrument}; +use tracing::{info_span, instrument, Instrument}; type MessageHandler = Box, Box) -> BoxFuture<'static, ()>>; @@ -244,12 +244,14 @@ impl Server { self: &Arc, connection: Connection, address: String, - user_id: UserId, + user: User, mut send_connection_id: Option>, executor: E, ) -> impl Future> { let mut this = self.clone(); - let span = info_span!("handle connection", %user_id, %address); + let user_id = user.id; + let login = user.github_login; + let span = info_span!("handle connection", %user_id, %login, %address); async move { let (connection_id, handle_io, mut incoming_rx) = this .peer @@ -264,7 +266,7 @@ impl Server { }) .await; - tracing::info!(%user_id, %connection_id, %address, "connection opened"); + tracing::info!(%user_id, %login, %connection_id, %address, "connection opened"); if let Some(send_connection_id) = send_connection_id.as_mut() { let _ = send_connection_id.send(connection_id).await; @@ -287,14 +289,14 @@ impl Server { futures::select_biased! { result = handle_io => { if let Err(error) = result { - tracing::error!(%error, "error handling I/O"); + tracing::error!(%error, %user_id, %login, %connection_id, %address, "error handling I/O"); } break; } message = next_message => { if let Some(message) = message { let type_name = message.payload_type_name(); - let span = tracing::info_span!("receive message", %user_id, %connection_id, %address, type_name); + let span = tracing::info_span!("receive message", %user_id, %login, %connection_id, %address, type_name); async { if let Some(handler) = this.handlers.get(&message.payload_type_id()) { let notifications = this.notifications.clone(); @@ -312,25 +314,27 @@ impl Server { handle_message.await; } } else { - tracing::error!("no message handler"); + tracing::error!(%user_id, %login, %connection_id, %address, "no message handler"); } }.instrument(span).await; } else { - tracing::info!(%user_id, %connection_id, %address, "connection closed"); + tracing::info!(%user_id, %login, %connection_id, %address, "connection closed"); break; } } } } + tracing::info!(%user_id, %login, %connection_id, %address, "signing out"); if let Err(error) = this.sign_out(connection_id).await { - tracing::error!(%error, "error signing out"); + tracing::error!(%user_id, %login, %connection_id, %address, %error, "error signing out"); } Ok(()) }.instrument(span) } + #[instrument(skip(self), err)] async fn sign_out(self: &mut Arc, connection_id: ConnectionId) -> Result<()> { self.peer.disconnect(connection_id); let removed_connection = self.store_mut().await.remove_connection(connection_id)?; @@ -1420,7 +1424,7 @@ pub async fn handle_websocket_request( TypedHeader(ProtocolVersion(protocol_version)): TypedHeader, ConnectInfo(socket_address): ConnectInfo, Extension(server): Extension>, - Extension(user_id): Extension, + Extension(user): Extension, ws: WebSocketUpgrade, ) -> axum::response::Response { if protocol_version != rpc::PROTOCOL_VERSION { @@ -1440,7 +1444,7 @@ pub async fn handle_websocket_request( let connection = Connection::new(Box::pin(socket)); async move { server - .handle_connection(connection, socket_address, user_id, None, RealExecutor) + .handle_connection(connection, socket_address, user, None, RealExecutor) .await .log_err(); } @@ -6451,6 +6455,7 @@ mod tests { let client_name = name.to_string(); let mut client = Client::new(http.clone()); let server = self.server.clone(); + let db = self.app_state.db.clone(); let connection_killers = self.connection_killers.clone(); let forbid_connections = self.forbid_connections.clone(); let (connection_id_tx, mut connection_id_rx) = mpsc::channel(16); @@ -6471,6 +6476,7 @@ mod tests { assert_eq!(credentials.access_token, "the-token"); let server = server.clone(); + let db = db.clone(); let connection_killers = connection_killers.clone(); let forbid_connections = forbid_connections.clone(); let client_name = client_name.clone(); @@ -6484,11 +6490,12 @@ mod tests { let (client_conn, server_conn, killed) = Connection::in_memory(cx.background()); connection_killers.lock().insert(user_id, killed); + let user = db.get_user_by_id(user_id).await.unwrap().unwrap(); cx.background() .spawn(server.handle_connection( server_conn, client_name, - user_id, + user, Some(connection_id_tx), cx.background(), )) From 451338061dc7d59499a10d556fd05bc9462586cb Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 12 May 2022 13:05:05 -0600 Subject: [PATCH 07/18] Try to improve tracing messages when client disconnects --- crates/collab/src/rpc.rs | 4 ++-- crates/rpc/src/peer.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 06e2b6e228..f5cf0e10dc 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -289,7 +289,7 @@ impl Server { futures::select_biased! { result = handle_io => { if let Err(error) = result { - tracing::error!(%error, %user_id, %login, %connection_id, %address, "error handling I/O"); + tracing::error!(?error, %user_id, %login, %connection_id, %address, "error handling I/O"); } break; } @@ -327,7 +327,7 @@ impl Server { tracing::info!(%user_id, %login, %connection_id, %address, "signing out"); if let Err(error) = this.sign_out(connection_id).await { - tracing::error!(%user_id, %login, %connection_id, %address, %error, "error signing out"); + tracing::error!(%user_id, %login, %connection_id, %address, ?error, "error signing out"); } Ok(()) diff --git a/crates/rpc/src/peer.rs b/crates/rpc/src/peer.rs index 7c183a98e6..2fcc5dc09b 100644 --- a/crates/rpc/src/peer.rs +++ b/crates/rpc/src/peer.rs @@ -190,8 +190,8 @@ impl Peer { }, }, incoming = read_message => { + let incoming = incoming.context("error reading rpc message from socket")?; tracing::debug!(%connection_id, "incoming rpc message: received"); - let incoming = incoming.context("received invalid RPC message")?; tracing::debug!(%connection_id, "receive timeout: resetting"); receive_timeout.set(create_timer(RECEIVE_TIMEOUT).fuse()); if let proto::Message::Envelope(incoming) = incoming { From 02e39e756bcd2bd8b31e49e715351ed252a4d790 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 12 May 2022 14:46:33 -0600 Subject: [PATCH 08/18] 0.33.0 --- Cargo.lock | 2 +- crates/zed/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 550b390995..958d135103 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6009,7 +6009,7 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" [[package]] name = "zed" -version = "0.32.0" +version = "0.33.0" dependencies = [ "anyhow", "assets", diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index bdc6566619..dd421b64f6 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Nathan Sobo "] description = "The fast, collaborative code editor." edition = "2021" name = "zed" -version = "0.32.0" +version = "0.33.0" [lib] name = "zed" From a620665bedd00f5cfe11c1b0024a6b99085d3d79 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 13 May 2022 13:57:39 -0600 Subject: [PATCH 09/18] Only synthesize mouse moves on scene construction if window is active --- crates/gpui/src/app.rs | 7 +++++++ crates/gpui/src/presenter.rs | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 3aba2cbffb..4fc5dc564c 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1005,6 +1005,13 @@ impl MutableAppContext { .and_then(|window| window.root_view.clone().downcast::()) } + pub fn window_is_active(&self, window_id: usize) -> bool { + self.cx + .windows + .get(&window_id) + .map_or(false, |window| window.is_active) + } + pub fn render_view( &mut self, window_id: usize, diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index a7d715fadf..451f14567a 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -122,8 +122,10 @@ impl Presenter { self.text_layout_cache.finish_frame(); self.cursor_styles = scene.cursor_styles(); - if let Some(event) = self.last_mouse_moved_event.clone() { - self.dispatch_event(event, cx) + if cx.window_is_active(self.window_id) { + if let Some(event) = self.last_mouse_moved_event.clone() { + self.dispatch_event(event, cx) + } } } else { log::error!("could not find root_view_id for window {}", self.window_id); From c9dcfff60745dcc46cf0e64afe61c7bd838578af Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Thu, 5 May 2022 21:09:26 -0700 Subject: [PATCH 10/18] Move selection helpers to SelectionCollection, add update_anchor_selections, add a number of invariant preserving mutation functions to the MutableSelectionCollection --- crates/breadcrumbs/src/breadcrumbs.rs | 2 +- crates/collab/src/rpc.rs | 20 +- crates/diagnostics/src/diagnostics.rs | 11 +- crates/diagnostics/src/items.rs | 4 +- crates/editor/src/editor.rs | 2274 +++++++---------- crates/editor/src/element.rs | 8 +- crates/editor/src/items.rs | 22 +- crates/editor/src/selections_collection.rs | 703 +++++ crates/editor/src/test.rs | 2 +- crates/go_to_line/src/go_to_line.rs | 6 +- crates/journal/src/journal.rs | 4 +- crates/outline/src/outline.rs | 8 +- crates/project_symbols/src/project_symbols.rs | 8 +- crates/search/src/buffer_search.rs | 46 +- crates/search/src/project_search.rs | 18 +- crates/vim/src/insert.rs | 8 +- crates/vim/src/normal.rs | 38 +- crates/vim/src/normal/change.rs | 27 +- crates/vim/src/normal/delete.rs | 28 +- crates/vim/src/vim_test_context.rs | 7 +- crates/vim/src/visual.rs | 76 +- crates/zed/src/zed.rs | 38 +- 22 files changed, 1891 insertions(+), 1467 deletions(-) create mode 100644 crates/editor/src/selections_collection.rs diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs index b2bba37e38..bbd11deac8 100644 --- a/crates/breadcrumbs/src/breadcrumbs.rs +++ b/crates/breadcrumbs/src/breadcrumbs.rs @@ -37,7 +37,7 @@ impl Breadcrumbs { cx: &AppContext, ) -> Option<(ModelHandle, Vec>)> { let editor = self.editor.as_ref()?.read(cx); - let cursor = editor.newest_anchor_selection().head(); + let cursor = editor.selections.newest_anchor().head(); let multibuffer = &editor.buffer().read(cx); let (buffer_id, symbols) = multibuffer .read(cx) diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 33d1d52677..1536ceae92 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -3001,7 +3001,7 @@ mod tests { // Type a completion trigger character as the guest. editor_b.update(cx_b, |editor, cx| { - editor.select_ranges([13..13], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([13..13], None)); editor.handle_input(&Input(".".into()), cx); cx.focus(&editor_b); }); @@ -4213,7 +4213,9 @@ mod tests { // Move cursor to a location that contains code actions. editor_b.update(cx_b, |editor, cx| { - editor.select_ranges([Point::new(1, 31)..Point::new(1, 31)], None, cx); + editor.change_selections(true, cx, |s| { + s.select_ranges([Point::new(1, 31)..Point::new(1, 31)], None) + }); cx.focus(&editor_b); }); @@ -4450,7 +4452,7 @@ mod tests { // Move cursor to a location that can be renamed. let prepare_rename = editor_b.update(cx_b, |editor, cx| { - editor.select_ranges([7..7], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([7..7], None)); editor.rename(&Rename, cx).unwrap() }); @@ -5470,8 +5472,12 @@ mod tests { }); // When client B starts following client A, all visible view states are replicated to client B. - editor_a1.update(cx_a, |editor, cx| editor.select_ranges([0..1], None, cx)); - editor_a2.update(cx_a, |editor, cx| editor.select_ranges([2..3], None, cx)); + editor_a1.update(cx_a, |editor, cx| { + editor.change_selections(true, cx, |s| s.select_ranges([0..1], None)) + }); + editor_a2.update(cx_a, |editor, cx| { + editor.change_selections(true, cx, |s| s.select_ranges([2..3], None)) + }); workspace_b .update(cx_b, |workspace, cx| { workspace @@ -5536,7 +5542,7 @@ mod tests { // Changes to client A's editor are reflected on client B. editor_a1.update(cx_a, |editor, cx| { - editor.select_ranges([1..1, 2..2], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([1..1, 2..2], None)); }); editor_b1 .condition(cx_b, |editor, cx| { @@ -5550,7 +5556,7 @@ mod tests { .await; editor_a1.update(cx_a, |editor, cx| { - editor.select_ranges([3..3], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([3..3], None)); editor.set_scroll_position(vec2f(0., 100.), cx); }); editor_b1 diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index eb8fae2ab2..31807f07d8 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -417,8 +417,11 @@ impl ProjectDiagnosticsEditor { }]; } else { groups = self.path_states.get(path_ix)?.diagnostic_groups.as_slice(); - new_excerpt_ids_by_selection_id = editor.refresh_selections(cx); - selections = editor.local_selections::(cx); + new_excerpt_ids_by_selection_id = + editor.change_selections(true, cx, |s| s.refresh()); + selections = editor + .selections + .interleaved::(&editor.buffer().read(cx).read(cx)); } // If any selection has lost its position, move it to start of the next primary diagnostic. @@ -441,7 +444,9 @@ impl ProjectDiagnosticsEditor { } } } - editor.update_selections(selections, None, cx); + editor.change_selections(true, cx, |s| { + s.select(selections, None); + }); Some(()) }); diff --git a/crates/diagnostics/src/items.rs b/crates/diagnostics/src/items.rs index ef99cbf5a8..abc0b13181 100644 --- a/crates/diagnostics/src/items.rs +++ b/crates/diagnostics/src/items.rs @@ -58,9 +58,7 @@ impl DiagnosticIndicator { fn update(&mut self, editor: ViewHandle, cx: &mut ViewContext) { let editor = editor.read(cx); let buffer = editor.buffer().read(cx); - let cursor_position = editor - .newest_selection_with_snapshot::(&buffer.read(cx)) - .head(); + let cursor_position = editor.selections.newest::(&buffer.read(cx)).head(); let new_diagnostic = buffer .read(cx) .diagnostics_in_range::<_, usize>(cursor_position..cursor_position, false) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index a9a95280d8..b01bee0ab4 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -3,6 +3,7 @@ mod element; pub mod items; pub mod movement; mod multi_buffer; +mod selections_collection; #[cfg(test)] mod test; @@ -28,7 +29,6 @@ use gpui::{ ModelHandle, MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; -use itertools::Itertools as _; pub use language::{char_kind, CharKind}; use language::{ BracketPair, Buffer, CodeAction, CodeLabel, Completion, Diagnostic, DiagnosticSeverity, @@ -40,6 +40,7 @@ pub use multi_buffer::{ }; use ordered_float::OrderedFloat; use project::{Project, ProjectTransaction}; +use selections_collection::{resolve_multiple, MutableSelectionsCollection, SelectionsCollection}; use serde::{Deserialize, Serialize}; use settings::Settings; use smallvec::SmallVec; @@ -49,8 +50,7 @@ use std::{ any::TypeId, borrow::Cow, cmp::{self, Ordering, Reverse}, - iter::{self, FromIterator}, - mem, + iter, mem, ops::{Deref, DerefMut, Range, RangeInclusive, Sub}, sync::Arc, time::{Duration, Instant}, @@ -377,9 +377,7 @@ pub struct Editor { handle: WeakViewHandle, buffer: ModelHandle, display_map: ModelHandle, - next_selection_id: usize, - selections: Arc<[Selection]>, - pending_selection: Option, + pub selections: SelectionsCollection, columnar_selection_tail: Option, add_selections_state: Option, select_next_state: Option, @@ -429,13 +427,7 @@ pub struct EditorSnapshot { scroll_top_anchor: Anchor, } -#[derive(Clone)] -pub struct PendingSelection { - selection: Selection, - mode: SelectMode, -} - -#[derive(Clone)] +#[derive(Clone, Debug)] struct SelectionHistoryEntry { selections: Arc<[Selection]>, select_next_state: Option, @@ -527,13 +519,13 @@ impl SelectionHistory { } } -#[derive(Clone)] +#[derive(Clone, Debug)] struct AddSelectionsState { above: bool, stack: Vec, } -#[derive(Clone)] +#[derive(Clone, Debug)] struct SelectNextState { query: AhoCorasick, wordwise: bool, @@ -949,19 +941,8 @@ impl Editor { handle: cx.weak_handle(), buffer, display_map, - selections: Arc::from([]), - pending_selection: Some(PendingSelection { - selection: Selection { - id: 0, - start: Anchor::min(), - end: Anchor::min(), - reversed: false, - goal: SelectionGoal::None, - }, - mode: SelectMode::Character, - }), + selections: SelectionsCollection::new(), columnar_selection_tail: None, - next_selection_id: 1, add_selections_state: None, select_next_state: None, selection_history: Default::default(), @@ -1204,12 +1185,15 @@ impl Editor { first_cursor_top = highlighted_rows.start as f32; last_cursor_bottom = first_cursor_top + 1.; } else if autoscroll == Autoscroll::Newest { - let newest_selection = - self.newest_selection_with_snapshot::(&display_map.buffer_snapshot); + let newest_selection = self + .selections + .newest::(&display_map.buffer_snapshot); first_cursor_top = newest_selection.head().to_display_point(&display_map).row() as f32; last_cursor_bottom = first_cursor_top + 1.; } else { - let selections = self.local_selections::(cx); + let selections = self + .selections + .interleaved::(&display_map.buffer_snapshot); first_cursor_top = selections .first() .unwrap() @@ -1269,7 +1253,9 @@ impl Editor { cx: &mut ViewContext, ) -> bool { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = self.local_selections::(cx); + let selections = self + .selections + .interleaved::(&display_map.buffer_snapshot); let mut target_left; let mut target_right; @@ -1318,22 +1304,91 @@ impl Editor { } } - pub fn replace_selections_with( + pub fn change_selections( &mut self, + local: bool, cx: &mut ViewContext, - mut find_replacement: impl FnMut(&DisplaySnapshot) -> DisplayPoint, - ) { - let display_map = self.snapshot(cx); - let cursor = find_replacement(&display_map); - let selection = Selection { - id: post_inc(&mut self.next_selection_id), - start: cursor, - end: cursor, - reversed: false, - goal: SelectionGoal::None, + change: impl FnOnce(&mut MutableSelectionsCollection<'_>) -> R, + ) -> R { + let old_cursor_position = self.selections.newest_anchor().head(); + self.push_to_selection_history(); + + #[allow(deprecated)] + // Using deprecated to prevent using change_with outside of this function + let (autoscroll, result) = + self.selections + .change_with(self.display_map.clone(), self.buffer.clone(), cx, change); + + if let Some(autoscroll) = autoscroll { + self.request_autoscroll(autoscroll, cx); } - .map(|display_point| display_point.to_point(&display_map)); - self.update_selections(vec![selection], None, cx); + + if self.focused && self.leader_replica_id.is_none() { + self.buffer.update(cx, |buffer, cx| { + buffer.set_active_selections(&self.selections.disjoint_anchors(), cx) + }); + } + + let display_map = self + .display_map + .update(cx, |display_map, cx| display_map.snapshot(cx)); + let buffer = &display_map.buffer_snapshot; + self.add_selections_state = None; + self.select_next_state = None; + self.select_larger_syntax_node_stack.clear(); + self.autoclose_stack + .invalidate(&self.selections.disjoint_anchors(), &buffer); + self.snippet_stack + .invalidate(&self.selections.disjoint_anchors(), &buffer); + self.take_rename(false, cx); + + let new_cursor_position = self.selections.newest_anchor().head(); + + self.push_to_nav_history( + old_cursor_position.clone(), + Some(new_cursor_position.to_point(&buffer)), + cx, + ); + + if local { + let completion_menu = match self.context_menu.as_mut() { + Some(ContextMenu::Completions(menu)) => Some(menu), + _ => { + self.context_menu.take(); + None + } + }; + + if let Some(completion_menu) = completion_menu { + let cursor_position = new_cursor_position.to_offset(&buffer); + let (word_range, kind) = + buffer.surrounding_word(completion_menu.initial_position.clone()); + if kind == Some(CharKind::Word) + && word_range.to_inclusive().contains(&cursor_position) + { + let query = Self::completion_query(&buffer, cursor_position); + cx.background() + .block(completion_menu.filter(query.as_deref(), cx.background().clone())); + self.show_completions(&ShowCompletions, cx); + } else { + self.hide_context_menu(cx); + } + } + + if old_cursor_position.to_display_point(&display_map).row() + != new_cursor_position.to_display_point(&display_map).row() + { + self.available_code_actions.take(); + } + self.refresh_code_actions(cx); + self.refresh_document_highlights(cx); + } + + self.pause_cursor_blinking(cx); + cx.emit(Event::SelectionsChanged { local }); + cx.notify(); + + result } pub fn display_selections( @@ -1342,61 +1397,14 @@ impl Editor { ) -> (DisplaySnapshot, Vec>) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let selections = self - .local_selections::(cx) + .selections + .interleaved::(&display_map.buffer_snapshot) .into_iter() .map(|selection| selection.map(|point| point.to_display_point(&display_map))) .collect(); (display_map, selections) } - pub fn move_selections( - &mut self, - cx: &mut ViewContext, - mut move_selection: impl FnMut(&DisplaySnapshot, &mut Selection), - ) { - let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = self - .local_selections::(cx) - .into_iter() - .map(|selection| { - let mut selection = selection.map(|point| point.to_display_point(&display_map)); - move_selection(&display_map, &mut selection); - selection.map(|display_point| display_point.to_point(&display_map)) - }) - .collect(); - self.update_selections(selections, Some(Autoscroll::Fit), cx); - } - - pub fn move_selection_heads( - &mut self, - cx: &mut ViewContext, - mut update_head: impl FnMut( - &DisplaySnapshot, - DisplayPoint, - SelectionGoal, - ) -> (DisplayPoint, SelectionGoal), - ) { - self.move_selections(cx, |map, selection| { - let (new_head, new_goal) = update_head(map, selection.head(), selection.goal); - selection.set_head(new_head, new_goal); - }); - } - - pub fn move_cursors( - &mut self, - cx: &mut ViewContext, - mut update_cursor_position: impl FnMut( - &DisplaySnapshot, - DisplayPoint, - SelectionGoal, - ) -> (DisplayPoint, SelectionGoal), - ) { - self.move_selections(cx, |map, selection| { - let (cursor, new_goal) = update_cursor_position(map, selection.head(), selection.goal); - selection.collapse_to(cursor, new_goal) - }); - } - pub fn edit(&mut self, edits: I, cx: &mut ViewContext) where I: IntoIterator, T)>, @@ -1450,29 +1458,34 @@ impl Editor { ) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let tail = self - .newest_selection_with_snapshot::(&display_map.buffer_snapshot) + .selections + .newest::(&display_map.buffer_snapshot) .tail(); self.begin_selection(position, false, click_count, cx); let position = position.to_offset(&display_map, Bias::Left); let tail_anchor = display_map.buffer_snapshot.anchor_before(tail); - let mut pending = self.pending_selection.clone().unwrap(); - if position >= tail { - pending.selection.start = tail_anchor.clone(); - } else { - pending.selection.end = tail_anchor.clone(); - pending.selection.reversed = true; - } + self.change_selections(true, cx, |s| { + let mut pending = s + .pending_mut() + .as_mut() + .expect("extend_selection not called with pending selection"); - match &mut pending.mode { - SelectMode::Word(range) | SelectMode::Line(range) => { - *range = tail_anchor.clone()..tail_anchor + if position >= tail { + pending.selection.start = tail_anchor.clone(); + } else { + pending.selection.end = tail_anchor.clone(); + pending.selection.reversed = true; } - _ => {} - } - self.set_selections(self.selections.clone(), Some(pending), true, cx); + match &mut pending.mode { + SelectMode::Word(range) | SelectMode::Line(range) => { + *range = tail_anchor.clone()..tail_anchor + } + _ => {} + } + }); } fn begin_selection( @@ -1489,7 +1502,7 @@ impl Editor { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = &display_map.buffer_snapshot; - let newest_selection = self.newest_anchor_selection().clone(); + let newest_selection = self.selections.newest_anchor().clone(); let position = display_map.clip_point(position, Bias::Left); let start; @@ -1527,38 +1540,17 @@ impl Editor { } } - let selection = Selection { - id: post_inc(&mut self.next_selection_id), - start, - end, - reversed: false, - goal: SelectionGoal::None, - }; - - let mut selections; - if add { - selections = self.selections.clone(); - // Remove the newest selection if it was added due to a previous mouse up - // within this multi-click. - if click_count > 1 { - selections = self - .selections - .iter() - .filter(|selection| selection.id != newest_selection.id) - .cloned() - .collect(); + self.change_selections(true, cx, |s| { + if add { + if click_count > 1 { + s.delete(newest_selection.id); + } + } else { + s.clear_disjoint(); } - } else { - selections = Arc::from([]); - } - self.set_selections( - selections, - Some(PendingSelection { selection, mode }), - true, - cx, - ); - cx.notify(); + s.set_pending_range(start..end, mode); + }); } fn begin_columnar_selection( @@ -1574,7 +1566,8 @@ impl Editor { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let tail = self - .newest_selection_with_snapshot::(&display_map.buffer_snapshot) + .selections + .newest::(&display_map.buffer_snapshot) .tail(); self.columnar_selection_tail = Some(display_map.buffer_snapshot.anchor_before(tail)); @@ -1599,14 +1592,14 @@ impl Editor { if let Some(tail) = self.columnar_selection_tail.as_ref() { let tail = tail.to_display_point(&display_map); self.select_columns(tail, position, overshoot, &display_map, cx); - } else if let Some(mut pending) = self.pending_selection.clone() { + } else if let Some(mut pending) = self.selections.pending_anchor().clone() { let buffer = self.buffer.read(cx).snapshot(cx); let head; let tail; - match &pending.mode { + match &self.selections.pending_mode().unwrap() { SelectMode::Character => { head = position.to_point(&display_map); - tail = pending.selection.tail().to_point(&buffer); + tail = pending.tail().to_point(&buffer); } SelectMode::Word(original_range) => { let original_display_range = original_range.start.to_display_point(&display_map) @@ -1662,15 +1655,18 @@ impl Editor { }; if head < tail { - pending.selection.start = buffer.anchor_before(head); - pending.selection.end = buffer.anchor_before(tail); - pending.selection.reversed = true; + pending.start = buffer.anchor_before(head); + pending.end = buffer.anchor_before(tail); + pending.reversed = true; } else { - pending.selection.start = buffer.anchor_before(tail); - pending.selection.end = buffer.anchor_before(head); - pending.selection.reversed = false; + pending.start = buffer.anchor_before(tail); + pending.end = buffer.anchor_before(head); + pending.reversed = false; } - self.set_selections(self.selections.clone(), Some(pending), true, cx); + + self.change_selections(true, cx, |s| { + s.pending_mut().as_mut().unwrap().selection = pending; + }); } else { log::error!("update_selection dispatched with no pending selection"); return; @@ -1682,9 +1678,14 @@ impl Editor { fn end_selection(&mut self, cx: &mut ViewContext) { self.columnar_selection_tail.take(); - if self.pending_selection.is_some() { - let selections = self.local_selections::(cx); - self.update_selections(selections, None, cx); + if self.selections.pending_anchor().is_some() { + let selections = self + .selections + .interleaved::(&self.buffer.read(cx).snapshot(cx)); + self.change_selections(true, cx, |s| { + s.select(selections, None); + s.clear_pending(); + }); } } @@ -1702,7 +1703,7 @@ impl Editor { let end_column = cmp::max(tail.column(), head.column() + overshoot); let reversed = start_column < tail.column(); - let selections = (start_row..=end_row) + let selection_ranges = (start_row..=end_row) .filter_map(|row| { if start_column <= display_map.line_len(row) && !display_map.is_block_line(row) { let start = display_map @@ -1711,25 +1712,25 @@ impl Editor { let end = display_map .clip_point(DisplayPoint::new(row, end_column), Bias::Right) .to_point(&display_map); - Some(Selection { - id: post_inc(&mut self.next_selection_id), - start, - end, - reversed, - goal: SelectionGoal::None, - }) + if reversed { + Some(end..start) + } else { + Some(start..end) + } } else { None } }) .collect::>(); - self.update_selections(selections, None, cx); + self.change_selections(true, cx, |s| { + s.select_ranges(selection_ranges, None); + }); cx.notify(); } pub fn is_selecting(&self) -> bool { - self.pending_selection.is_some() || self.columnar_selection_tail.is_some() + self.selections.pending_anchor().is_some() || self.columnar_selection_tail.is_some() } pub fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext) { @@ -1751,28 +1752,10 @@ impl Editor { return; } - if let Some(pending) = self.pending_selection.clone() { - let mut selections = self.selections.clone(); - if selections.is_empty() { - selections = Arc::from([pending.selection]); - } - self.set_selections(selections, None, true, cx); + if self.change_selections(true, cx, |s| s.try_cancel()) { self.request_autoscroll(Autoscroll::Fit, cx); return; } - - let mut oldest_selection = self.oldest_selection::(&cx); - if self.selection_count() > 1 { - self.update_selections(vec![oldest_selection], Some(Autoscroll::Fit), cx); - return; - } - - if !oldest_selection.is_empty() { - oldest_selection.start = oldest_selection.head().clone(); - oldest_selection.end = oldest_selection.head().clone(); - self.update_selections(vec![oldest_selection], Some(Autoscroll::Fit), cx); - return; - } } cx.propagate_action(); @@ -1783,7 +1766,8 @@ impl Editor { &self, cx: &AppContext, ) -> Vec> { - self.local_selections::(cx) + self.selections + .interleaved::(&self.buffer.read(cx).read(cx)) .iter() .map(|s| { if s.reversed { @@ -1801,12 +1785,9 @@ impl Editor { .display_map .update(cx, |display_map, cx| display_map.snapshot(cx)); self.selections + .disjoint_anchors() .iter() - .chain( - self.pending_selection - .as_ref() - .map(|pending| &pending.selection), - ) + .chain(self.selections.pending_anchor().as_ref()) .map(|s| { if s.reversed { s.end.to_display_point(&display_map)..s.start.to_display_point(&display_map) @@ -1817,68 +1798,6 @@ impl Editor { .collect() } - pub fn select_ranges( - &mut self, - ranges: I, - autoscroll: Option, - cx: &mut ViewContext, - ) where - I: IntoIterator>, - T: ToOffset, - { - let buffer = self.buffer.read(cx).snapshot(cx); - let selections = ranges - .into_iter() - .map(|range| { - let mut start = range.start.to_offset(&buffer); - let mut end = range.end.to_offset(&buffer); - let reversed = if start > end { - mem::swap(&mut start, &mut end); - true - } else { - false - }; - Selection { - id: post_inc(&mut self.next_selection_id), - start, - end, - reversed, - goal: SelectionGoal::None, - } - }) - .collect::>(); - self.update_selections(selections, autoscroll, cx); - } - - #[cfg(any(test, feature = "test-support"))] - pub fn select_display_ranges<'a, T>(&mut self, ranges: T, cx: &mut ViewContext) - where - T: IntoIterator>, - { - let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = ranges - .into_iter() - .map(|range| { - let mut start = range.start; - let mut end = range.end; - let reversed = if start > end { - mem::swap(&mut start, &mut end); - true - } else { - false - }; - Selection { - id: post_inc(&mut self.next_selection_id), - start: start.to_point(&display_map), - end: end.to_point(&display_map), - reversed, - goal: SelectionGoal::None, - } - }) - .collect(); - self.update_selections(selections, None, cx); - } - pub fn handle_input(&mut self, action: &Input, cx: &mut ViewContext) { if !self.input_enabled { cx.propagate_action(); @@ -1900,8 +1819,8 @@ impl Editor { pub fn newline(&mut self, _: &Newline, cx: &mut ViewContext) { self.transact(cx, |this, cx| { let (edits, selection_fixup_info): (Vec<_>, Vec<_>) = { - let selections = this.local_selections::(cx); let buffer = this.buffer.read(cx).snapshot(cx); + let selections = this.selections.interleaved::(&buffer); selections .iter() .map(|selection| { @@ -1947,9 +1866,12 @@ impl Editor { if insert_extra_newline { new_text = new_text.repeat(2); } + + let anchor = buffer.anchor_after(end); + let new_selection = selection.map(|_| anchor.clone()); ( (start..end, new_text), - (insert_extra_newline, buffer.anchor_after(end)), + (insert_extra_newline, new_selection), ) }) .unzip() @@ -1957,25 +1879,22 @@ impl Editor { this.buffer.update(cx, |buffer, cx| { buffer.edit_with_autoindent(edits, cx); + }); + let buffer = this.buffer.read(cx).snapshot(cx); + let new_selections = selection_fixup_info + .into_iter() + .map(|(extra_newline_inserted, new_selection)| { + let mut cursor = new_selection.end.to_point(&buffer); + if extra_newline_inserted { + cursor.row -= 1; + cursor.column = buffer.line_len(cursor.row); + } + new_selection.map(|_| cursor.clone()) + }) + .collect(); - let buffer = buffer.read(cx); - this.selections = this - .selections - .iter() - .cloned() - .zip(selection_fixup_info) - .map(|(mut new_selection, (extra_newline_inserted, end))| { - let mut cursor = end.to_point(&buffer); - if extra_newline_inserted { - cursor.row -= 1; - cursor.column = buffer.line_len(cursor.row); - } - let anchor = buffer.anchor_after(cursor); - new_selection.start = anchor.clone(); - new_selection.end = anchor; - new_selection - }) - .collect(); + this.change_selections(true, cx, |s| { + s.select(new_selections, Some(Autoscroll::Fit)) }); this.request_autoscroll(Autoscroll::Fit, cx); @@ -1985,7 +1904,9 @@ impl Editor { pub fn insert(&mut self, text: &str, cx: &mut ViewContext) { let text: Arc = text.into(); self.transact(cx, |this, cx| { - let old_selections = this.local_selections::(cx); + let old_selections = this + .selections + .interleaved::(&this.buffer.read(cx).snapshot(cx)); let selection_anchors = this.buffer.update(cx, |buffer, cx| { let anchors = { let snapshot = buffer.read(cx); @@ -2019,12 +1940,15 @@ impl Editor { }) .collect() }; - this.update_selections(selections, Some(Autoscroll::Fit), cx); + + this.change_selections(true, cx, |s| { + s.select(selections, Some(Autoscroll::Fit)); + }) }); } fn trigger_completion_on_input(&mut self, text: &str, cx: &mut ViewContext) { - let selection = self.newest_anchor_selection(); + let selection = self.selections.newest_anchor(); if self .buffer .read(cx) @@ -2044,51 +1968,52 @@ impl Editor { .cloned() { if self - .local_selections::(cx) + .selections + .interleaved::(&snapshot) .iter() .any(|selection| selection.is_empty()) { - false - } else { - let mut selections = self.selections.to_vec(); - for selection in &mut selections { - selection.end = selection.end.bias_left(&snapshot); - } - drop(snapshot); - - self.buffer.update(cx, |buffer, cx| { - let pair_start: Arc = pair.start.clone().into(); - buffer.edit( - selections - .iter() - .map(|s| (s.start.clone()..s.start.clone(), pair_start.clone())), - cx, - ); - let pair_end: Arc = pair.end.clone().into(); - buffer.edit( - selections - .iter() - .map(|s| (s.end.clone()..s.end.clone(), pair_end.clone())), - cx, - ); - }); - - let snapshot = self.buffer.read(cx).read(cx); - for selection in &mut selections { - selection.end = selection.end.bias_right(&snapshot); - } - drop(snapshot); - - self.set_selections(selections.into(), None, true, cx); - true + return false; } + + let mut selections = self.selections.disjoint_anchors().to_vec(); + for selection in &mut selections { + selection.end = selection.end.bias_left(&snapshot); + } + drop(snapshot); + + self.buffer.update(cx, |buffer, cx| { + let pair_start: Arc = pair.start.clone().into(); + let pair_end: Arc = pair.end.clone().into(); + buffer.edit( + selections + .iter() + .map(|s| (s.start.clone()..s.start.clone(), pair_start.clone())) + .chain( + selections + .iter() + .map(|s| (s.end.clone()..s.end.clone(), pair_end.clone())), + ), + cx, + ); + }); + + let snapshot = self.buffer.read(cx).read(cx); + for selection in &mut selections { + selection.end = selection.end.bias_right(&snapshot); + } + drop(snapshot); + + self.change_selections(true, cx, |s| s.select_anchors(selections, None)); + true } else { false } } fn autoclose_bracket_pairs(&mut self, cx: &mut ViewContext) { - let selections = self.local_selections::(cx); + let snapshot = self.buffer.read(cx).snapshot(cx); + let selections = self.selections.interleaved::(&snapshot); let mut bracket_pair_state = None; let mut new_selections = None; self.buffer.update(cx, |buffer, cx| { @@ -2155,7 +2080,7 @@ impl Editor { snapshot = buffer.snapshot(cx); new_selections = Some( - self.resolve_selections::(left_biased_selections.iter(), &snapshot) + resolve_multiple::(left_biased_selections.iter(), &snapshot) .collect::>(), ); @@ -2177,7 +2102,9 @@ impl Editor { }); if let Some(new_selections) = new_selections { - self.update_selections(new_selections, None, cx); + self.change_selections(true, cx, |s| { + s.select(new_selections, None); + }); } if let Some(bracket_pair_state) = bracket_pair_state { self.autoclose_stack.push(bracket_pair_state); @@ -2185,7 +2112,8 @@ impl Editor { } fn skip_autoclose_end(&mut self, text: &str, cx: &mut ViewContext) -> bool { - let old_selections = self.local_selections::(cx); + let buffer = self.buffer.read(cx).snapshot(cx); + let old_selections = self.selections.interleaved::(&buffer); let autoclose_pair = if let Some(autoclose_pair) = self.autoclose_stack.last() { autoclose_pair } else { @@ -2197,7 +2125,6 @@ impl Editor { debug_assert_eq!(old_selections.len(), autoclose_pair.ranges.len()); - let buffer = self.buffer.read(cx).snapshot(cx); if old_selections .iter() .zip(autoclose_pair.ranges.iter().map(|r| r.to_offset(&buffer))) @@ -2220,7 +2147,9 @@ impl Editor { }) .collect(); self.autoclose_stack.pop(); - self.update_selections(new_selections, Some(Autoscroll::Fit), cx); + self.change_selections(true, cx, |s| { + s.select(new_selections, Some(Autoscroll::Fit)); + }); true } else { false @@ -2252,7 +2181,7 @@ impl Editor { return; }; - let position = self.newest_anchor_selection().head(); + let position = self.selections.newest_anchor().head(); let (buffer, buffer_position) = if let Some(output) = self .buffer .read(cx) @@ -2357,8 +2286,10 @@ impl Editor { let old_range = completion.old_range.to_offset(&buffer); let old_text = buffer.text_for_range(old_range.clone()).collect::(); - let selections = self.local_selections::(cx); - let newest_selection = self.newest_anchor_selection(); + let selections = self + .selections + .interleaved::(&self.buffer.read(cx).snapshot(cx)); + let newest_selection = self.selections.newest_anchor(); if newest_selection.start.buffer_id != Some(buffer_handle.id()) { return None; } @@ -2524,7 +2455,7 @@ impl Editor { editor .buffer() .read(cx) - .excerpt_containing(editor.newest_anchor_selection().head(), cx) + .excerpt_containing(editor.selections.newest_anchor().head(), cx) }); if let Some((excerpted_buffer, excerpt_range)) = excerpt { if excerpted_buffer == *buffer { @@ -2585,7 +2516,7 @@ impl Editor { fn refresh_code_actions(&mut self, cx: &mut ViewContext) -> Option<()> { let project = self.project.as_ref()?; let buffer = self.buffer.read(cx); - let newest_selection = self.newest_anchor_selection().clone(); + let newest_selection = self.selections.newest_anchor().clone(); let (start_buffer, start) = buffer.text_anchor_for_position(newest_selection.start, cx)?; let (end_buffer, end) = buffer.text_anchor_for_position(newest_selection.end, cx)?; if start_buffer != end_buffer { @@ -2620,7 +2551,7 @@ impl Editor { let project = self.project.as_ref()?; let buffer = self.buffer.read(cx); - let newest_selection = self.newest_anchor_selection().clone(); + let newest_selection = self.selections.newest_anchor().clone(); let cursor_position = newest_selection.head(); let (cursor_buffer, cursor_buffer_position) = buffer.text_anchor_for_position(cursor_position.clone(), cx)?; @@ -2808,7 +2739,9 @@ impl Editor { }); if let Some(tabstop) = tabstops.first() { - self.select_ranges(tabstop.iter().cloned(), Some(Autoscroll::Fit), cx); + self.change_selections(true, cx, |s| { + s.select_ranges(tabstop.iter().cloned(), Some(Autoscroll::Fit)); + }); self.snippet_stack.push(SnippetState { active_index: 0, ranges: tabstops, @@ -2827,14 +2760,13 @@ impl Editor { } pub fn move_to_snippet_tabstop(&mut self, bias: Bias, cx: &mut ViewContext) -> bool { - let buffer = self.buffer.read(cx).snapshot(cx); - - if let Some(snippet) = self.snippet_stack.last_mut() { + if let Some(mut snippet) = self.snippet_stack.pop() { match bias { Bias::Left => { if snippet.active_index > 0 { snippet.active_index -= 1; } else { + self.snippet_stack.push(snippet); return false; } } @@ -2842,34 +2774,25 @@ impl Editor { if snippet.active_index + 1 < snippet.ranges.len() { snippet.active_index += 1; } else { + self.snippet_stack.push(snippet); return false; } } } if let Some(current_ranges) = snippet.ranges.get(snippet.active_index) { - let new_selections = current_ranges - .iter() - .map(|new_range| { - let new_range = new_range.to_offset(&buffer); - Selection { - id: post_inc(&mut self.next_selection_id), - start: new_range.start, - end: new_range.end, - reversed: false, - goal: SelectionGoal::None, - } - }) - .collect(); + self.change_selections(true, cx, |s| { + s.select_anchor_ranges( + current_ranges.into_iter().cloned(), + Some(Autoscroll::Fit), + ) + }); - // Remove the snippet state when moving to the last tabstop. - if snippet.active_index + 1 == snippet.ranges.len() { - self.snippet_stack.pop(); + // If snippet state is not at the last tabstop, push it back on the stack + if snippet.active_index + 1 != snippet.ranges.len() { + self.snippet_stack.push(snippet); } - - self.update_selections(new_selections, Some(Autoscroll::Fit), cx); return true; } - self.snippet_stack.pop(); } false @@ -2883,8 +2806,10 @@ impl Editor { } pub fn backspace(&mut self, _: &Backspace, cx: &mut ViewContext) { - let mut selections = self.local_selections::(cx); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); + let mut selections = self + .selections + .interleaved::(&display_map.buffer_snapshot); for selection in &mut selections { if selection.is_empty() { let old_head = selection.head(); @@ -2911,18 +2836,20 @@ impl Editor { } self.transact(cx, |this, cx| { - this.update_selections(selections, Some(Autoscroll::Fit), cx); + this.change_selections(true, cx, |s| s.select(selections, Some(Autoscroll::Fit))); this.insert("", cx); }); } pub fn delete(&mut self, _: &Delete, cx: &mut ViewContext) { self.transact(cx, |this, cx| { - this.move_selections(cx, |map, selection| { - if selection.is_empty() { - let cursor = movement::right(map, selection.head()); - selection.set_head(cursor, SelectionGoal::None); - } + this.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + if selection.is_empty() { + let cursor = movement::right(map, selection.head()); + selection.set_head(cursor, SelectionGoal::None); + } + }) }); this.insert(&"", cx); }); @@ -2941,7 +2868,9 @@ impl Editor { return; } - let mut selections = self.local_selections::(cx); + let mut selections = self + .selections + .interleaved::(&self.buffer.read(cx).read(cx)); if selections.iter().all(|s| s.is_empty()) { self.transact(cx, |this, cx| { this.buffer.update(cx, |buffer, cx| { @@ -2966,7 +2895,9 @@ impl Editor { selection.end = selection.start; } }); - this.update_selections(selections, Some(Autoscroll::Fit), cx); + this.change_selections(true, cx, |s| { + s.select(selections, Some(Autoscroll::Fit)); + }); }); } else { self.indent(&Indent, cx); @@ -2974,7 +2905,9 @@ impl Editor { } pub fn indent(&mut self, _: &Indent, cx: &mut ViewContext) { - let mut selections = self.local_selections::(cx); + let mut selections = self + .selections + .interleaved::(&self.buffer.read(cx).read(cx)); self.transact(cx, |this, cx| { let mut last_indent = None; this.buffer.update(cx, |buffer, cx| { @@ -3029,13 +2962,17 @@ impl Editor { } }); - this.update_selections(selections, Some(Autoscroll::Fit), cx); + this.change_selections(true, cx, |s| { + s.select(selections, Some(Autoscroll::Fit)); + }); }); } pub fn outdent(&mut self, _: &Outdent, cx: &mut ViewContext) { - let selections = self.local_selections::(cx); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); + let selections = self + .selections + .interleaved::(&display_map.buffer_snapshot); let mut deletion_ranges = Vec::new(); let mut last_outdent = None; { @@ -3078,18 +3015,18 @@ impl Editor { cx, ); }); - this.update_selections( - this.local_selections::(cx), - Some(Autoscroll::Fit), - cx, - ); + let snapshot = this.buffer.read(cx).snapshot(cx); + this.change_selections(true, cx, |s| { + s.select(s.interleaved::(&snapshot), Some(Autoscroll::Fit)) + }); }); } pub fn delete_line(&mut self, _: &DeleteLine, cx: &mut ViewContext) { - let selections = self.local_selections::(cx); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let buffer = self.buffer.read(cx).snapshot(cx); + let selections = self + .selections + .interleaved::(&display_map.buffer_snapshot); let mut new_cursors = Vec::new(); let mut edit_ranges = Vec::new(); @@ -3109,6 +3046,7 @@ impl Editor { } } + let buffer = &display_map.buffer_snapshot; let mut edit_start = Point::new(rows.start, 0).to_offset(&buffer); let edit_end; let cursor_buffer_row; @@ -3160,14 +3098,17 @@ impl Editor { } }) .collect(); - this.update_selections(new_selections, Some(Autoscroll::Fit), cx); + + this.change_selections(true, cx, |s| { + s.select(new_selections, Some(Autoscroll::Fit)); + }); }); } pub fn duplicate_line(&mut self, _: &DuplicateLine, cx: &mut ViewContext) { - let selections = self.local_selections::(cx); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = &display_map.buffer_snapshot; + let selections = self.selections.interleaved::(buffer); let mut edits = Vec::new(); let mut selections_iter = selections.iter().peekable(); @@ -3212,7 +3153,7 @@ impl Editor { let mut unfold_ranges = Vec::new(); let mut refold_ranges = Vec::new(); - let selections = self.local_selections::(cx); + let selections = self.selections.interleaved::(&buffer); let mut selections = selections.iter().peekable(); let mut contiguous_row_selections = Vec::new(); let mut new_selections = Vec::new(); @@ -3310,7 +3251,9 @@ impl Editor { } }); this.fold_ranges(refold_ranges, cx); - this.update_selections(new_selections, Some(Autoscroll::Fit), cx); + this.change_selections(true, cx, |s| { + s.select(new_selections, Some(Autoscroll::Fit)); + }) }); } @@ -3322,7 +3265,7 @@ impl Editor { let mut unfold_ranges = Vec::new(); let mut refold_ranges = Vec::new(); - let selections = self.local_selections::(cx); + let selections = self.selections.interleaved::(&buffer); let mut selections = selections.iter().peekable(); let mut contiguous_row_selections = Vec::new(); let mut new_selections = Vec::new(); @@ -3413,62 +3356,68 @@ impl Editor { } }); this.fold_ranges(refold_ranges, cx); - this.update_selections(new_selections, Some(Autoscroll::Fit), cx); + this.change_selections(true, cx, |s| { + s.select(new_selections, Some(Autoscroll::Fit)) + }); }); } pub fn transpose(&mut self, _: &Transpose, cx: &mut ViewContext) { self.transact(cx, |this, cx| { - let mut edits: Vec<(Range, String)> = Default::default(); - this.move_selections(cx, |display_map, selection| { - if !selection.is_empty() { - return; - } + let edits = this.change_selections(true, cx, |s| { + let mut edits: Vec<(Range, String)> = Default::default(); + s.move_with(|display_map, selection| { + if !selection.is_empty() { + return; + } - let mut head = selection.head(); - let mut transpose_offset = head.to_offset(display_map, Bias::Right); - if head.column() == display_map.line_len(head.row()) { - transpose_offset = display_map + let mut head = selection.head(); + let mut transpose_offset = head.to_offset(display_map, Bias::Right); + if head.column() == display_map.line_len(head.row()) { + transpose_offset = display_map + .buffer_snapshot + .clip_offset(transpose_offset.saturating_sub(1), Bias::Left); + } + + if transpose_offset == 0 { + return; + } + + *head.column_mut() += 1; + head = display_map.clip_point(head, Bias::Right); + selection.collapse_to(head, SelectionGoal::Column(head.column())); + + let transpose_start = display_map .buffer_snapshot .clip_offset(transpose_offset.saturating_sub(1), Bias::Left); - } - - if transpose_offset == 0 { - return; - } - - *head.column_mut() += 1; - head = display_map.clip_point(head, Bias::Right); - selection.collapse_to(head, SelectionGoal::Column(head.column())); - - let transpose_start = display_map - .buffer_snapshot - .clip_offset(transpose_offset.saturating_sub(1), Bias::Left); - if edits.last().map_or(true, |e| e.0.end <= transpose_start) { - let transpose_end = display_map - .buffer_snapshot - .clip_offset(transpose_offset + 1, Bias::Right); - if let Some(ch) = display_map.buffer_snapshot.chars_at(transpose_start).next() { - edits.push((transpose_start..transpose_offset, String::new())); - edits.push((transpose_end..transpose_end, ch.to_string())); + if edits.last().map_or(true, |e| e.0.end <= transpose_start) { + let transpose_end = display_map + .buffer_snapshot + .clip_offset(transpose_offset + 1, Bias::Right); + if let Some(ch) = + display_map.buffer_snapshot.chars_at(transpose_start).next() + { + edits.push((transpose_start..transpose_offset, String::new())); + edits.push((transpose_end..transpose_end, ch.to_string())); + } } - } + }); + edits }); this.buffer.update(cx, |buffer, cx| buffer.edit(edits, cx)); - this.update_selections( - this.local_selections::(cx), - Some(Autoscroll::Fit), - cx, - ); + let buffer = this.buffer.read(cx).snapshot(cx); + this.change_selections(true, cx, |s| { + s.select(s.interleaved::(&buffer), Some(Autoscroll::Fit)); + }); }); } pub fn cut(&mut self, _: &Cut, cx: &mut ViewContext) { let mut text = String::new(); - let mut selections = self.local_selections::(cx); + let buffer = self.buffer.read(cx).snapshot(cx); + let mut selections = self.selections.interleaved::(&buffer); let mut clipboard_selections = Vec::with_capacity(selections.len()); { - let buffer = self.buffer.read(cx).read(cx); let max_point = buffer.max_point(); for selection in &mut selections { let is_entire_line = selection.is_empty(); @@ -3490,18 +3439,20 @@ impl Editor { } self.transact(cx, |this, cx| { - this.update_selections(selections, Some(Autoscroll::Fit), cx); + this.change_selections(true, cx, |s| { + s.select(selections, Some(Autoscroll::Fit)); + }); this.insert("", cx); cx.write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections)); }); } pub fn copy(&mut self, _: &Copy, cx: &mut ViewContext) { - let selections = self.local_selections::(cx); + let buffer = self.buffer.read(cx).read(cx); + let selections = self.selections.interleaved::(&buffer); let mut text = String::new(); let mut clipboard_selections = Vec::with_capacity(selections.len()); { - let buffer = self.buffer.read(cx).read(cx); let max_point = buffer.max_point(); for selection in selections.iter() { let mut start = selection.start; @@ -3531,7 +3482,9 @@ impl Editor { if let Some(item) = cx.as_mut().read_from_clipboard() { let mut clipboard_text = Cow::Borrowed(item.text()); if let Some(mut clipboard_selections) = item.metadata::>() { - let old_selections = this.local_selections::(cx); + let old_selections = this + .selections + .interleaved::(&this.buffer.read(cx).read(cx)); let all_selections_were_entire_line = clipboard_selections.iter().all(|s| s.is_entire_line); if clipboard_selections.len() != old_selections.len() { @@ -3584,8 +3537,12 @@ impl Editor { buffer.edit_with_autoindent(edits, cx); }); - let selections = this.local_selections::(cx); - this.update_selections(selections, Some(Autoscroll::Fit), cx); + let selections = this + .selections + .interleaved::(&this.buffer.read(cx).read(cx)); + this.change_selections(true, cx, |s| { + s.select(selections, Some(Autoscroll::Fit)) + }); } else { this.insert(&clipboard_text, cx); } @@ -3596,7 +3553,11 @@ impl Editor { pub fn undo(&mut self, _: &Undo, cx: &mut ViewContext) { if let Some(tx_id) = self.buffer.update(cx, |buffer, cx| buffer.undo(cx)) { if let Some((selections, _)) = self.selection_history.transaction(tx_id).cloned() { - self.set_selections(selections, None, true, cx); + self.change_selections(true, cx, |s| { + // TODO: move to SelectionsCollection to preserve selection + // invariants without rechecking + s.select_anchors(selections.to_vec(), None); + }); } self.request_autoscroll(Autoscroll::Fit, cx); cx.emit(Event::Edited); @@ -3607,7 +3568,11 @@ impl Editor { if let Some(tx_id) = self.buffer.update(cx, |buffer, cx| buffer.redo(cx)) { if let Some((_, Some(selections))) = self.selection_history.transaction(tx_id).cloned() { - self.set_selections(selections, None, true, cx); + self.change_selections(true, cx, |s| { + // TODO: move to SelectionsCollection to preserve selection + // invariants without rechecking + s.select_anchors(selections.to_vec(), None); + }); } self.request_autoscroll(Autoscroll::Fit, cx); cx.emit(Event::Edited); @@ -3620,37 +3585,41 @@ impl Editor { } pub fn move_left(&mut self, _: &MoveLeft, cx: &mut ViewContext) { - self.move_selections(cx, |map, selection| { - let cursor = if selection.is_empty() { - movement::left(map, selection.start) - } else { - selection.start - }; - selection.collapse_to(cursor, SelectionGoal::None); - }); + self.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + let cursor = if selection.is_empty() { + movement::left(map, selection.start) + } else { + selection.start + }; + selection.collapse_to(cursor, SelectionGoal::None); + }); + }) } pub fn select_left(&mut self, _: &SelectLeft, cx: &mut ViewContext) { - self.move_selection_heads(cx, |map, head, _| { - (movement::left(map, head), SelectionGoal::None) - }); + self.change_selections(true, cx, |s| { + s.move_heads_with(|map, head, _| (movement::left(map, head), SelectionGoal::None)); + }) } pub fn move_right(&mut self, _: &MoveRight, cx: &mut ViewContext) { - self.move_selections(cx, |map, selection| { - let cursor = if selection.is_empty() { - movement::right(map, selection.end) - } else { - selection.end - }; - selection.collapse_to(cursor, SelectionGoal::None) - }); + self.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + let cursor = if selection.is_empty() { + movement::right(map, selection.end) + } else { + selection.end + }; + selection.collapse_to(cursor, SelectionGoal::None) + }); + }) } pub fn select_right(&mut self, _: &SelectRight, cx: &mut ViewContext) { - self.move_selection_heads(cx, |map, head, _| { - (movement::right(map, head), SelectionGoal::None) - }); + self.change_selections(true, cx, |s| { + s.move_heads_with(|map, head, _| (movement::right(map, head), SelectionGoal::None)); + }) } pub fn move_up(&mut self, _: &MoveUp, cx: &mut ViewContext) { @@ -3669,17 +3638,21 @@ impl Editor { return; } - self.move_selections(cx, |map, selection| { - if !selection.is_empty() { - selection.goal = SelectionGoal::None; - } - let (cursor, goal) = movement::up(&map, selection.start, selection.goal, false); - selection.collapse_to(cursor, goal); - }); + self.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + if !selection.is_empty() { + selection.goal = SelectionGoal::None; + } + let (cursor, goal) = movement::up(&map, selection.start, selection.goal, false); + selection.collapse_to(cursor, goal); + }); + }) } pub fn select_up(&mut self, _: &SelectUp, cx: &mut ViewContext) { - self.move_selection_heads(cx, |map, head, goal| movement::up(map, head, goal, false)) + self.change_selections(true, cx, |s| { + s.move_heads_with(|map, head, goal| movement::up(map, head, goal, false)) + }) } pub fn move_down(&mut self, _: &MoveDown, cx: &mut ViewContext) { @@ -3696,17 +3669,21 @@ impl Editor { return; } - self.move_selections(cx, |map, selection| { - if !selection.is_empty() { - selection.goal = SelectionGoal::None; - } - let (cursor, goal) = movement::down(&map, selection.end, selection.goal, false); - selection.collapse_to(cursor, goal); + self.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + if !selection.is_empty() { + selection.goal = SelectionGoal::None; + } + let (cursor, goal) = movement::down(&map, selection.end, selection.goal, false); + selection.collapse_to(cursor, goal); + }); }); } pub fn select_down(&mut self, _: &SelectDown, cx: &mut ViewContext) { - self.move_selection_heads(cx, |map, head, goal| movement::down(map, head, goal, false)) + self.change_selections(true, cx, |s| { + s.move_heads_with(|map, head, goal| movement::down(map, head, goal, false)) + }); } pub fn move_to_previous_word_start( @@ -3714,12 +3691,14 @@ impl Editor { _: &MoveToPreviousWordStart, cx: &mut ViewContext, ) { - self.move_cursors(cx, |map, head, _| { - ( - movement::previous_word_start(map, head), - SelectionGoal::None, - ) - }); + self.change_selections(true, cx, |s| { + s.move_cursors_with(|map, head, _| { + ( + movement::previous_word_start(map, head), + SelectionGoal::None, + ) + }); + }) } pub fn move_to_previous_subword_start( @@ -3727,12 +3706,14 @@ impl Editor { _: &MoveToPreviousSubwordStart, cx: &mut ViewContext, ) { - self.move_cursors(cx, |map, head, _| { - ( - movement::previous_subword_start(map, head), - SelectionGoal::None, - ) - }); + self.change_selections(true, cx, |s| { + s.move_cursors_with(|map, head, _| { + ( + movement::previous_subword_start(map, head), + SelectionGoal::None, + ) + }); + }) } pub fn select_to_previous_word_start( @@ -3740,12 +3721,14 @@ impl Editor { _: &SelectToPreviousWordStart, cx: &mut ViewContext, ) { - self.move_selection_heads(cx, |map, head, _| { - ( - movement::previous_word_start(map, head), - SelectionGoal::None, - ) - }); + self.change_selections(true, cx, |s| { + s.move_heads_with(|map, head, _| { + ( + movement::previous_word_start(map, head), + SelectionGoal::None, + ) + }); + }) } pub fn select_to_previous_subword_start( @@ -3753,12 +3736,14 @@ impl Editor { _: &SelectToPreviousSubwordStart, cx: &mut ViewContext, ) { - self.move_selection_heads(cx, |map, head, _| { - ( - movement::previous_subword_start(map, head), - SelectionGoal::None, - ) - }); + self.change_selections(true, cx, |s| { + s.move_heads_with(|map, head, _| { + ( + movement::previous_subword_start(map, head), + SelectionGoal::None, + ) + }); + }) } pub fn delete_to_previous_word_start( @@ -3767,11 +3752,13 @@ impl Editor { cx: &mut ViewContext, ) { self.transact(cx, |this, cx| { - this.move_selections(cx, |map, selection| { - if selection.is_empty() { - let cursor = movement::previous_word_start(map, selection.head()); - selection.set_head(cursor, SelectionGoal::None); - } + this.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + if selection.is_empty() { + let cursor = movement::previous_word_start(map, selection.head()); + selection.set_head(cursor, SelectionGoal::None); + } + }); }); this.insert("", cx); }); @@ -3783,20 +3770,24 @@ impl Editor { cx: &mut ViewContext, ) { self.transact(cx, |this, cx| { - this.move_selections(cx, |map, selection| { - if selection.is_empty() { - let cursor = movement::previous_subword_start(map, selection.head()); - selection.set_head(cursor, SelectionGoal::None); - } + this.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + if selection.is_empty() { + let cursor = movement::previous_subword_start(map, selection.head()); + selection.set_head(cursor, SelectionGoal::None); + } + }); }); this.insert("", cx); }); } pub fn move_to_next_word_end(&mut self, _: &MoveToNextWordEnd, cx: &mut ViewContext) { - self.move_cursors(cx, |map, head, _| { - (movement::next_word_end(map, head), SelectionGoal::None) - }); + self.change_selections(true, cx, |s| { + s.move_cursors_with(|map, head, _| { + (movement::next_word_end(map, head), SelectionGoal::None) + }); + }) } pub fn move_to_next_subword_end( @@ -3804,15 +3795,19 @@ impl Editor { _: &MoveToNextSubwordEnd, cx: &mut ViewContext, ) { - self.move_cursors(cx, |map, head, _| { - (movement::next_subword_end(map, head), SelectionGoal::None) - }); + self.change_selections(true, cx, |s| { + s.move_cursors_with(|map, head, _| { + (movement::next_subword_end(map, head), SelectionGoal::None) + }); + }) } pub fn select_to_next_word_end(&mut self, _: &SelectToNextWordEnd, cx: &mut ViewContext) { - self.move_selection_heads(cx, |map, head, _| { - (movement::next_word_end(map, head), SelectionGoal::None) - }); + self.change_selections(true, cx, |s| { + s.move_heads_with(|map, head, _| { + (movement::next_word_end(map, head), SelectionGoal::None) + }); + }) } pub fn select_to_next_subword_end( @@ -3820,18 +3815,22 @@ impl Editor { _: &SelectToNextSubwordEnd, cx: &mut ViewContext, ) { - self.move_selection_heads(cx, |map, head, _| { - (movement::next_subword_end(map, head), SelectionGoal::None) - }); + self.change_selections(true, cx, |s| { + s.move_heads_with(|map, head, _| { + (movement::next_subword_end(map, head), SelectionGoal::None) + }); + }) } pub fn delete_to_next_word_end(&mut self, _: &DeleteToNextWordEnd, cx: &mut ViewContext) { self.transact(cx, |this, cx| { - this.move_selections(cx, |map, selection| { - if selection.is_empty() { - let cursor = movement::next_word_end(map, selection.head()); - selection.set_head(cursor, SelectionGoal::None); - } + this.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + if selection.is_empty() { + let cursor = movement::next_word_end(map, selection.head()); + selection.set_head(cursor, SelectionGoal::None); + } + }); }); this.insert("", cx); }); @@ -3843,11 +3842,13 @@ impl Editor { cx: &mut ViewContext, ) { self.transact(cx, |this, cx| { - this.move_selections(cx, |map, selection| { - if selection.is_empty() { - let cursor = movement::next_subword_end(map, selection.head()); - selection.set_head(cursor, SelectionGoal::None); - } + this.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + if selection.is_empty() { + let cursor = movement::next_subword_end(map, selection.head()); + selection.set_head(cursor, SelectionGoal::None); + } + }); }); this.insert("", cx); }); @@ -3858,12 +3859,14 @@ impl Editor { _: &MoveToBeginningOfLine, cx: &mut ViewContext, ) { - self.move_cursors(cx, |map, head, _| { - ( - movement::line_beginning(map, head, true), - SelectionGoal::None, - ) - }); + self.change_selections(true, cx, |s| { + s.move_cursors_with(|map, head, _| { + ( + movement::line_beginning(map, head, true), + SelectionGoal::None, + ) + }); + }) } pub fn select_to_beginning_of_line( @@ -3871,11 +3874,13 @@ impl Editor { action: &SelectToBeginningOfLine, cx: &mut ViewContext, ) { - self.move_selection_heads(cx, |map, head, _| { - ( - movement::line_beginning(map, head, action.stop_at_soft_wraps), - SelectionGoal::None, - ) + self.change_selections(true, cx, |s| { + s.move_heads_with(|map, head, _| { + ( + movement::line_beginning(map, head, action.stop_at_soft_wraps), + SelectionGoal::None, + ) + }); }); } @@ -3885,8 +3890,10 @@ impl Editor { cx: &mut ViewContext, ) { self.transact(cx, |this, cx| { - this.move_selections(cx, |_, selection| { - selection.reversed = true; + this.change_selections(true, cx, |s| { + s.move_with(|_, selection| { + selection.reversed = true; + }); }); this.select_to_beginning_of_line( @@ -3900,9 +3907,11 @@ impl Editor { } pub fn move_to_end_of_line(&mut self, _: &MoveToEndOfLine, cx: &mut ViewContext) { - self.move_cursors(cx, |map, head, _| { - (movement::line_end(map, head, true), SelectionGoal::None) - }); + self.change_selections(true, cx, |s| { + s.move_cursors_with(|map, head, _| { + (movement::line_end(map, head, true), SelectionGoal::None) + }); + }) } pub fn select_to_end_of_line( @@ -3910,12 +3919,14 @@ impl Editor { action: &SelectToEndOfLine, cx: &mut ViewContext, ) { - self.move_selection_heads(cx, |map, head, _| { - ( - movement::line_end(map, head, action.stop_at_soft_wraps), - SelectionGoal::None, - ) - }); + self.change_selections(true, cx, |s| { + s.move_heads_with(|map, head, _| { + ( + movement::line_end(map, head, action.stop_at_soft_wraps), + SelectionGoal::None, + ) + }); + }) } pub fn delete_to_end_of_line(&mut self, _: &DeleteToEndOfLine, cx: &mut ViewContext) { @@ -3948,20 +3959,20 @@ impl Editor { return; } - let selection = Selection { - id: post_inc(&mut self.next_selection_id), - start: 0, - end: 0, - reversed: false, - goal: SelectionGoal::None, - }; - self.update_selections(vec![selection], Some(Autoscroll::Fit), cx); + self.change_selections(true, cx, |s| { + s.select_ranges(vec![0..0], Some(Autoscroll::Fit)); + }); } pub fn select_to_beginning(&mut self, _: &SelectToBeginning, cx: &mut ViewContext) { - let mut selection = self.local_selections::(cx).last().unwrap().clone(); + let mut selection = self + .selections + .last::(&self.buffer.read(cx).read(cx)); selection.set_head(Point::zero(), SelectionGoal::None); - self.update_selections(vec![selection], Some(Autoscroll::Fit), cx); + + self.change_selections(true, cx, |s| { + s.select(vec![selection], Some(Autoscroll::Fit)); + }); } pub fn move_to_end(&mut self, _: &MoveToEnd, cx: &mut ViewContext) { @@ -3971,14 +3982,9 @@ impl Editor { } let cursor = self.buffer.read(cx).read(cx).len(); - let selection = Selection { - id: post_inc(&mut self.next_selection_id), - start: cursor, - end: cursor, - reversed: false, - goal: SelectionGoal::None, - }; - self.update_selections(vec![selection], Some(Autoscroll::Fit), cx); + self.change_selections(true, cx, |s| { + s.select_ranges(vec![cursor..cursor], Some(Autoscroll::Fit)) + }); } pub fn set_nav_history(&mut self, nav_history: Option) { @@ -4019,25 +4025,26 @@ impl Editor { } pub fn select_to_end(&mut self, _: &SelectToEnd, cx: &mut ViewContext) { - let mut selection = self.local_selections::(cx).first().unwrap().clone(); - selection.set_head(self.buffer.read(cx).read(cx).len(), SelectionGoal::None); - self.update_selections(vec![selection], Some(Autoscroll::Fit), cx); + let buffer = self.buffer.read(cx).snapshot(cx); + let mut selection = self.selections.first::(&buffer); + selection.set_head(buffer.len(), SelectionGoal::None); + self.change_selections(true, cx, |s| { + s.select(vec![selection], Some(Autoscroll::Fit)); + }); } pub fn select_all(&mut self, _: &SelectAll, cx: &mut ViewContext) { - let selection = Selection { - id: post_inc(&mut self.next_selection_id), - start: 0, - end: self.buffer.read(cx).read(cx).len(), - reversed: false, - goal: SelectionGoal::None, - }; - self.update_selections(vec![selection], None, cx); + let end = self.buffer.read(cx).read(cx).len(); + self.change_selections(true, cx, |s| { + s.select_ranges(vec![0..end], Some(Autoscroll::Fit)); + }); } pub fn select_line(&mut self, _: &SelectLine, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let mut selections = self.local_selections::(cx); + let mut selections = self + .selections + .interleaved::(&display_map.buffer_snapshot); let max_point = display_map.buffer_snapshot.max_point(); for selection in &mut selections { let rows = selection.spanned_rows(true, &display_map); @@ -4045,7 +4052,9 @@ impl Editor { selection.end = cmp::min(max_point, Point::new(rows.end, 0)); selection.reversed = false; } - self.update_selections(selections, Some(Autoscroll::Fit), cx); + self.change_selections(true, cx, |s| { + s.select(selections, Some(Autoscroll::Fit)); + }); } pub fn split_selection_into_lines( @@ -4054,33 +4063,23 @@ impl Editor { cx: &mut ViewContext, ) { let mut to_unfold = Vec::new(); - let mut new_selections = Vec::new(); + let mut new_selection_ranges = Vec::new(); { - let selections = self.local_selections::(cx); let buffer = self.buffer.read(cx).read(cx); + let selections = self.selections.interleaved::(&buffer); for selection in selections { for row in selection.start.row..selection.end.row { let cursor = Point::new(row, buffer.line_len(row)); - new_selections.push(Selection { - id: post_inc(&mut self.next_selection_id), - start: cursor, - end: cursor, - reversed: false, - goal: SelectionGoal::None, - }); + new_selection_ranges.push(cursor..cursor); } - new_selections.push(Selection { - id: selection.id, - start: selection.end, - end: selection.end, - reversed: false, - goal: SelectionGoal::None, - }); + new_selection_ranges.push(selection.end..selection.end); to_unfold.push(selection.start..selection.end); } } self.unfold_ranges(to_unfold, true, cx); - self.update_selections(new_selections, Some(Autoscroll::Fit), cx); + self.change_selections(true, cx, |s| { + s.select_ranges(new_selection_ranges, Some(Autoscroll::Fit)); + }); } pub fn add_selection_above(&mut self, _: &AddSelectionAbove, cx: &mut ViewContext) { @@ -4094,7 +4093,9 @@ impl Editor { fn add_selection(&mut self, above: bool, cx: &mut ViewContext) { self.push_to_selection_history(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let mut selections = self.local_selections::(cx); + let mut selections = self + .selections + .interleaved::(&display_map.buffer_snapshot); let mut state = self.add_selections_state.take().unwrap_or_else(|| { let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone(); let range = oldest_selection.display_range(&display_map).sorted(); @@ -4179,7 +4180,9 @@ impl Editor { state.stack.pop(); } - self.update_selections(new_selections, Some(Autoscroll::Newest), cx); + self.change_selections(true, cx, |s| { + s.select(new_selections, Some(Autoscroll::Fit)); + }); if state.stack.len() > 1 { self.add_selections_state = Some(state); } @@ -4189,7 +4192,7 @@ impl Editor { self.push_to_selection_history(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = &display_map.buffer_snapshot; - let mut selections = self.local_selections::(cx); + let mut selections = self.selections.interleaved::(&buffer); if let Some(mut select_next_state) = self.select_next_state.take() { let query = &select_next_state.query; if !select_next_state.done { @@ -4225,22 +4228,13 @@ impl Editor { } if let Some(next_selected_range) = next_selected_range { - if action.replace_newest { - if let Some(newest_id) = - selections.iter().max_by_key(|s| s.id).map(|s| s.id) - { - selections.retain(|s| s.id != newest_id); + self.unfold_ranges([next_selected_range.clone()], false, cx); + self.change_selections(true, cx, |s| { + if action.replace_newest { + s.delete(s.newest_anchor().id); } - } - selections.push(Selection { - id: post_inc(&mut self.next_selection_id), - start: next_selected_range.start, - end: next_selected_range.end, - reversed: false, - goal: SelectionGoal::None, + s.insert_range(next_selected_range, Some(Autoscroll::Newest)); }); - self.unfold_ranges([next_selected_range], false, cx); - self.update_selections(selections, Some(Autoscroll::Newest), cx); } else { select_next_state.done = true; } @@ -4268,7 +4262,9 @@ impl Editor { done: false, }; self.unfold_ranges([selection.start..selection.end], false, cx); - self.update_selections(selections, Some(Autoscroll::Newest), cx); + self.change_selections(true, cx, |s| { + s.select(selections, Some(Autoscroll::Newest)); + }); self.select_next_state = Some(select_state); } else { let query = buffer @@ -4286,7 +4282,9 @@ impl Editor { pub fn toggle_comments(&mut self, _: &ToggleComments, cx: &mut ViewContext) { self.transact(cx, |this, cx| { - let mut selections = this.local_selections::(cx); + let mut selections = this + .selections + .interleaved::(&this.buffer.read(cx).snapshot(cx)); let mut all_selection_lines_are_comments = true; let mut edit_ranges = Vec::new(); let mut last_toggled_row = None; @@ -4387,11 +4385,12 @@ impl Editor { } }); - this.update_selections( - this.local_selections::(cx), - Some(Autoscroll::Fit), - cx, - ); + let selections = this + .selections + .interleaved::(&this.buffer.read(cx).read(cx)); + this.change_selections(true, cx, |s| { + s.select(selections, Some(Autoscroll::Fit)); + }); }); } @@ -4400,9 +4399,12 @@ impl Editor { _: &SelectLargerSyntaxNode, cx: &mut ViewContext, ) { - let old_selections = self.local_selections::(cx).into_boxed_slice(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = self.buffer.read(cx).snapshot(cx); + let old_selections = self + .selections + .interleaved::(&buffer) + .into_boxed_slice(); let mut stack = mem::take(&mut self.select_larger_syntax_node_stack); let mut selected_larger_node = false; @@ -4435,7 +4437,9 @@ impl Editor { if selected_larger_node { stack.push(old_selections); - self.update_selections(new_selections, Some(Autoscroll::Fit), cx); + self.change_selections(true, cx, |s| { + s.select(new_selections, Some(Autoscroll::Fit)); + }); } self.select_larger_syntax_node_stack = stack; } @@ -4447,7 +4451,9 @@ impl Editor { ) { let mut stack = mem::take(&mut self.select_larger_syntax_node_stack); if let Some(selections) = stack.pop() { - self.update_selections(selections.to_vec(), Some(Autoscroll::Fit), cx); + self.change_selections(true, cx, |s| { + s.select(selections.to_vec(), Some(Autoscroll::Fit)); + }); } self.select_larger_syntax_node_stack = stack; } @@ -4457,8 +4463,8 @@ impl Editor { _: &MoveToEnclosingBracket, cx: &mut ViewContext, ) { - let mut selections = self.local_selections::(cx); let buffer = self.buffer.read(cx).snapshot(cx); + let mut selections = self.selections.interleaved::(&buffer); for selection in &mut selections { if let Some((open_range, close_range)) = buffer.enclosing_bracket_ranges(selection.start..selection.end) @@ -4476,14 +4482,20 @@ impl Editor { } } - self.update_selections(selections, Some(Autoscroll::Fit), cx); + self.change_selections(true, cx, |s| { + s.select(selections, Some(Autoscroll::Fit)); + }); } pub fn undo_selection(&mut self, _: &UndoSelection, cx: &mut ViewContext) { self.end_selection(cx); self.selection_history.mode = SelectionHistoryMode::Undoing; if let Some(entry) = self.selection_history.undo_stack.pop_back() { - self.set_selections(entry.selections, None, true, cx); + self.change_selections(true, cx, |s| { + // TODO: Move to selections so selections invariants can be preserved rather than + // rechecking them. + s.select_anchors(entry.selections.to_vec(), None) + }); self.select_next_state = entry.select_next_state; self.add_selections_state = entry.add_selections_state; self.request_autoscroll(Autoscroll::Newest, cx); @@ -4495,7 +4507,11 @@ impl Editor { self.end_selection(cx); self.selection_history.mode = SelectionHistoryMode::Redoing; if let Some(entry) = self.selection_history.redo_stack.pop_back() { - self.set_selections(entry.selections, None, true, cx); + self.change_selections(true, cx, |s| { + // TODO: Move to selections so selections invariants can be preserved rather than + // rechecking them. + s.select_anchors(entry.selections.to_vec(), None) + }); self.select_next_state = entry.select_next_state; self.add_selections_state = entry.add_selections_state; self.request_autoscroll(Autoscroll::Newest, cx); @@ -4513,7 +4529,7 @@ impl Editor { pub fn go_to_diagnostic(&mut self, direction: Direction, cx: &mut ViewContext) { let buffer = self.buffer.read(cx).snapshot(cx); - let selection = self.newest_selection_with_snapshot::(&buffer); + let selection = self.selections.newest::(&buffer); let mut active_primary_range = self.active_diagnostics.as_ref().map(|active_diagnostics| { active_diagnostics .primary_range @@ -4550,17 +4566,18 @@ impl Editor { if let Some((primary_range, group_id)) = group { self.activate_diagnostics(group_id, cx); - self.update_selections( - vec![Selection { - id: selection.id, - start: primary_range.start, - end: primary_range.start, - reversed: false, - goal: SelectionGoal::None, - }], - Some(Autoscroll::Center), - cx, - ); + self.change_selections(true, cx, |s| { + s.select( + vec![Selection { + id: selection.id, + start: primary_range.start, + end: primary_range.start, + reversed: false, + goal: SelectionGoal::None, + }], + Some(Autoscroll::Center), + ); + }); break; } else { // Cycle around to the start of the buffer, potentially moving back to the start of @@ -4599,13 +4616,13 @@ impl Editor { }; let editor = editor_handle.read(cx); - let head = editor.newest_selection::(cx).head(); - let (buffer, head) = - if let Some(text_anchor) = editor.buffer.read(cx).text_anchor_for_position(head, cx) { - text_anchor - } else { - return; - }; + let buffer = editor.buffer.read(cx); + let head = editor.selections.newest::(&buffer.read(cx)).head(); + let (buffer, head) = if let Some(text_anchor) = buffer.text_anchor_for_position(head, cx) { + text_anchor + } else { + return; + }; let project = workspace.project().clone(); let definitions = project.update(cx, |project, cx| project.definition(&buffer, head, cx)); @@ -4623,7 +4640,10 @@ impl Editor { if editor_handle != target_editor_handle { nav_history.borrow_mut().disable(); } - target_editor.select_ranges([range], Some(Autoscroll::Center), cx); + target_editor.change_selections(true, cx, |s| { + s.select_ranges([range], Some(Autoscroll::Center)); + }); + nav_history.borrow_mut().enable(); }); } @@ -4643,8 +4663,9 @@ impl Editor { let editor_handle = active_item.act_as::(cx)?; let editor = editor_handle.read(cx); - let head = editor.newest_selection::(cx).head(); - let (buffer, head) = editor.buffer.read(cx).text_anchor_for_position(head, cx)?; + let buffer = editor.buffer.read(cx); + let head = editor.selections.newest::(&buffer.read(cx)).head(); + let (buffer, head) = buffer.text_anchor_for_position(head, cx)?; let replica_id = editor.replica_id(cx); let project = workspace.project().clone(); @@ -4712,7 +4733,7 @@ impl Editor { use language::ToOffset as _; let project = self.project.clone()?; - let selection = self.newest_anchor_selection().clone(); + let selection = self.selections.newest_anchor().clone(); let (cursor_buffer, cursor_buffer_position) = self .buffer .read(cx) @@ -4901,8 +4922,12 @@ impl Editor { self.show_local_selections = true; if moving_cursor { - let cursor_in_rename_editor = - rename.editor.read(cx).newest_selection::(cx).head(); + let rename_editor = rename.editor.read(cx); + let rename_buffer = rename_editor.buffer.read(cx); + let cursor_in_rename_editor = rename_editor + .selections + .newest::(&rename_buffer.read(cx)) + .head(); // Update the selection to match the position of the selection inside // the rename editor. @@ -4913,17 +4938,14 @@ impl Editor { .min(rename_range.end); drop(snapshot); - self.update_selections( - vec![Selection { - id: self.newest_anchor_selection().id, - start: cursor_in_editor, - end: cursor_in_editor, - reversed: false, - goal: SelectionGoal::None, - }], - None, - cx, - ); + let new_selection = Selection { + id: self.selections.newest_anchor().id, + start: cursor_in_editor, + end: cursor_in_editor, + reversed: false, + goal: SelectionGoal::None, + }; + self.change_selections(true, cx, |s| s.select(vec![new_selection], None)); } Some(rename) @@ -5046,8 +5068,9 @@ impl Editor { if columns.start < line_len || (is_empty && columns.start == line_len) { let start = DisplayPoint::new(row, columns.start); let end = DisplayPoint::new(row, cmp::min(columns.end, line_len)); + // TODO: Don't expose next_selection_id Some(Selection { - id: post_inc(&mut self.next_selection_id), + id: post_inc(&mut self.selections.next_selection_id), start: start.to_point(display_map), end: end.to_point(display_map), reversed, @@ -5061,430 +5084,19 @@ impl Editor { } } - pub fn local_selections_in_range( - &self, - range: Range, - display_map: &DisplaySnapshot, - ) -> Vec> { - let buffer = &display_map.buffer_snapshot; - - let start_ix = match self - .selections - .binary_search_by(|probe| probe.end.cmp(&range.start, &buffer)) - { - Ok(ix) | Err(ix) => ix, - }; - let end_ix = match self - .selections - .binary_search_by(|probe| probe.start.cmp(&range.end, &buffer)) - { - Ok(ix) => ix + 1, - Err(ix) => ix, - }; - - fn point_selection( - selection: &Selection, - buffer: &MultiBufferSnapshot, - ) -> Selection { - let start = selection.start.to_point(&buffer); - let end = selection.end.to_point(&buffer); - Selection { - id: selection.id, - start, - end, - reversed: selection.reversed, - goal: selection.goal, - } - } - - self.selections[start_ix..end_ix] - .iter() - .chain( - self.pending_selection - .as_ref() - .map(|pending| &pending.selection), - ) - .map(|s| point_selection(s, &buffer)) - .collect() - } - - pub fn local_selections<'a, D>(&self, cx: &'a AppContext) -> Vec> - where - D: 'a + TextDimension + Ord + Sub, - { - let buffer = self.buffer.read(cx).snapshot(cx); - let mut selections = self - .resolve_selections::(self.selections.iter(), &buffer) - .peekable(); - - let mut pending_selection = self.pending_selection::(&buffer); - - iter::from_fn(move || { - if let Some(pending) = pending_selection.as_mut() { - while let Some(next_selection) = selections.peek() { - if pending.start <= next_selection.end && pending.end >= next_selection.start { - let next_selection = selections.next().unwrap(); - if next_selection.start < pending.start { - pending.start = next_selection.start; - } - if next_selection.end > pending.end { - pending.end = next_selection.end; - } - } else if next_selection.end < pending.start { - return selections.next(); - } else { - break; - } - } - - pending_selection.take() - } else { - selections.next() - } - }) - .collect() - } - - fn resolve_selections<'a, D, I>( - &self, - selections: I, - snapshot: &MultiBufferSnapshot, - ) -> impl 'a + Iterator> - where - D: TextDimension + Ord + Sub, - I: 'a + IntoIterator>, - { - let (to_summarize, selections) = selections.into_iter().tee(); - let mut summaries = snapshot - .summaries_for_anchors::(to_summarize.flat_map(|s| [&s.start, &s.end])) - .into_iter(); - selections.map(move |s| Selection { - id: s.id, - start: summaries.next().unwrap(), - end: summaries.next().unwrap(), - reversed: s.reversed, - goal: s.goal, - }) - } - - fn pending_selection>( - &self, - snapshot: &MultiBufferSnapshot, - ) -> Option> { - self.pending_selection - .as_ref() - .map(|pending| self.resolve_selection(&pending.selection, &snapshot)) - } - - fn resolve_selection>( - &self, - selection: &Selection, - buffer: &MultiBufferSnapshot, - ) -> Selection { - Selection { - id: selection.id, - start: selection.start.summary::(&buffer), - end: selection.end.summary::(&buffer), - reversed: selection.reversed, - goal: selection.goal, - } - } - - fn selection_count<'a>(&self) -> usize { - let mut count = self.selections.len(); - if self.pending_selection.is_some() { - count += 1; - } - count - } - - pub fn oldest_selection>( - &self, - cx: &AppContext, - ) -> Selection { - let snapshot = self.buffer.read(cx).read(cx); - self.selections - .iter() - .min_by_key(|s| s.id) - .map(|selection| self.resolve_selection(selection, &snapshot)) - .or_else(|| self.pending_selection(&snapshot)) - .unwrap() - } - - pub fn newest_selection>( - &self, - cx: &AppContext, - ) -> Selection { - self.resolve_selection( - self.newest_anchor_selection(), - &self.buffer.read(cx).read(cx), - ) - } - - pub fn newest_selection_with_snapshot>( - &self, - snapshot: &MultiBufferSnapshot, - ) -> Selection { - self.resolve_selection(self.newest_anchor_selection(), snapshot) - } - - pub fn newest_anchor_selection(&self) -> &Selection { - self.pending_selection - .as_ref() - .map(|s| &s.selection) - .or_else(|| self.selections.iter().max_by_key(|s| s.id)) - .unwrap() - } - - pub fn update_selections( - &mut self, - mut selections: Vec>, - autoscroll: Option, - cx: &mut ViewContext, - ) where - T: ToOffset + ToPoint + Ord + std::marker::Copy + std::fmt::Debug, - { - let buffer = self.buffer.read(cx).snapshot(cx); - selections.sort_unstable_by_key(|s| s.start); - - // Merge overlapping selections. - let mut i = 1; - while i < selections.len() { - if selections[i - 1].end >= selections[i].start { - let removed = selections.remove(i); - if removed.start < selections[i - 1].start { - selections[i - 1].start = removed.start; - } - if removed.end > selections[i - 1].end { - selections[i - 1].end = removed.end; - } - } else { - i += 1; - } - } - - if let Some(autoscroll) = autoscroll { - self.request_autoscroll(autoscroll, cx); - } - - self.set_selections( - Arc::from_iter(selections.into_iter().map(|selection| { - let end_bias = if selection.end > selection.start { - Bias::Left - } else { - Bias::Right - }; - Selection { - id: selection.id, - start: buffer.anchor_after(selection.start), - end: buffer.anchor_at(selection.end, end_bias), - reversed: selection.reversed, - goal: selection.goal, - } - })), - None, - true, - cx, - ); - } - pub fn set_selections_from_remote( &mut self, - mut selections: Vec>, + selections: Vec>, cx: &mut ViewContext, ) { - let buffer = self.buffer.read(cx); - let buffer = buffer.read(cx); - selections.sort_by(|a, b| { - a.start - .cmp(&b.start, &*buffer) - .then_with(|| b.end.cmp(&a.end, &*buffer)) + self.change_selections(false, cx, |s| { + s.select_anchors(selections, None); }); - - // Merge overlapping selections - let mut i = 1; - while i < selections.len() { - if selections[i - 1] - .end - .cmp(&selections[i].start, &*buffer) - .is_ge() - { - let removed = selections.remove(i); - if removed - .start - .cmp(&selections[i - 1].start, &*buffer) - .is_lt() - { - selections[i - 1].start = removed.start; - } - if removed.end.cmp(&selections[i - 1].end, &*buffer).is_gt() { - selections[i - 1].end = removed.end; - } - } else { - i += 1; - } - } - - drop(buffer); - self.set_selections(selections.into(), None, false, cx); - } - - /// Compute new ranges for any selections that were located in excerpts that have - /// since been removed. - /// - /// Returns a `HashMap` indicating which selections whose former head position - /// was no longer present. The keys of the map are selection ids. The values are - /// the id of the new excerpt where the head of the selection has been moved. - pub fn refresh_selections(&mut self, cx: &mut ViewContext) -> HashMap { - let snapshot = self.buffer.read(cx).read(cx); - let mut selections_with_lost_position = HashMap::default(); - - let mut pending_selection = self.pending_selection.take(); - if let Some(pending) = pending_selection.as_mut() { - let anchors = - snapshot.refresh_anchors([&pending.selection.start, &pending.selection.end]); - let (_, start, kept_start) = anchors[0].clone(); - let (_, end, kept_end) = anchors[1].clone(); - let kept_head = if pending.selection.reversed { - kept_start - } else { - kept_end - }; - if !kept_head { - selections_with_lost_position.insert( - pending.selection.id, - pending.selection.head().excerpt_id.clone(), - ); - } - - pending.selection.start = start; - pending.selection.end = end; - } - - let anchors_with_status = snapshot.refresh_anchors( - self.selections - .iter() - .flat_map(|selection| [&selection.start, &selection.end]), - ); - self.selections = anchors_with_status - .chunks(2) - .map(|selection_anchors| { - let (anchor_ix, start, kept_start) = selection_anchors[0].clone(); - let (_, end, kept_end) = selection_anchors[1].clone(); - let selection = &self.selections[anchor_ix / 2]; - let kept_head = if selection.reversed { - kept_start - } else { - kept_end - }; - if !kept_head { - selections_with_lost_position - .insert(selection.id, selection.head().excerpt_id.clone()); - } - - Selection { - id: selection.id, - start, - end, - reversed: selection.reversed, - goal: selection.goal, - } - }) - .collect(); - drop(snapshot); - - let new_selections = self.local_selections::(cx); - if !new_selections.is_empty() { - self.update_selections(new_selections, Some(Autoscroll::Fit), cx); - } - self.pending_selection = pending_selection; - - selections_with_lost_position - } - - fn set_selections( - &mut self, - selections: Arc<[Selection]>, - pending_selection: Option, - local: bool, - cx: &mut ViewContext, - ) { - assert!( - !selections.is_empty() || pending_selection.is_some(), - "must have at least one selection" - ); - - let old_cursor_position = self.newest_anchor_selection().head(); - - self.push_to_selection_history(); - self.selections = selections; - self.pending_selection = pending_selection; - if self.focused && self.leader_replica_id.is_none() { - self.buffer.update(cx, |buffer, cx| { - buffer.set_active_selections(&self.selections, cx) - }); - } - - let display_map = self - .display_map - .update(cx, |display_map, cx| display_map.snapshot(cx)); - let buffer = &display_map.buffer_snapshot; - self.add_selections_state = None; - self.select_next_state = None; - self.select_larger_syntax_node_stack.clear(); - self.autoclose_stack.invalidate(&self.selections, &buffer); - self.snippet_stack.invalidate(&self.selections, &buffer); - self.take_rename(false, cx); - - let new_cursor_position = self.newest_anchor_selection().head(); - - self.push_to_nav_history( - old_cursor_position.clone(), - Some(new_cursor_position.to_point(&buffer)), - cx, - ); - - if local { - let completion_menu = match self.context_menu.as_mut() { - Some(ContextMenu::Completions(menu)) => Some(menu), - _ => { - self.context_menu.take(); - None - } - }; - - if let Some(completion_menu) = completion_menu { - let cursor_position = new_cursor_position.to_offset(&buffer); - let (word_range, kind) = - buffer.surrounding_word(completion_menu.initial_position.clone()); - if kind == Some(CharKind::Word) - && word_range.to_inclusive().contains(&cursor_position) - { - let query = Self::completion_query(&buffer, cursor_position); - cx.background() - .block(completion_menu.filter(query.as_deref(), cx.background().clone())); - self.show_completions(&ShowCompletions, cx); - } else { - self.hide_context_menu(cx); - } - } - - if old_cursor_position.to_display_point(&display_map).row() - != new_cursor_position.to_display_point(&display_map).row() - { - self.available_code_actions.take(); - } - self.refresh_code_actions(cx); - self.refresh_document_highlights(cx); - } - - self.pause_cursor_blinking(cx); - cx.emit(Event::SelectionsChanged { local }); } fn push_to_selection_history(&mut self) { self.selection_history.push(SelectionHistoryEntry { - selections: self.selections.clone(), + selections: self.selections.disjoint_anchors().clone(), select_next_state: self.select_next_state.clone(), add_selections_state: self.add_selections_state.clone(), }); @@ -5517,7 +5129,7 @@ impl Editor { .update(cx, |buffer, cx| buffer.start_transaction_at(now, cx)) { self.selection_history - .insert_transaction(tx_id, self.selections.clone()); + .insert_transaction(tx_id, self.selections.disjoint_anchors().clone()); } } @@ -5527,7 +5139,7 @@ impl Editor { .update(cx, |buffer, cx| buffer.end_transaction_at(now, cx)) { if let Some((_, end_selections)) = self.selection_history.transaction_mut(tx_id) { - *end_selections = Some(self.selections.clone()); + *end_selections = Some(self.selections.disjoint_anchors().clone()); } else { log::error!("unexpectedly ended a transaction that wasn't started by this editor"); } @@ -5547,8 +5159,10 @@ impl Editor { pub fn fold(&mut self, _: &Fold, cx: &mut ViewContext) { let mut fold_ranges = Vec::new(); - let selections = self.local_selections::(cx); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); + let selections = self + .selections + .interleaved::(&display_map.buffer_snapshot); for selection in selections { let range = selection.display_range(&display_map).sorted(); let buffer_start_row = range.start.to_point(&display_map).row; @@ -5570,9 +5184,9 @@ impl Editor { } pub fn unfold_lines(&mut self, _: &UnfoldLines, cx: &mut ViewContext) { - let selections = self.local_selections::(cx); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = &display_map.buffer_snapshot; + let selections = self.selections.interleaved::(buffer); let ranges = selections .iter() .map(|s| { @@ -5630,7 +5244,9 @@ impl Editor { } pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext) { - let selections = self.local_selections::(cx); + let selections = self + .selections + .interleaved::(&self.buffer.read(cx).read(cx)); let ranges = selections.into_iter().map(|s| s.start..s.end); self.fold_ranges(ranges, cx); } @@ -6007,7 +5623,7 @@ impl Editor { } let mut new_selections_by_buffer = HashMap::default(); - for selection in editor.local_selections::(cx) { + for selection in editor.selections.interleaved::(&buffer.read(cx)) { for (buffer, mut range) in buffer.range_to_buffer_ranges(selection.start..selection.end, cx) { @@ -6022,7 +5638,7 @@ impl Editor { } editor_handle.update(cx, |editor, cx| { - editor.push_to_nav_history(editor.newest_anchor_selection().head(), None, cx); + editor.push_to_nav_history(editor.selections.newest_anchor().head(), None, cx); }); let nav_history = workspace.active_pane().read(cx).nav_history().clone(); nav_history.borrow_mut().disable(); @@ -6034,7 +5650,9 @@ impl Editor { for (buffer, ranges) in new_selections_by_buffer.into_iter() { let editor = workspace.open_project_item::(buffer, cx); editor.update(cx, |editor, cx| { - editor.select_ranges(ranges, Some(Autoscroll::Newest), cx); + editor.change_selections(true, cx, |s| { + s.select_ranges(ranges, Some(Autoscroll::Newest)); + }); }); } @@ -6134,7 +5752,7 @@ impl View for Editor { self.buffer.update(cx, |buffer, cx| { buffer.finalize_last_transaction(cx); if self.leader_replica_id.is_none() { - buffer.set_active_selections(&self.selections, cx); + buffer.set_active_selections(&self.selections.disjoint_anchors(), cx); } }); } @@ -6571,7 +6189,7 @@ mod tests { use std::{cell::RefCell, rc::Rc, time::Instant}; use text::Point; use unindent::Unindent; - use util::test::{marked_text_by, marked_text_ranges, sample_text}; + use util::test::{marked_text_by, marked_text_ranges, marked_text_ranges_by, sample_text}; use workspace::{FollowableItem, ItemHandle}; #[gpui::test] @@ -6676,7 +6294,8 @@ mod tests { // No event is emitted when the mutation is a no-op. editor2.update(cx, |editor, cx| { - editor.select_ranges([0..0], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([0..0], None)); + editor.backspace(&Backspace, cx); }); assert_eq!(mem::take(&mut *events.borrow_mut()), []); @@ -6693,21 +6312,22 @@ mod tests { editor.update(cx, |editor, cx| { editor.start_transaction_at(now, cx); - editor.select_ranges([2..4], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([2..4], None)); + editor.insert("cd", cx); editor.end_transaction_at(now, cx); assert_eq!(editor.text(cx), "12cd56"); assert_eq!(editor.selected_ranges(cx), vec![4..4]); editor.start_transaction_at(now, cx); - editor.select_ranges([4..5], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([4..5], None)); editor.insert("e", cx); editor.end_transaction_at(now, cx); assert_eq!(editor.text(cx), "12cde6"); assert_eq!(editor.selected_ranges(cx), vec![5..5]); now += group_interval + Duration::from_millis(1); - editor.select_ranges([2..2], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([2..2], None)); // Simulate an edit in another editor buffer.update(cx, |buffer, cx| { @@ -6861,13 +6481,19 @@ mod tests { // Move the cursor a small distance. // Nothing is added to the navigation history. - editor.select_display_ranges(&[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)], cx); - editor.select_display_ranges(&[DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]) + }); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)]) + }); assert!(nav_history.borrow_mut().pop_backward().is_none()); // Move the cursor a large distance. // The history can jump back to the previous position. - editor.select_display_ranges(&[DisplayPoint::new(13, 0)..DisplayPoint::new(13, 3)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(13, 0)..DisplayPoint::new(13, 3)]) + }); let nav_entry = nav_history.borrow_mut().pop_backward().unwrap(); editor.navigate(nav_entry.data.unwrap(), cx); assert_eq!(nav_entry.item.id(), cx.view_id()); @@ -7014,7 +6640,9 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); view.update(cx, |view, cx| { - view.select_display_ranges(&[DisplayPoint::new(8, 0)..DisplayPoint::new(12, 0)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(8, 0)..DisplayPoint::new(12, 0)]); + }); view.fold(&Fold, cx); assert_eq!( view.display_text(cx), @@ -7130,7 +6758,9 @@ mod tests { &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] ); - view.select_display_ranges(&[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2)]); + }); view.select_to_beginning(&SelectToBeginning, cx); assert_eq!( view.selected_display_ranges(cx), @@ -7252,7 +6882,9 @@ mod tests { let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); view.update(cx, |view, cx| { - view.select_display_ranges(&[empty_range(0, "ⓐⓑⓒⓓⓔ".len())], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([empty_range(0, "ⓐⓑⓒⓓⓔ".len())]); + }); view.move_down(&MoveDown, cx); assert_eq!( view.selected_display_ranges(cx), @@ -7297,13 +6929,12 @@ mod tests { let buffer = MultiBuffer::build_simple("abc\n def", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4), - ], - cx, - ); + ]); + }); }); view.update(cx, |view, cx| { @@ -7458,13 +7089,12 @@ mod tests { let buffer = MultiBuffer::build_simple("use std::str::{foo, bar}\n\n {baz.qux()}", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 11)..DisplayPoint::new(0, 11), DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4), - ], - cx, - ); + ]) + }); view.move_to_previous_word_start(&MoveToPreviousWordStart, cx); assert_selection_ranges( @@ -7570,7 +7200,9 @@ mod tests { "use one::{\n two::three::\n four::five\n};" ); - view.select_display_ranges(&[DisplayPoint::new(1, 7)..DisplayPoint::new(1, 7)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(1, 7)..DisplayPoint::new(1, 7)]); + }); view.move_to_next_word_end(&MoveToNextWordEnd, cx); assert_eq!( @@ -7619,7 +7251,7 @@ mod tests { let (_, editor) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); editor.update(cx, |editor, cx| { - editor.select_ranges(ranges, None, cx); + editor.change_selections(true, cx, |s| s.select_ranges(ranges, None)); editor.delete_to_beginning_of_line(&DeleteToBeginningOfLine, cx); assert_eq!(editor.text(cx), " four"); }); @@ -7632,30 +7264,28 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ // an empty selection - the preceding word fragment is deleted DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), // characters selected - they are deleted DisplayPoint::new(0, 9)..DisplayPoint::new(0, 12), - ], - cx, - ); + ]) + }); view.delete_to_previous_word_start(&DeleteToPreviousWordStart, cx); }); assert_eq!(buffer.read(cx).read(cx).text(), "e two te four"); view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ // an empty selection - the following word fragment is deleted DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), // characters selected - they are deleted DisplayPoint::new(0, 9)..DisplayPoint::new(0, 10), - ], - cx, - ); + ]) + }); view.delete_to_next_word_end(&DeleteToNextWordEnd, cx); }); @@ -7669,14 +7299,13 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), DisplayPoint::new(1, 6)..DisplayPoint::new(1, 6), - ], - cx, - ); + ]) + }); view.newline(&Newline, cx); assert_eq!(view.text(cx), "aa\naa\n \n bb\n bb\n"); @@ -7703,14 +7332,15 @@ mod tests { let (_, editor) = cx.add_window(Default::default(), |cx| { let mut editor = build_editor(buffer.clone(), cx); - editor.select_ranges( - [ - Point::new(2, 4)..Point::new(2, 5), - Point::new(5, 4)..Point::new(5, 5), - ], - None, - cx, - ); + editor.change_selections(true, cx, |s| { + s.select_ranges( + [ + Point::new(2, 4)..Point::new(2, 5), + Point::new(5, 4)..Point::new(5, 5), + ], + None, + ) + }); editor }); @@ -7773,7 +7403,7 @@ mod tests { let buffer = MultiBuffer::build_simple("a( X ), b( Y ), c( Z )", cx); let (_, editor) = cx.add_window(Default::default(), |cx| { let mut editor = build_editor(buffer.clone(), cx); - editor.select_ranges([3..4, 11..12, 19..20], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([3..4, 11..12, 19..20], None)); editor }); @@ -8022,23 +7652,22 @@ mod tests { view.update(cx, |view, cx| { view.set_text("one two three\nfour five six\nseven eight nine\nten\n", cx); - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ // an empty selection - the preceding character is deleted DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), // one character selected - it is deleted DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3), // a line suffix selected - it is deleted DisplayPoint::new(2, 6)..DisplayPoint::new(3, 0), - ], - cx, - ); + ]) + }); view.backspace(&Backspace, cx); assert_eq!(view.text(cx), "oe two three\nfou five six\nseven ten\n"); view.set_text(" one\n two\n three\n four", cx); - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ // cursors at the the end of leading indent - last indent is deleted DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4), DisplayPoint::new(1, 8)..DisplayPoint::new(1, 8), @@ -8050,9 +7679,8 @@ mod tests { DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0), // selection inside leading indent - only the selected character is deleted DisplayPoint::new(3, 2)..DisplayPoint::new(3, 3), - ], - cx, - ); + ]) + }); view.backspace(&Backspace, cx); assert_eq!(view.text(cx), "one\n two\n three four"); }); @@ -8066,17 +7694,16 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ // an empty selection - the following character is deleted DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), // one character selected - it is deleted DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3), // a line suffix selected - it is deleted DisplayPoint::new(2, 6)..DisplayPoint::new(3, 0), - ], - cx, - ); + ]) + }); view.delete(&Delete, cx); }); @@ -8092,14 +7719,13 @@ mod tests { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0), - ], - cx, - ); + ]) + }); view.delete_line(&DeleteLine, cx); assert_eq!(view.display_text(cx), "ghi"); assert_eq!( @@ -8115,7 +7741,9 @@ mod tests { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.select_display_ranges(&[DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)]) + }); view.delete_line(&DeleteLine, cx); assert_eq!(view.display_text(cx), "ghi\n"); assert_eq!( @@ -8131,15 +7759,14 @@ mod tests { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1), DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0), - ], - cx, - ); + ]) + }); view.duplicate_line(&DuplicateLine, cx); assert_eq!(view.display_text(cx), "abc\nabc\ndef\ndef\nghi\n\n"); assert_eq!( @@ -8156,13 +7783,12 @@ mod tests { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(1, 2)..DisplayPoint::new(2, 1), - ], - cx, - ); + ]) + }); view.duplicate_line(&DuplicateLine, cx); assert_eq!(view.display_text(cx), "abc\ndef\nghi\nabc\ndef\nghi\n"); assert_eq!( @@ -8189,15 +7815,14 @@ mod tests { ], cx, ); - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1), DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3), DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2), - ], - cx, - ); + ]) + }); assert_eq!( view.display_text(cx), "aa…bbb\nccc…eeee\nfffff\nggggg\n…i\njjjjj" @@ -8287,7 +7912,9 @@ mod tests { }], cx, ); - editor.select_ranges([Point::new(2, 0)..Point::new(2, 0)], None, cx); + editor.change_selections(true, cx, |s| { + s.select_ranges([Point::new(2, 0)..Point::new(2, 0)], None) + }); editor.move_line_down(&MoveLineDown, cx); }); } @@ -8299,7 +7926,7 @@ mod tests { cx.add_window(Default::default(), |cx| { let mut editor = build_editor(MultiBuffer::build_simple("abc", cx), cx); - editor.select_ranges([1..1], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([1..1], None)); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bac"); assert_eq!(editor.selected_ranges(cx), [2..2]); @@ -8319,12 +7946,12 @@ mod tests { cx.add_window(Default::default(), |cx| { let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); - editor.select_ranges([3..3], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([3..3], None)); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acb\nde"); assert_eq!(editor.selected_ranges(cx), [3..3]); - editor.select_ranges([4..4], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([4..4], None)); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acbd\ne"); assert_eq!(editor.selected_ranges(cx), [5..5]); @@ -8344,7 +7971,7 @@ mod tests { cx.add_window(Default::default(), |cx| { let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); - editor.select_ranges([1..1, 2..2, 4..4], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([1..1, 2..2, 4..4], None)); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bacd\ne"); assert_eq!(editor.selected_ranges(cx), [2..2, 3..3, 5..5]); @@ -8372,7 +7999,7 @@ mod tests { cx.add_window(Default::default(), |cx| { let mut editor = build_editor(MultiBuffer::build_simple("🍐🏀✋", cx), cx); - editor.select_ranges([4..4], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([4..4], None)); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "🏀🍐✋"); assert_eq!(editor.selected_ranges(cx), [8..8]); @@ -8400,14 +8027,18 @@ mod tests { // Cut with three selections. Clipboard text is divided into three slices. view.update(cx, |view, cx| { - view.select_ranges(vec![0..7, 11..17, 22..27], None, cx); + view.change_selections(true, cx, |s| { + s.select_ranges(vec![0..7, 11..17, 22..27], None) + }); view.cut(&Cut, cx); assert_eq!(view.display_text(cx), "two four six "); }); // Paste with three cursors. Each cursor pastes one slice of the clipboard text. view.update(cx, |view, cx| { - view.select_ranges(vec![4..4, 9..9, 13..13], None, cx); + view.change_selections(true, cx, |s| { + s.select_ranges(vec![4..4, 9..9, 13..13], None) + }); view.paste(&Paste, cx); assert_eq!(view.display_text(cx), "two one✅ four three six five "); assert_eq!( @@ -8424,7 +8055,7 @@ mod tests { // match the number of slices in the clipboard, the entire clipboard text // is pasted at each cursor. view.update(cx, |view, cx| { - view.select_ranges(vec![0..0, 31..31], None, cx); + view.change_selections(true, cx, |s| s.select_ranges(vec![0..0, 31..31], None)); view.handle_input(&Input("( ".into()), cx); view.paste(&Paste, cx); view.handle_input(&Input(") ".into()), cx); @@ -8435,7 +8066,7 @@ mod tests { }); view.update(cx, |view, cx| { - view.select_ranges(vec![0..0], None, cx); + view.change_selections(true, cx, |s| s.select_ranges(vec![0..0], None)); view.handle_input(&Input("123\n4567\n89\n".into()), cx); assert_eq!( view.display_text(cx), @@ -8445,14 +8076,13 @@ mod tests { // Cut with three selections, one of which is full-line. view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| s.select_display_ranges( + [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(2, 0)..DisplayPoint::new(2, 1), ], - cx, - ); + )); view.cut(&Cut, cx); assert_eq!( view.display_text(cx), @@ -8463,14 +8093,13 @@ mod tests { // Paste with three selections, noticing how the copied selection that was full-line // gets inserted before the second cursor. view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| s.select_display_ranges( + [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(2, 2)..DisplayPoint::new(2, 3), ], - cx, - ); + )); view.paste(&Paste, cx); assert_eq!( view.display_text(cx), @@ -8488,21 +8117,22 @@ mod tests { // Copy with a single cursor only, which writes the whole line into the clipboard. view.update(cx, |view, cx| { - view.select_display_ranges(&[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)]) + }); view.copy(&Copy, cx); }); // Paste with three selections, noticing how the copied full-line selection is inserted // before the empty selections but replaces the selection that is non-empty. view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| s.select_display_ranges( + [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 2), DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), ], - cx, - ); + )); view.paste(&Paste, cx); assert_eq!( view.display_text(cx), @@ -8539,15 +8169,14 @@ mod tests { let buffer = MultiBuffer::build_simple(&sample_text(6, 5, 'a'), cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1), DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), DisplayPoint::new(4, 2)..DisplayPoint::new(4, 2), - ], - cx, - ); + ]) + }); view.select_line(&SelectLine, cx); assert_eq!( view.selected_display_ranges(cx), @@ -8592,15 +8221,14 @@ mod tests { ], cx, ); - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1), DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), DisplayPoint::new(4, 4)..DisplayPoint::new(4, 4), - ], - cx, - ); + ]) + }); assert_eq!(view.display_text(cx), "aa…bbb\nccc…eeee\nfffff\nggggg\n…i"); }); @@ -8622,7 +8250,9 @@ mod tests { }); view.update(cx, |view, cx| { - view.select_display_ranges(&[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 1)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(5, 0)..DisplayPoint::new(0, 1)]) + }); view.split_selection_into_lines(&SplitSelectionIntoLines, cx); assert_eq!( view.display_text(cx), @@ -8651,7 +8281,9 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.select_display_ranges(&[DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)]) + }); }); view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); @@ -8721,7 +8353,9 @@ mod tests { }); view.update(cx, |view, cx| { - view.select_display_ranges(&[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)]) + }); }); view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); @@ -8762,7 +8396,9 @@ mod tests { }); view.update(cx, |view, cx| { - view.select_display_ranges(&[DisplayPoint::new(0, 1)..DisplayPoint::new(1, 4)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(0, 1)..DisplayPoint::new(1, 4)]) + }); view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( view.selected_display_ranges(cx), @@ -8800,7 +8436,9 @@ mod tests { }); view.update(cx, |view, cx| { - view.select_display_ranges(&[DisplayPoint::new(4, 3)..DisplayPoint::new(1, 1)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(4, 3)..DisplayPoint::new(1, 1)]) + }); }); view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); @@ -8837,7 +8475,9 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.select_ranges([ranges[1].start + 1..ranges[1].start + 1], None, cx); + view.change_selections(true, cx, |s| { + s.select_ranges([ranges[1].start + 1..ranges[1].start + 1], None) + }); view.select_next( &SelectNext { replace_newest: false, @@ -8902,14 +8542,13 @@ mod tests { .await; view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25), DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12), DisplayPoint::new(3, 18)..DisplayPoint::new(3, 18), - ], - cx, - ); + ]); + }); view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( @@ -9062,7 +8701,7 @@ mod tests { .await; editor.update(cx, |editor, cx| { - editor.select_ranges([5..5, 8..8, 9..9], None, cx); + editor.change_selections(true, cx, |s| s.select_ranges([5..5, 8..8, 9..9], None)); editor.newline(&Newline, cx); assert_eq!(editor.text(cx), "fn a(\n \n) {\n \n}\n"); assert_eq!( @@ -9116,13 +8755,12 @@ mod tests { .await; view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), - ], - cx, - ); + ]) + }); view.handle_input(&Input("{".to_string()), cx); view.handle_input(&Input("{".to_string()), cx); @@ -9168,13 +8806,12 @@ mod tests { ); view.undo(&Undo, cx); - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0), - ], - cx, - ); + ]) + }); view.handle_input(&Input("*".to_string()), cx); assert_eq!( view.text(cx), @@ -9190,7 +8827,9 @@ mod tests { // Don't autoclose if the next character isn't whitespace and isn't // listed in the language's "autoclose_before" section. view.finalize_last_transaction(cx); - view.select_display_ranges(&[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]) + }); view.handle_input(&Input("{".to_string()), cx); assert_eq!( view.text(cx), @@ -9204,7 +8843,9 @@ mod tests { ); view.undo(&Undo, cx); - view.select_display_ranges(&[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1)], cx); + view.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1)]) + }); view.handle_input(&Input("{".to_string()), cx); assert_eq!( view.text(cx), @@ -9227,105 +8868,88 @@ mod tests { async fn test_snippets(cx: &mut gpui::TestAppContext) { cx.update(|cx| cx.set_global(Settings::test(cx))); - let text = " - a. b - a. b - a. b - " - .unindent(); + let (text, insertion_ranges) = marked_text_ranges(indoc! {" + a.| b + a.| b + a.| b"}); let buffer = cx.update(|cx| MultiBuffer::build_simple(&text, cx)); let (_, editor) = cx.add_window(|cx| build_editor(buffer, cx)); editor.update(cx, |editor, cx| { - let buffer = &editor.snapshot(cx).buffer_snapshot; let snippet = Snippet::parse("f(${1:one}, ${2:two}, ${1:three})$0").unwrap(); - let insertion_ranges = [ - Point::new(0, 2).to_offset(buffer)..Point::new(0, 2).to_offset(buffer), - Point::new(1, 2).to_offset(buffer)..Point::new(1, 2).to_offset(buffer), - Point::new(2, 2).to_offset(buffer)..Point::new(2, 2).to_offset(buffer), - ]; editor .insert_snippet(&insertion_ranges, snippet, cx) .unwrap(); - assert_eq!( - editor.text(cx), - " - a.f(one, two, three) b - a.f(one, two, three) b - a.f(one, two, three) b - " - .unindent() - ); - assert_eq!( - editor.selected_ranges::(cx), - &[ - Point::new(0, 4)..Point::new(0, 7), - Point::new(0, 14)..Point::new(0, 19), - Point::new(1, 4)..Point::new(1, 7), - Point::new(1, 14)..Point::new(1, 19), - Point::new(2, 4)..Point::new(2, 7), - Point::new(2, 14)..Point::new(2, 19), - ] + + fn assert(editor: &mut Editor, cx: &mut ViewContext, marked_text_ranges: &str) { + let range_markers = ('<', '>'); + let (expected_text, mut selection_ranges_lookup) = + marked_text_ranges_by(marked_text_ranges, vec![range_markers.clone()]); + let selection_ranges = selection_ranges_lookup.remove(&range_markers).unwrap(); + assert_eq!(editor.text(cx), expected_text); + assert_eq!(editor.selected_ranges::(cx), selection_ranges); + } + assert( + editor, + cx, + indoc! {" + a.f(, two, ) b + a.f(, two, ) b + a.f(, two, ) b"}, ); // Can't move earlier than the first tab stop - editor.move_to_prev_snippet_tabstop(cx); - assert_eq!( - editor.selected_ranges::(cx), - &[ - Point::new(0, 4)..Point::new(0, 7), - Point::new(0, 14)..Point::new(0, 19), - Point::new(1, 4)..Point::new(1, 7), - Point::new(1, 14)..Point::new(1, 19), - Point::new(2, 4)..Point::new(2, 7), - Point::new(2, 14)..Point::new(2, 19), - ] + assert!(!editor.move_to_prev_snippet_tabstop(cx)); + assert( + editor, + cx, + indoc! {" + a.f(, two, ) b + a.f(, two, ) b + a.f(, two, ) b"}, ); assert!(editor.move_to_next_snippet_tabstop(cx)); - assert_eq!( - editor.selected_ranges::(cx), - &[ - Point::new(0, 9)..Point::new(0, 12), - Point::new(1, 9)..Point::new(1, 12), - Point::new(2, 9)..Point::new(2, 12) - ] + assert( + editor, + cx, + indoc! {" + a.f(one, , three) b + a.f(one, , three) b + a.f(one, , three) b"}, ); editor.move_to_prev_snippet_tabstop(cx); - assert_eq!( - editor.selected_ranges::(cx), - &[ - Point::new(0, 4)..Point::new(0, 7), - Point::new(0, 14)..Point::new(0, 19), - Point::new(1, 4)..Point::new(1, 7), - Point::new(1, 14)..Point::new(1, 19), - Point::new(2, 4)..Point::new(2, 7), - Point::new(2, 14)..Point::new(2, 19), - ] + assert( + editor, + cx, + indoc! {" + a.f(, two, ) b + a.f(, two, ) b + a.f(, two, ) b"}, ); assert!(editor.move_to_next_snippet_tabstop(cx)); assert!(editor.move_to_next_snippet_tabstop(cx)); - assert_eq!( - editor.selected_ranges::(cx), - &[ - Point::new(0, 20)..Point::new(0, 20), - Point::new(1, 20)..Point::new(1, 20), - Point::new(2, 20)..Point::new(2, 20) - ] + assert( + editor, + cx, + indoc! {" + a.f(one, two, three)<> b + a.f(one, two, three)<> b + a.f(one, two, three)<> b"}, ); // As soon as the last tab stop is reached, snippet state is gone editor.move_to_prev_snippet_tabstop(cx); - assert_eq!( - editor.selected_ranges::(cx), - &[ - Point::new(0, 20)..Point::new(0, 20), - Point::new(1, 20)..Point::new(1, 20), - Point::new(2, 20)..Point::new(2, 20) - ] + assert( + editor, + cx, + indoc! {" + a.f(one, two, three)<> b + a.f(one, two, three)<> b + a.f(one, two, three)<> b"}, ); }); } @@ -9489,7 +9113,9 @@ mod tests { editor.update(cx, |editor, cx| { editor.project = Some(project); - editor.select_ranges([Point::new(0, 3)..Point::new(0, 3)], None, cx); + editor.change_selections(true, cx, |s| { + s.select_ranges([Point::new(0, 3)..Point::new(0, 3)], None) + }); editor.handle_input(&Input(".".to_string()), cx); }); @@ -9542,14 +9168,15 @@ mod tests { ); editor.update(cx, |editor, cx| { - editor.select_ranges( - [ - Point::new(1, 3)..Point::new(1, 3), - Point::new(2, 5)..Point::new(2, 5), - ], - None, - cx, - ); + editor.change_selections(true, cx, |s| { + s.select_ranges( + [ + Point::new(1, 3)..Point::new(1, 3), + Point::new(2, 5)..Point::new(2, 5), + ], + None, + ) + }); editor.handle_input(&Input(" ".to_string()), cx); assert!(editor.context_menu.is_none()); @@ -9702,13 +9329,12 @@ mod tests { view.update(cx, |editor, cx| { // If multiple selections intersect a line, the line is only // toggled once. - editor.select_display_ranges( - &[ + editor.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(1, 3)..DisplayPoint::new(2, 3), DisplayPoint::new(3, 5)..DisplayPoint::new(3, 6), - ], - cx, - ); + ]) + }); editor.toggle_comments(&ToggleComments, cx); assert_eq!( editor.text(cx), @@ -9724,7 +9350,9 @@ mod tests { // The comment prefix is inserted at the same column for every line // in a selection. - editor.select_display_ranges(&[DisplayPoint::new(1, 3)..DisplayPoint::new(3, 6)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(1, 3)..DisplayPoint::new(3, 6)]) + }); editor.toggle_comments(&ToggleComments, cx); assert_eq!( editor.text(cx), @@ -9739,7 +9367,9 @@ mod tests { ); // If a selection ends at the beginning of a line, that line is not toggled. - editor.select_display_ranges(&[DisplayPoint::new(2, 0)..DisplayPoint::new(3, 0)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(3, 0)]) + }); editor.toggle_comments(&ToggleComments, cx); assert_eq!( editor.text(cx), @@ -9777,14 +9407,15 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(multibuffer, cx)); view.update(cx, |view, cx| { assert_eq!(view.text(cx), "aaaa\nbbbb"); - view.select_ranges( - [ - Point::new(0, 0)..Point::new(0, 0), - Point::new(1, 0)..Point::new(1, 0), - ], - None, - cx, - ); + view.change_selections(true, cx, |s| { + s.select_ranges( + [ + Point::new(0, 0)..Point::new(0, 0), + Point::new(1, 0)..Point::new(1, 0), + ], + None, + ) + }); view.handle_input(&Input("X".to_string()), cx); assert_eq!(view.text(cx), "Xaaaa\nXbbbb"); @@ -9820,7 +9451,7 @@ mod tests { b|bb|b cccc"}); assert_eq!(view.text(cx), expected_text); - view.select_ranges(selection_ranges, None, cx); + view.change_selections(true, cx, |s| s.select_ranges(selection_ranges, None)); view.handle_input(&Input("X".to_string()), cx); @@ -9874,7 +9505,9 @@ mod tests { let (_, editor) = cx.add_window(Default::default(), |cx| { let mut editor = build_editor(multibuffer.clone(), cx); let snapshot = editor.snapshot(cx); - editor.select_ranges([Point::new(1, 3)..Point::new(1, 3)], None, cx); + editor.change_selections(true, cx, |s| { + s.select_ranges([Point::new(1, 3)..Point::new(1, 3)], None) + }); editor.begin_selection(Point::new(2, 1).to_display_point(&snapshot), true, 1, cx); assert_eq!( editor.selected_ranges(cx), @@ -9888,7 +9521,9 @@ mod tests { // Refreshing selections is a no-op when excerpts haven't changed. editor.update(cx, |editor, cx| { - editor.refresh_selections(cx); + editor.change_selections(true, cx, |s| { + s.refresh(); + }); assert_eq!( editor.selected_ranges(cx), [ @@ -9913,7 +9548,9 @@ mod tests { // Refreshing selections will relocate the first selection to the original buffer // location. - editor.refresh_selections(cx); + editor.change_selections(true, cx, |s| { + s.refresh(); + }); assert_eq!( editor.selected_ranges(cx), [ @@ -9921,7 +9558,7 @@ mod tests { Point::new(0, 3)..Point::new(0, 3) ] ); - assert!(editor.pending_selection.is_some()); + assert!(editor.selections.pending_anchor().is_some()); }); } @@ -9970,12 +9607,14 @@ mod tests { ); // Ensure we don't panic when selections are refreshed and that the pending selection is finalized. - editor.refresh_selections(cx); + editor.change_selections(true, cx, |s| { + s.refresh(); + }); assert_eq!( editor.selected_ranges(cx), [Point::new(0, 3)..Point::new(0, 3)] ); - assert!(editor.pending_selection.is_some()); + assert!(editor.selections.pending_anchor().is_some()); }); } @@ -10018,14 +9657,13 @@ mod tests { .await; view.update(cx, |view, cx| { - view.select_display_ranges( - &[ + view.change_selections(true, cx, |s| { + s.select_display_ranges([ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 3), DisplayPoint::new(2, 5)..DisplayPoint::new(2, 5), DisplayPoint::new(4, 4)..DisplayPoint::new(4, 4), - ], - cx, - ); + ]) + }); view.newline(&Newline, cx); assert_eq!( @@ -10158,7 +9796,7 @@ mod tests { // Update the selections only leader.update(cx, |leader, cx| { - leader.select_ranges([1..1], None, cx); + leader.change_selections(true, cx, |s| s.select_ranges([1..1], None)); }); follower.update(cx, |follower, cx| { follower @@ -10183,7 +9821,7 @@ mod tests { // Update the selections and scroll position leader.update(cx, |leader, cx| { - leader.select_ranges([0..0], None, cx); + leader.change_selections(true, cx, |s| s.select_ranges([0..0], None)); leader.request_autoscroll(Autoscroll::Newest, cx); leader.set_scroll_position(vec2f(1.5, 3.5), cx); }); @@ -10199,7 +9837,7 @@ mod tests { // Creating a pending selection that precedes another selection leader.update(cx, |leader, cx| { - leader.select_ranges([1..1], None, cx); + leader.change_selections(true, cx, |s| s.select_ranges([1..1], None)); leader.begin_selection(DisplayPoint::new(0, 0), true, 1, cx); }); follower.update(cx, |follower, cx| { diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index a04d27a8bb..dcef624d01 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -957,8 +957,9 @@ impl Element for EditorElement { selections.extend(remote_selections); if view.show_local_selections { - let local_selections = - view.local_selections_in_range(start_anchor..end_anchor, &display_map); + let local_selections = view + .selections + .interleaved_in_range(start_anchor..end_anchor, &display_map.buffer_snapshot); for selection in &local_selections { let is_empty = selection.start == selection.end; let selection_start = snapshot.prev_line_boundary(selection.start).1; @@ -1041,7 +1042,8 @@ impl Element for EditorElement { } let newest_selection_head = view - .newest_selection_with_snapshot::(&snapshot.buffer_snapshot) + .selections + .newest::(&snapshot.buffer_snapshot) .head() .to_display_point(&snapshot); diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 120826321b..b87719c130 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -102,7 +102,7 @@ impl FollowableItem for Editor { } else { self.buffer.update(cx, |buffer, cx| { if self.focused { - buffer.set_active_selections(&self.selections, cx); + buffer.set_active_selections(&self.selections.disjoint_anchors(), cx); } }); } @@ -118,7 +118,12 @@ impl FollowableItem for Editor { )), scroll_x: self.scroll_position.x(), scroll_y: self.scroll_position.y(), - selections: self.selections.iter().map(serialize_selection).collect(), + selections: self + .selections + .disjoint_anchors() + .iter() + .map(serialize_selection) + .collect(), })) } @@ -144,8 +149,9 @@ impl FollowableItem for Editor { Event::SelectionsChanged { .. } => { update.selections = self .selections + .disjoint_anchors() .iter() - .chain(self.pending_selection.as_ref().map(|p| &p.selection)) + .chain(self.selections.pending_anchor().as_ref()) .map(serialize_selection) .collect(); true @@ -252,7 +258,7 @@ impl Item for Editor { } else { buffer.clip_point(data.cursor_position, Bias::Left) }; - let newest_selection = self.newest_selection_with_snapshot::(&buffer); + let newest_selection = self.selections.newest::(&buffer); let scroll_top_anchor = if buffer.can_resolve(&data.scroll_top_anchor) { data.scroll_top_anchor @@ -270,7 +276,9 @@ impl Item for Editor { let nav_history = self.nav_history.take(); self.scroll_position = data.scroll_position; self.scroll_top_anchor = scroll_top_anchor; - self.select_ranges([offset..offset], Some(Autoscroll::Fit), cx); + self.change_selections(true, cx, |s| { + s.select_ranges([offset..offset], Some(Autoscroll::Fit)) + }); self.nav_history = nav_history; true } @@ -307,7 +315,7 @@ impl Item for Editor { } fn deactivated(&mut self, cx: &mut ViewContext) { - let selection = self.newest_anchor_selection(); + let selection = self.selections.newest_anchor(); self.push_to_nav_history(selection.head(), None, cx); } @@ -457,7 +465,7 @@ impl CursorPosition { self.selected_count = 0; let mut last_selection: Option> = None; - for selection in editor.local_selections::(cx) { + for selection in editor.selections.interleaved::(&buffer) { self.selected_count += selection.end - selection.start; if last_selection .as_ref() diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs new file mode 100644 index 0000000000..fc2f563099 --- /dev/null +++ b/crates/editor/src/selections_collection.rs @@ -0,0 +1,703 @@ +use std::{ + iter, mem, + ops::{Deref, Range, Sub}, + sync::Arc, +}; + +use collections::HashMap; +use gpui::{ModelHandle, MutableAppContext}; +use itertools::Itertools; +use language::{rope::TextDimension, Bias, Point, Selection, SelectionGoal, ToPoint}; +use util::post_inc; + +use crate::{ + display_map::{DisplayMap, DisplaySnapshot, ToDisplayPoint}, + Anchor, Autoscroll, DisplayPoint, ExcerptId, MultiBuffer, MultiBufferSnapshot, SelectMode, + ToOffset, +}; + +#[derive(Clone)] +pub struct PendingSelection { + pub selection: Selection, + pub mode: SelectMode, +} + +pub struct SelectionsCollection { + pub next_selection_id: usize, + disjoint: Arc<[Selection]>, + pending: Option, +} + +impl SelectionsCollection { + pub fn new() -> Self { + Self { + next_selection_id: 1, + disjoint: Arc::from([]), + pending: Some(PendingSelection { + selection: Selection { + id: 0, + start: Anchor::min(), + end: Anchor::min(), + reversed: false, + goal: SelectionGoal::None, + }, + mode: SelectMode::Character, + }), + } + } + + pub fn count<'a>(&self) -> usize { + let mut count = self.disjoint.len(); + if self.pending.is_some() { + count += 1; + } + count + } + + pub fn disjoint_anchors(&self) -> Arc<[Selection]> { + self.disjoint.clone() + } + + pub fn pending_anchor(&self) -> Option> { + self.pending + .as_ref() + .map(|pending| pending.selection.clone()) + } + + pub fn pending>( + &self, + snapshot: &MultiBufferSnapshot, + ) -> Option> { + self.pending_anchor() + .as_ref() + .map(|pending| pending.map(|p| p.summary::(&snapshot))) + } + + pub fn pending_mode(&self) -> Option { + self.pending.as_ref().map(|pending| pending.mode.clone()) + } + + pub fn interleaved<'a, D>(&self, buffer: &MultiBufferSnapshot) -> Vec> + where + D: 'a + TextDimension + Ord + Sub, + { + let anchor_disjoint = &self.disjoint; + let mut disjoint = resolve_multiple::(anchor_disjoint.iter(), &buffer).peekable(); + + let mut pending_opt = self.pending::(&buffer); + + iter::from_fn(move || { + if let Some(pending) = pending_opt.as_mut() { + while let Some(next_selection) = disjoint.peek() { + if pending.start <= next_selection.end && pending.end >= next_selection.start { + let next_selection = disjoint.next().unwrap(); + if next_selection.start < pending.start { + pending.start = next_selection.start; + } + if next_selection.end > pending.end { + pending.end = next_selection.end; + } + } else if next_selection.end < pending.start { + return disjoint.next(); + } else { + break; + } + } + + pending_opt.take() + } else { + disjoint.next() + } + }) + .collect() + } + + pub fn interleaved_in_range<'a>( + &self, + range: Range, + buffer: &MultiBufferSnapshot, + ) -> Vec> { + let start_ix = match self + .disjoint + .binary_search_by(|probe| probe.end.cmp(&range.start, &buffer)) + { + Ok(ix) | Err(ix) => ix, + }; + let end_ix = match self + .disjoint + .binary_search_by(|probe| probe.start.cmp(&range.end, &buffer)) + { + Ok(ix) => ix + 1, + Err(ix) => ix, + }; + + fn point_selection( + selection: &Selection, + buffer: &MultiBufferSnapshot, + ) -> Selection { + let start = crate::ToPoint::to_point(&selection.start, &buffer); + let end = crate::ToPoint::to_point(&selection.end, &buffer); + Selection { + id: selection.id, + start, + end, + reversed: selection.reversed, + goal: selection.goal, + } + } + + self.disjoint[start_ix..end_ix] + .iter() + .chain(self.pending.as_ref().map(|pending| &pending.selection)) + .map(|s| point_selection(s, &buffer)) + .collect() + } + + pub fn newest_anchor(&self) -> &Selection { + self.pending + .as_ref() + .map(|s| &s.selection) + .or_else(|| self.disjoint.iter().max_by_key(|s| s.id)) + .unwrap() + } + + pub fn newest>( + &self, + snapshot: &MultiBufferSnapshot, + ) -> Selection { + resolve(self.newest_anchor(), snapshot) + } + + pub fn oldest_anchor(&self) -> &Selection { + self.disjoint + .iter() + .min_by_key(|s| s.id) + .or_else(|| self.pending.as_ref().map(|p| &p.selection)) + .unwrap() + } + + pub fn oldest>( + &self, + snapshot: &MultiBufferSnapshot, + ) -> Selection { + resolve(self.oldest_anchor(), snapshot) + } + + pub fn first>( + &self, + snapshot: &MultiBufferSnapshot, + ) -> Selection { + self.interleaved(&snapshot).first().unwrap().clone() + } + + pub fn last>( + &self, + snapshot: &MultiBufferSnapshot, + ) -> Selection { + self.interleaved(&snapshot).last().unwrap().clone() + } + + // NOTE do not use. This should only be called from Editor::change_selections. + #[deprecated] + pub fn change_with( + &mut self, + display_map: ModelHandle, + buffer: ModelHandle, + cx: &mut MutableAppContext, + change: impl FnOnce(&mut MutableSelectionsCollection) -> R, + ) -> (Option, R) { + let mut mutable_collection = MutableSelectionsCollection { + collection: self, + autoscroll: None, + display_map, + buffer, + cx, + }; + + let result = change(&mut mutable_collection); + + assert!( + !mutable_collection.disjoint.is_empty() || mutable_collection.pending.is_some(), + "There must be at least one selection" + ); + (mutable_collection.autoscroll, result) + } +} + +pub struct MutableSelectionsCollection<'a> { + collection: &'a mut SelectionsCollection, + pub autoscroll: Option, + buffer: ModelHandle, + display_map: ModelHandle, + cx: &'a mut MutableAppContext, +} + +impl<'a> MutableSelectionsCollection<'a> { + pub fn clear_disjoint(&mut self) { + self.collection.disjoint = Arc::from([]); + } + + pub fn delete(&mut self, selection_id: usize) { + self.collection.disjoint = self + .disjoint + .into_iter() + .filter(|selection| selection.id != selection_id) + .cloned() + .collect(); + } + + pub fn clear_pending(&mut self) { + self.collection.pending = None; + } + + pub fn set_pending_range(&mut self, range: Range, mode: SelectMode) { + self.collection.pending = Some(PendingSelection { + selection: Selection { + id: post_inc(&mut self.collection.next_selection_id), + start: range.start, + end: range.end, + reversed: false, + goal: SelectionGoal::None, + }, + mode, + }) + } + pub fn pending_mut(&mut self) -> &mut Option { + &mut self.collection.pending + } + + pub fn try_cancel(&mut self) -> bool { + let buffer = self.buffer.read(self.cx).snapshot(self.cx); + if let Some(pending) = self.collection.pending.take() { + if self.disjoint.is_empty() { + self.collection.disjoint = Arc::from([pending.selection]); + } + return true; + } + + let mut oldest = self.oldest_anchor().clone(); + if self.count() > 1 { + self.collection.disjoint = Arc::from([oldest]); + return true; + } + + if !oldest.start.cmp(&oldest.end, &buffer).is_eq() { + let head = oldest.head(); + oldest.start = head.clone(); + oldest.end = head; + self.collection.disjoint = Arc::from([oldest]); + return true; + } + + return false; + } + + pub fn reset_biases(&mut self) { + let buffer = self.buffer.read(self.cx).snapshot(self.cx); + self.collection.disjoint = self + .collection + .disjoint + .into_iter() + .cloned() + .map(|selection| reset_biases(selection, &buffer)) + .collect(); + + if let Some(pending) = self.collection.pending.as_mut() { + pending.selection = reset_biases(pending.selection.clone(), &buffer); + } + } + + pub fn insert_range(&mut self, range: Range, autoscroll: Option) + where + T: 'a + + ToOffset + + ToPoint + + TextDimension + + Ord + + Sub + + std::marker::Copy + + std::fmt::Debug, + { + let buffer = self.buffer.read(self.cx).snapshot(self.cx); + let mut selections = self.interleaved(&buffer); + let mut start = range.start.to_offset(&buffer); + let mut end = range.end.to_offset(&buffer); + let reversed = if start > end { + mem::swap(&mut start, &mut end); + true + } else { + false + }; + selections.push(Selection { + id: post_inc(&mut self.collection.next_selection_id), + start, + end, + reversed, + goal: SelectionGoal::None, + }); + self.select(selections, autoscroll); + } + + pub fn select(&mut self, mut selections: Vec>, autoscroll: Option) + where + T: ToOffset + ToPoint + Ord + std::marker::Copy + std::fmt::Debug, + { + let buffer = self.buffer.read(self.cx).snapshot(self.cx); + selections.sort_unstable_by_key(|s| s.start); + // Merge overlapping selections. + let mut i = 1; + while i < selections.len() { + if selections[i - 1].end >= selections[i].start { + let removed = selections.remove(i); + if removed.start < selections[i - 1].start { + selections[i - 1].start = removed.start; + } + if removed.end > selections[i - 1].end { + selections[i - 1].end = removed.end; + } + } else { + i += 1; + } + } + + self.autoscroll = autoscroll.or(self.autoscroll.take()); + + self.collection.disjoint = Arc::from_iter(selections.into_iter().map(|selection| { + let end_bias = if selection.end > selection.start { + Bias::Left + } else { + Bias::Right + }; + Selection { + id: selection.id, + start: buffer.anchor_after(selection.start), + end: buffer.anchor_at(selection.end, end_bias), + reversed: selection.reversed, + goal: selection.goal, + } + })); + + self.collection.pending = None; + } + + pub fn select_anchors( + &mut self, + mut selections: Vec>, + autoscroll: Option, + ) { + let buffer = self.buffer.read(self.cx).snapshot(self.cx); + selections.sort_unstable_by(|a, b| a.start.cmp(&b.start, &buffer)); + + // Merge overlapping selections. + let mut i = 1; + while i < selections.len() { + if selections[i - 1] + .end + .cmp(&selections[i].start, &buffer) + .is_ge() + { + let removed = selections.remove(i); + if removed.start.cmp(&selections[i - 1].start, &buffer).is_lt() { + selections[i - 1].start = removed.start; + } + if removed.end.cmp(&selections[i - 1].end, &buffer).is_gt() { + selections[i - 1].end = removed.end; + } + } else { + i += 1; + } + } + + self.autoscroll = autoscroll.or(self.autoscroll.take()); + + self.collection.disjoint = Arc::from_iter( + selections + .into_iter() + .map(|selection| reset_biases(selection, &buffer)), + ); + + self.collection.pending = None; + } + + pub fn select_ranges(&mut self, ranges: I, autoscroll: Option) + where + I: IntoIterator>, + T: ToOffset, + { + let buffer = self.buffer.read(self.cx).snapshot(self.cx); + let selections = ranges + .into_iter() + .map(|range| { + let mut start = range.start.to_offset(&buffer); + let mut end = range.end.to_offset(&buffer); + let reversed = if start > end { + mem::swap(&mut start, &mut end); + true + } else { + false + }; + Selection { + id: post_inc(&mut self.collection.next_selection_id), + start, + end, + reversed, + goal: SelectionGoal::None, + } + }) + .collect::>(); + + self.select(selections, autoscroll) + } + + pub fn select_anchor_ranges>>( + &mut self, + ranges: I, + autoscroll: Option, + ) { + let buffer = self.buffer.read(self.cx).snapshot(self.cx); + let selections = ranges + .into_iter() + .map(|range| { + let mut start = range.start; + let mut end = range.end; + let reversed = if start.cmp(&end, &buffer).is_gt() { + mem::swap(&mut start, &mut end); + true + } else { + false + }; + Selection { + id: post_inc(&mut self.collection.next_selection_id), + start, + end, + reversed, + goal: SelectionGoal::None, + } + }) + .collect::>(); + + self.select_anchors(selections, autoscroll) + } + + #[cfg(any(test, feature = "test-support"))] + pub fn select_display_ranges(&mut self, ranges: T) + where + T: IntoIterator>, + { + let display_map = self.display_map.update(self.cx, |map, cx| map.snapshot(cx)); + let selections = ranges + .into_iter() + .map(|range| { + let mut start = range.start; + let mut end = range.end; + let reversed = if start > end { + mem::swap(&mut start, &mut end); + true + } else { + false + }; + Selection { + id: post_inc(&mut self.collection.next_selection_id), + start: start.to_point(&display_map), + end: end.to_point(&display_map), + reversed, + goal: SelectionGoal::None, + } + }) + .collect(); + self.select(selections, None); + } + + pub fn move_with( + &mut self, + mut move_selection: impl FnMut(&DisplaySnapshot, &mut Selection), + ) { + let display_map = self.display_map.update(self.cx, |map, cx| map.snapshot(cx)); + let selections = self + .interleaved::(&display_map.buffer_snapshot) + .into_iter() + .map(|selection| { + let mut selection = selection.map(|point| point.to_display_point(&display_map)); + move_selection(&display_map, &mut selection); + selection.map(|display_point| display_point.to_point(&display_map)) + }) + .collect(); + + self.select(selections, Some(Autoscroll::Fit)) + } + + pub fn move_heads_with( + &mut self, + mut update_head: impl FnMut( + &DisplaySnapshot, + DisplayPoint, + SelectionGoal, + ) -> (DisplayPoint, SelectionGoal), + ) { + self.move_with(|map, selection| { + let (new_head, new_goal) = update_head(map, selection.head(), selection.goal); + selection.set_head(new_head, new_goal); + }); + } + + pub fn move_cursors_with( + &mut self, + mut update_cursor_position: impl FnMut( + &DisplaySnapshot, + DisplayPoint, + SelectionGoal, + ) -> (DisplayPoint, SelectionGoal), + ) { + self.move_with(|map, selection| { + let (cursor, new_goal) = update_cursor_position(map, selection.head(), selection.goal); + selection.collapse_to(cursor, new_goal) + }); + } + + pub fn replace_cursors_with( + &mut self, + mut find_replacement_cursors: impl FnMut(&DisplaySnapshot) -> Vec, + ) { + let display_map = self.display_map.update(self.cx, |map, cx| map.snapshot(cx)); + let new_selections = find_replacement_cursors(&display_map) + .into_iter() + .map(|cursor| { + let cursor_point = cursor.to_point(&display_map); + Selection { + id: post_inc(&mut self.collection.next_selection_id), + start: cursor_point, + end: cursor_point, + reversed: false, + goal: SelectionGoal::None, + } + }) + .collect(); + self.select(new_selections, None); + } + + /// Compute new ranges for any selections that were located in excerpts that have + /// since been removed. + /// + /// Returns a `HashMap` indicating which selections whose former head position + /// was no longer present. The keys of the map are selection ids. The values are + /// the id of the new excerpt where the head of the selection has been moved. + pub fn refresh(&mut self) -> HashMap { + // TODO: Pull disjoint constraint out of update_selections so we don't have to + // store the pending_selection here. + let buffer = self.buffer.read(self.cx).snapshot(self.cx); + let mut pending = self.collection.pending.take(); + let mut selections_with_lost_position = HashMap::default(); + + let anchors_with_status = buffer.refresh_anchors( + self.disjoint + .iter() + .flat_map(|selection| [&selection.start, &selection.end]), + ); + let adjusted_disjoint: Vec<_> = anchors_with_status + .chunks(2) + .map(|selection_anchors| { + let (anchor_ix, start, kept_start) = selection_anchors[0].clone(); + let (_, end, kept_end) = selection_anchors[1].clone(); + let selection = &self.disjoint[anchor_ix / 2]; + let kept_head = if selection.reversed { + kept_start + } else { + kept_end + }; + if !kept_head { + selections_with_lost_position + .insert(selection.id, selection.head().excerpt_id.clone()); + } + + Selection { + id: selection.id, + start, + end, + reversed: selection.reversed, + goal: selection.goal, + } + }) + .collect(); + + if !adjusted_disjoint.is_empty() { + self.select::( + resolve_multiple(adjusted_disjoint.iter(), &buffer).collect(), + None, + ); + } + + if let Some(pending) = pending.as_mut() { + let anchors = + buffer.refresh_anchors([&pending.selection.start, &pending.selection.end]); + let (_, start, kept_start) = anchors[0].clone(); + let (_, end, kept_end) = anchors[1].clone(); + let kept_head = if pending.selection.reversed { + kept_start + } else { + kept_end + }; + if !kept_head { + selections_with_lost_position.insert( + pending.selection.id, + pending.selection.head().excerpt_id.clone(), + ); + } + + pending.selection.start = start; + pending.selection.end = end; + } + self.collection.pending = pending; + + selections_with_lost_position + } +} + +impl<'a> Deref for MutableSelectionsCollection<'a> { + type Target = SelectionsCollection; + fn deref(&self) -> &Self::Target { + self.collection + } +} + +// Panics if passed selections are not in order +pub fn resolve_multiple<'a, D, I>( + selections: I, + snapshot: &MultiBufferSnapshot, +) -> impl 'a + Iterator> +where + D: TextDimension + Ord + Sub, + I: 'a + IntoIterator>, +{ + let (to_summarize, selections) = selections.into_iter().tee(); + let mut summaries = snapshot + .summaries_for_anchors::(to_summarize.flat_map(|s| [&s.start, &s.end])) + .into_iter(); + selections.map(move |s| Selection { + id: s.id, + start: summaries.next().unwrap(), + end: summaries.next().unwrap(), + reversed: s.reversed, + goal: s.goal, + }) +} + +fn resolve>( + selection: &Selection, + buffer: &MultiBufferSnapshot, +) -> Selection { + selection.map(|p| p.summary::(&buffer)) +} + +fn reset_biases( + mut selection: Selection, + buffer: &MultiBufferSnapshot, +) -> Selection { + let end_bias = if selection.end.cmp(&selection.start, buffer).is_gt() { + Bias::Left + } else { + Bias::Right + }; + selection.start = buffer.anchor_after(selection.start); + selection.end = buffer.anchor_at(selection.end, end_bias); + selection +} diff --git a/crates/editor/src/test.rs b/crates/editor/src/test.rs index eb23d7e15f..407733c771 100644 --- a/crates/editor/src/test.rs +++ b/crates/editor/src/test.rs @@ -43,7 +43,7 @@ pub fn marked_display_snapshot( pub fn select_ranges(editor: &mut Editor, marked_text: &str, cx: &mut ViewContext) { let (umarked_text, text_ranges) = marked_text_ranges(marked_text); assert_eq!(editor.text(cx), umarked_text); - editor.select_ranges(text_ranges, None, cx); + editor.change_selections(true, cx, |s| s.select_ranges(text_ranges, None)); } pub fn assert_text_with_selections( diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index 3f8aa933ba..2f7219aa6f 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -43,7 +43,7 @@ impl GoToLine { let buffer = editor.buffer().read(cx).read(cx); ( Some(scroll_position), - editor.newest_selection_with_snapshot(&buffer).head(), + editor.selections.newest(&buffer).head(), buffer.max_point(), ) }); @@ -80,7 +80,9 @@ impl GoToLine { if let Some(rows) = active_editor.highlighted_rows() { let snapshot = active_editor.snapshot(cx).display_snapshot; let position = DisplayPoint::new(rows.start, 0).to_point(&snapshot); - active_editor.select_ranges([position..position], Some(Autoscroll::Center), cx); + active_editor.change_selections(true, cx, |s| { + s.select_ranges([position..position], Some(Autoscroll::Center)) + }); } }); cx.emit(Event::Dismissed); diff --git a/crates/journal/src/journal.rs b/crates/journal/src/journal.rs index 19c044e65f..ff0dfa5145 100644 --- a/crates/journal/src/journal.rs +++ b/crates/journal/src/journal.rs @@ -57,7 +57,9 @@ pub fn new_journal_entry(app_state: Arc, cx: &mut MutableAppContext) { if let Some(editor) = item.downcast::() { editor.update(&mut cx, |editor, cx| { let len = editor.buffer().read(cx).read(cx).len(); - editor.select_ranges([len..len], Some(Autoscroll::Center), cx); + editor.change_selections(true, cx, |s| { + s.select_ranges([len..len], Some(Autoscroll::Center)) + }); if len > 0 { editor.insert("\n\n", cx); } diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 5658cf2011..7383b4b3a9 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -172,9 +172,7 @@ impl PickerDelegate for OutlineView { let editor = self.active_editor.read(cx); let buffer = editor.buffer().read(cx).read(cx); - let cursor_offset = editor - .newest_selection_with_snapshot::(&buffer) - .head(); + let cursor_offset = editor.selections.newest::(&buffer).head(); selected_index = self .outline .items @@ -217,7 +215,9 @@ impl PickerDelegate for OutlineView { if let Some(rows) = active_editor.highlighted_rows() { let snapshot = active_editor.snapshot(cx).display_snapshot; let position = DisplayPoint::new(rows.start, 0).to_point(&snapshot); - active_editor.select_ranges([position..position], Some(Autoscroll::Center), cx); + active_editor.change_selections(true, cx, |s| { + s.select_ranges([position..position], Some(Autoscroll::Center)) + }); } }); cx.emit(Event::Dismissed); diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index 157ea8ef73..80530ff5e6 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -145,11 +145,9 @@ impl ProjectSymbolsView { let editor = workspace.open_project_item::(buffer, cx); editor.update(cx, |editor, cx| { - editor.select_ranges( - [position..position], - Some(Autoscroll::Center), - cx, - ); + editor.change_selections(true, cx, |s| { + s.select_ranges([position..position], Some(Autoscroll::Center)) + }); }); }); Ok::<_, anyhow::Error>(()) diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 549edf89e7..95ef808ab0 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -227,7 +227,8 @@ impl BufferSearchBar { .display_snapshot; let selection = editor .read(cx) - .newest_selection_with_snapshot::(&display_map.buffer_snapshot); + .selections + .newest::(&display_map.buffer_snapshot); let mut text: String; if selection.start == selection.end { @@ -387,14 +388,16 @@ impl BufferSearchBar { if let Some(ranges) = self.editors_with_matches.get(&cx.weak_handle()) { let new_index = match_index_for_direction( ranges, - &editor.newest_anchor_selection().head(), + &editor.selections.newest_anchor().head(), index, direction, &editor.buffer().read(cx).read(cx), ); let range_to_select = ranges[new_index].clone(); editor.unfold_ranges([range_to_select.clone()], false, cx); - editor.select_ranges([range_to_select], Some(Autoscroll::Fit), cx); + editor.change_selections(true, cx, |s| { + s.select_ranges([range_to_select], Some(Autoscroll::Fit)) + }); } }); } @@ -535,11 +538,12 @@ impl BufferSearchBar { editor.update(cx, |editor, cx| { if select_closest_match { if let Some(match_ix) = this.active_match_index { - editor.select_ranges( - [ranges[match_ix].clone()], - Some(Autoscroll::Fit), - cx, - ); + editor.change_selections(true, cx, |s| { + s.select_ranges( + [ranges[match_ix].clone()], + Some(Autoscroll::Fit), + ) + }); } } @@ -564,7 +568,7 @@ impl BufferSearchBar { let editor = editor.read(cx); active_match_index( &ranges, - &editor.newest_anchor_selection().head(), + &editor.selections.newest_anchor().head(), &editor.buffer().read(cx).read(cx), ) }); @@ -721,7 +725,9 @@ mod tests { }); editor.update(cx, |editor, cx| { - editor.select_display_ranges(&[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]) + }); }); search_bar.update(cx, |search_bar, cx| { assert_eq!(search_bar.active_match_index, Some(0)); @@ -804,7 +810,9 @@ mod tests { // Park the cursor in between matches and ensure that going to the previous match selects // the closest match to the left. editor.update(cx, |editor, cx| { - editor.select_display_ranges(&[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]) + }); }); search_bar.update(cx, |search_bar, cx| { assert_eq!(search_bar.active_match_index, Some(1)); @@ -821,7 +829,9 @@ mod tests { // Park the cursor in between matches and ensure that going to the next match selects the // closest match to the right. editor.update(cx, |editor, cx| { - editor.select_display_ranges(&[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]) + }); }); search_bar.update(cx, |search_bar, cx| { assert_eq!(search_bar.active_match_index, Some(1)); @@ -838,7 +848,9 @@ mod tests { // Park the cursor after the last match and ensure that going to the previous match selects // the last match. editor.update(cx, |editor, cx| { - editor.select_display_ranges(&[DisplayPoint::new(3, 60)..DisplayPoint::new(3, 60)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(3, 60)..DisplayPoint::new(3, 60)]) + }); }); search_bar.update(cx, |search_bar, cx| { assert_eq!(search_bar.active_match_index, Some(2)); @@ -855,7 +867,9 @@ mod tests { // Park the cursor after the last match and ensure that going to the next match selects the // first match. editor.update(cx, |editor, cx| { - editor.select_display_ranges(&[DisplayPoint::new(3, 60)..DisplayPoint::new(3, 60)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(3, 60)..DisplayPoint::new(3, 60)]) + }); }); search_bar.update(cx, |search_bar, cx| { assert_eq!(search_bar.active_match_index, Some(2)); @@ -872,7 +886,9 @@ mod tests { // Park the cursor before the first match and ensure that going to the previous match // selects the last match. editor.update(cx, |editor, cx| { - editor.select_display_ranges(&[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]) + }); }); search_bar.update(cx, |search_bar, cx| { assert_eq!(search_bar.active_match_index, Some(0)); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index cbd373c468..1e363ebf15 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -454,7 +454,7 @@ impl ProjectSearchView { let results_editor = self.results_editor.read(cx); let new_index = match_index_for_direction( &model.match_ranges, - &results_editor.newest_anchor_selection().head(), + &results_editor.selections.newest_anchor().head(), index, direction, &results_editor.buffer().read(cx).read(cx), @@ -462,7 +462,9 @@ impl ProjectSearchView { let range_to_select = model.match_ranges[new_index].clone(); self.results_editor.update(cx, |editor, cx| { editor.unfold_ranges([range_to_select.clone()], false, cx); - editor.select_ranges([range_to_select], Some(Autoscroll::Fit), cx); + editor.change_selections(true, cx, |s| { + s.select_ranges([range_to_select], Some(Autoscroll::Fit)) + }); }); } } @@ -476,8 +478,10 @@ impl ProjectSearchView { fn focus_results_editor(&self, cx: &mut ViewContext) { self.query_editor.update(cx, |query_editor, cx| { - let cursor = query_editor.newest_anchor_selection().head(); - query_editor.select_ranges([cursor.clone()..cursor], None, cx); + let cursor = query_editor.selections.newest_anchor().head(); + query_editor.change_selections(true, cx, |s| { + s.select_ranges([cursor.clone()..cursor], None) + }); }); cx.focus(&self.results_editor); } @@ -489,7 +493,9 @@ impl ProjectSearchView { } else { self.results_editor.update(cx, |editor, cx| { if reset_selections { - editor.select_ranges(match_ranges.first().cloned(), Some(Autoscroll::Fit), cx); + editor.change_selections(true, cx, |s| { + s.select_ranges(match_ranges.first().cloned(), Some(Autoscroll::Fit)) + }); } editor.highlight_background::( match_ranges, @@ -510,7 +516,7 @@ impl ProjectSearchView { let results_editor = self.results_editor.read(cx); let new_index = active_match_index( &self.model.read(cx).match_ranges, - &results_editor.newest_anchor_selection().head(), + &results_editor.selections.newest_anchor().head(), &results_editor.buffer().read(cx).read(cx), ); if self.active_match_index != new_index { diff --git a/crates/vim/src/insert.rs b/crates/vim/src/insert.rs index afaeda17b0..69912cff18 100644 --- a/crates/vim/src/insert.rs +++ b/crates/vim/src/insert.rs @@ -13,9 +13,11 @@ pub fn init(cx: &mut MutableAppContext) { fn normal_before(_: &mut Workspace, _: &NormalBefore, cx: &mut ViewContext) { Vim::update(cx, |state, cx| { state.update_active_editor(cx, |editor, cx| { - editor.move_cursors(cx, |map, mut cursor, _| { - *cursor.column_mut() = cursor.column().saturating_sub(1); - (map.clip_point(cursor, Bias::Left), SelectionGoal::None) + editor.change_selections(true, cx, |s| { + s.move_cursors_with(|map, mut cursor, _| { + *cursor.column_mut() = cursor.column().saturating_sub(1); + (map.clip_point(cursor, Bias::Left), SelectionGoal::None) + }); }); }); state.switch_mode(Mode::Normal, cx); diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 63d5ab4ccb..7c4ac6a20c 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -76,7 +76,9 @@ pub fn normal_motion(motion: Motion, cx: &mut MutableAppContext) { fn move_cursor(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) { vim.update_active_editor(cx, |editor, cx| { - editor.move_cursors(cx, |map, cursor, goal| motion.move_point(map, cursor, goal)) + editor.change_selections(true, cx, |s| { + s.move_cursors_with(|map, cursor, goal| motion.move_point(map, cursor, goal)) + }) }); } @@ -84,8 +86,10 @@ fn insert_after(_: &mut Workspace, _: &InsertAfter, cx: &mut ViewContext = Default::default(); - editor.move_selections(cx, |map, selection| { - let original_head = selection.head(); - motion.expand_selection(map, selection, true); - original_columns.insert(selection.id, original_head.column()); + editor.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + let original_head = selection.head(); + motion.expand_selection(map, selection, true); + original_columns.insert(selection.id, original_head.column()); + }); }); editor.insert(&"", cx); // Fixup cursor position after the deletion editor.set_clip_at_line_ends(true, cx); - editor.move_selections(cx, |map, selection| { - let mut cursor = selection.head(); - if motion.linewise() { - if let Some(column) = original_columns.get(&selection.id) { - *cursor.column_mut() = *column + editor.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + let mut cursor = selection.head(); + if motion.linewise() { + if let Some(column) = original_columns.get(&selection.id) { + *cursor.column_mut() = *column + } } - } - cursor = map.clip_point(cursor, Bias::Left); - selection.collapse_to(cursor, selection.goal) + cursor = map.clip_point(cursor, Bias::Left); + selection.collapse_to(cursor, selection.goal) + }); }); }); }); diff --git a/crates/vim/src/vim_test_context.rs b/crates/vim/src/vim_test_context.rs index 09470c31c8..cfcfa8d2b4 100644 --- a/crates/vim/src/vim_test_context.rs +++ b/crates/vim/src/vim_test_context.rs @@ -128,7 +128,9 @@ impl<'a> VimTestContext<'a> { let (unmarked_text, markers) = marked_text(&text); editor.set_text(unmarked_text, cx); let cursor_offset = markers[0]; - editor.replace_selections_with(cx, |map| cursor_offset.to_display_point(map)); + editor.change_selections(true, cx, |s| { + s.replace_cursors_with(|map| vec![cursor_offset.to_display_point(map)]) + }); }) } @@ -197,7 +199,8 @@ impl<'a> VimTestContext<'a> { let (empty_selections, reverse_selections, forward_selections) = self.editor.read_with(self.cx, |editor, cx| { let (empty_selections, non_empty_selections): (Vec<_>, Vec<_>) = editor - .local_selections::(cx) + .selections + .interleaved::(&editor.buffer().read(cx).read(cx)) .into_iter() .partition_map(|selection| { if selection.is_empty() { diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index 9c41263317..c1b2771f7a 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -14,23 +14,25 @@ pub fn init(cx: &mut MutableAppContext) { pub fn visual_motion(motion: Motion, cx: &mut MutableAppContext) { Vim::update(cx, |vim, cx| { vim.update_active_editor(cx, |editor, cx| { - editor.move_selections(cx, |map, selection| { - let (new_head, goal) = motion.move_point(map, selection.head(), selection.goal); - let new_head = map.clip_at_line_end(new_head); - let was_reversed = selection.reversed; - selection.set_head(new_head, goal); + editor.change_selections(true, cx, |s| { + s.move_with(|map, selection| { + let (new_head, goal) = motion.move_point(map, selection.head(), selection.goal); + let new_head = map.clip_at_line_end(new_head); + let was_reversed = selection.reversed; + selection.set_head(new_head, goal); - if was_reversed && !selection.reversed { - // Head was at the start of the selection, and now is at the end. We need to move the start - // back by one if possible in order to compensate for this change. - *selection.start.column_mut() = selection.start.column().saturating_sub(1); - selection.start = map.clip_point(selection.start, Bias::Left); - } else if !was_reversed && selection.reversed { - // Head was at the end of the selection, and now is at the start. We need to move the end - // forward by one if possible in order to compensate for this change. - *selection.end.column_mut() = selection.end.column() + 1; - selection.end = map.clip_point(selection.end, Bias::Left); - } + if was_reversed && !selection.reversed { + // Head was at the start of the selection, and now is at the end. We need to move the start + // back by one if possible in order to compensate for this change. + *selection.start.column_mut() = selection.start.column().saturating_sub(1); + selection.start = map.clip_point(selection.start, Bias::Left); + } else if !was_reversed && selection.reversed { + // Head was at the end of the selection, and now is at the start. We need to move the end + // forward by one if possible in order to compensate for this change. + *selection.end.column_mut() = selection.end.column() + 1; + selection.end = map.clip_point(selection.end, Bias::Left); + } + }); }); }); }); @@ -40,13 +42,15 @@ pub fn change(_: &mut Workspace, _: &VisualChange, cx: &mut ViewContext() .unwrap(); editor1.update(cx, |editor, cx| { - editor.select_display_ranges(&[DisplayPoint::new(10, 0)..DisplayPoint::new(10, 0)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(10, 0)..DisplayPoint::new(10, 0)]) + }); }); let editor2 = workspace .update(cx, |w, cx| w.open_path(file2.clone(), true, cx)) @@ -979,10 +981,9 @@ mod tests { editor3 .update(cx, |editor, cx| { - editor.select_display_ranges( - &[DisplayPoint::new(12, 0)..DisplayPoint::new(12, 0)], - cx, - ); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(12, 0)..DisplayPoint::new(12, 0)]) + }); editor.newline(&Default::default(), cx); editor.newline(&Default::default(), cx); editor.move_down(&Default::default(), cx); @@ -1123,34 +1124,37 @@ mod tests { // Modify file to collapse multiple nav history entries into the same location. // Ensure we don't visit the same location twice when navigating. editor1.update(cx, |editor, cx| { - editor.select_display_ranges(&[DisplayPoint::new(15, 0)..DisplayPoint::new(15, 0)], cx) + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(15, 0)..DisplayPoint::new(15, 0)]) + }) }); for _ in 0..5 { editor1.update(cx, |editor, cx| { - editor - .select_display_ranges(&[DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)], cx); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)]) + }); }); editor1.update(cx, |editor, cx| { - editor.select_display_ranges( - &[DisplayPoint::new(13, 0)..DisplayPoint::new(13, 0)], - cx, - ) + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(13, 0)..DisplayPoint::new(13, 0)]) + }) }); } editor1.update(cx, |editor, cx| { editor.transact(cx, |editor, cx| { - editor.select_display_ranges( - &[DisplayPoint::new(2, 0)..DisplayPoint::new(14, 0)], - cx, - ); + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(14, 0)]) + }); editor.insert("", cx); }) }); editor1.update(cx, |editor, cx| { - editor.select_display_ranges(&[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)], cx) + editor.change_selections(true, cx, |s| { + s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]) + }) }); workspace .update(cx, |w, cx| Pane::go_back(w, None, cx)) From db0a9114c2b5b24ba8d8606b031086ef63f84bb0 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Thu, 12 May 2022 14:18:46 -0700 Subject: [PATCH 11/18] Passing tests and removed local argument. Also pulled autoscroll argument out to change_selections --- crates/collab/src/rpc.rs | 16 +- crates/diagnostics/src/diagnostics.rs | 8 +- crates/editor/src/editor.rs | 502 +++++++++--------- crates/editor/src/items.rs | 4 +- crates/editor/src/selections_collection.rs | 101 +--- crates/editor/src/test.rs | 2 +- crates/go_to_line/src/go_to_line.rs | 4 +- crates/journal/src/journal.rs | 4 +- crates/outline/src/outline.rs | 4 +- crates/project_symbols/src/project_symbols.rs | 4 +- crates/search/src/buffer_search.rs | 27 +- crates/search/src/project_search.rs | 12 +- crates/vim/src/insert.rs | 4 +- crates/vim/src/normal.rs | 14 +- crates/vim/src/normal/change.rs | 6 +- crates/vim/src/normal/delete.rs | 6 +- crates/vim/src/vim_test_context.rs | 4 +- crates/vim/src/visual.rs | 10 +- crates/zed/src/zed.rs | 16 +- 19 files changed, 351 insertions(+), 397 deletions(-) diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 1536ceae92..3ff9e13edb 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -3001,7 +3001,7 @@ mod tests { // Type a completion trigger character as the guest. editor_b.update(cx_b, |editor, cx| { - editor.change_selections(true, cx, |s| s.select_ranges([13..13], None)); + editor.change_selections(None, cx, |s| s.select_ranges([13..13])); editor.handle_input(&Input(".".into()), cx); cx.focus(&editor_b); }); @@ -4213,8 +4213,8 @@ mod tests { // Move cursor to a location that contains code actions. editor_b.update(cx_b, |editor, cx| { - editor.change_selections(true, cx, |s| { - s.select_ranges([Point::new(1, 31)..Point::new(1, 31)], None) + editor.change_selections(None, cx, |s| { + s.select_ranges([Point::new(1, 31)..Point::new(1, 31)]) }); cx.focus(&editor_b); }); @@ -4452,7 +4452,7 @@ mod tests { // Move cursor to a location that can be renamed. let prepare_rename = editor_b.update(cx_b, |editor, cx| { - editor.change_selections(true, cx, |s| s.select_ranges([7..7], None)); + editor.change_selections(None, cx, |s| s.select_ranges([7..7])); editor.rename(&Rename, cx).unwrap() }); @@ -5473,10 +5473,10 @@ mod tests { // When client B starts following client A, all visible view states are replicated to client B. editor_a1.update(cx_a, |editor, cx| { - editor.change_selections(true, cx, |s| s.select_ranges([0..1], None)) + editor.change_selections(None, cx, |s| s.select_ranges([0..1])) }); editor_a2.update(cx_a, |editor, cx| { - editor.change_selections(true, cx, |s| s.select_ranges([2..3], None)) + editor.change_selections(None, cx, |s| s.select_ranges([2..3])) }); workspace_b .update(cx_b, |workspace, cx| { @@ -5542,7 +5542,7 @@ mod tests { // Changes to client A's editor are reflected on client B. editor_a1.update(cx_a, |editor, cx| { - editor.change_selections(true, cx, |s| s.select_ranges([1..1, 2..2], None)); + editor.change_selections(None, cx, |s| s.select_ranges([1..1, 2..2])); }); editor_b1 .condition(cx_b, |editor, cx| { @@ -5556,7 +5556,7 @@ mod tests { .await; editor_a1.update(cx_a, |editor, cx| { - editor.change_selections(true, cx, |s| s.select_ranges([3..3], None)); + editor.change_selections(None, cx, |s| s.select_ranges([3..3])); editor.set_scroll_position(vec2f(0., 100.), cx); }); editor_b1 diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 31807f07d8..7fb7bffb1e 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -5,7 +5,7 @@ use collections::{BTreeSet, HashSet}; use editor::{ diagnostic_block_renderer, display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock}, - highlight_diagnostic_message, Editor, ExcerptId, MultiBuffer, ToOffset, + highlight_diagnostic_message, Autoscroll, Editor, ExcerptId, MultiBuffer, ToOffset, }; use gpui::{ actions, elements::*, fonts::TextStyle, serde_json, AnyViewHandle, AppContext, Entity, @@ -418,7 +418,7 @@ impl ProjectDiagnosticsEditor { } else { groups = self.path_states.get(path_ix)?.diagnostic_groups.as_slice(); new_excerpt_ids_by_selection_id = - editor.change_selections(true, cx, |s| s.refresh()); + editor.change_selections(Some(Autoscroll::Fit), cx, |s| s.refresh()); selections = editor .selections .interleaved::(&editor.buffer().read(cx).read(cx)); @@ -444,8 +444,8 @@ impl ProjectDiagnosticsEditor { } } } - editor.change_selections(true, cx, |s| { - s.select(selections, None); + editor.change_selections(None, cx, |s| { + s.select(selections); }); Some(()) }); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index b01bee0ab4..6d907b2b76 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -537,6 +537,7 @@ struct BracketPairState { pair: BracketPair, } +#[derive(Debug)] struct SnippetState { ranges: Vec>>, active_index: usize, @@ -1304,25 +1305,12 @@ impl Editor { } } - pub fn change_selections( + fn selections_did_change( &mut self, local: bool, + old_cursor_position: &Anchor, cx: &mut ViewContext, - change: impl FnOnce(&mut MutableSelectionsCollection<'_>) -> R, - ) -> R { - let old_cursor_position = self.selections.newest_anchor().head(); - self.push_to_selection_history(); - - #[allow(deprecated)] - // Using deprecated to prevent using change_with outside of this function - let (autoscroll, result) = - self.selections - .change_with(self.display_map.clone(), self.buffer.clone(), cx, change); - - if let Some(autoscroll) = autoscroll { - self.request_autoscroll(autoscroll, cx); - } - + ) { if self.focused && self.leader_replica_id.is_none() { self.buffer.update(cx, |buffer, cx| { buffer.set_active_selections(&self.selections.disjoint_anchors(), cx) @@ -1337,20 +1325,21 @@ impl Editor { self.select_next_state = None; self.select_larger_syntax_node_stack.clear(); self.autoclose_stack - .invalidate(&self.selections.disjoint_anchors(), &buffer); + .invalidate(&self.selections.disjoint_anchors(), buffer); self.snippet_stack - .invalidate(&self.selections.disjoint_anchors(), &buffer); + .invalidate(&self.selections.disjoint_anchors(), buffer); self.take_rename(false, cx); let new_cursor_position = self.selections.newest_anchor().head(); self.push_to_nav_history( old_cursor_position.clone(), - Some(new_cursor_position.to_point(&buffer)), + Some(new_cursor_position.to_point(buffer)), cx, ); if local { + let new_cursor_position = self.selections.newest_anchor().head(); let completion_menu = match self.context_menu.as_mut() { Some(ContextMenu::Completions(menu)) => Some(menu), _ => { @@ -1360,13 +1349,13 @@ impl Editor { }; if let Some(completion_menu) = completion_menu { - let cursor_position = new_cursor_position.to_offset(&buffer); + let cursor_position = new_cursor_position.to_offset(buffer); let (word_range, kind) = buffer.surrounding_word(completion_menu.initial_position.clone()); if kind == Some(CharKind::Word) && word_range.to_inclusive().contains(&cursor_position) { - let query = Self::completion_query(&buffer, cursor_position); + let query = Self::completion_query(buffer, cursor_position); cx.background() .block(completion_menu.filter(query.as_deref(), cx.background().clone())); self.show_completions(&ShowCompletions, cx); @@ -1387,6 +1376,25 @@ impl Editor { self.pause_cursor_blinking(cx); cx.emit(Event::SelectionsChanged { local }); cx.notify(); + } + + pub fn change_selections( + &mut self, + autoscroll: Option, + cx: &mut ViewContext, + change: impl FnOnce(&mut MutableSelectionsCollection<'_>) -> R, + ) -> R { + let old_cursor_position = self.selections.newest_anchor().head(); + self.push_to_selection_history(); + + let result = + self.selections + .change_with(self.display_map.clone(), self.buffer.clone(), cx, change); + + if let Some(autoscroll) = autoscroll { + self.request_autoscroll(autoscroll, cx); + } + self.selections_did_change(true, &old_cursor_position, cx); result } @@ -1466,7 +1474,7 @@ impl Editor { let position = position.to_offset(&display_map, Bias::Left); let tail_anchor = display_map.buffer_snapshot.anchor_before(tail); - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { let mut pending = s .pending_mut() .as_mut() @@ -1540,7 +1548,7 @@ impl Editor { } } - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { if add { if click_count > 1 { s.delete(newest_selection.id); @@ -1664,7 +1672,7 @@ impl Editor { pending.reversed = false; } - self.change_selections(true, cx, |s| { + self.change_selections(None, cx, |s| { s.pending_mut().as_mut().unwrap().selection = pending; }); } else { @@ -1682,8 +1690,8 @@ impl Editor { let selections = self .selections .interleaved::(&self.buffer.read(cx).snapshot(cx)); - self.change_selections(true, cx, |s| { - s.select(selections, None); + self.change_selections(None, cx, |s| { + s.select(selections); s.clear_pending(); }); } @@ -1723,8 +1731,8 @@ impl Editor { }) .collect::>(); - self.change_selections(true, cx, |s| { - s.select_ranges(selection_ranges, None); + self.change_selections(None, cx, |s| { + s.select_ranges(selection_ranges); }); cx.notify(); } @@ -1752,7 +1760,7 @@ impl Editor { return; } - if self.change_selections(true, cx, |s| s.try_cancel()) { + if self.change_selections(None, cx, |s| s.try_cancel()) { self.request_autoscroll(Autoscroll::Fit, cx); return; } @@ -1762,7 +1770,7 @@ impl Editor { } #[cfg(any(test, feature = "test-support"))] - pub fn selected_ranges>( + pub fn selected_ranges + std::fmt::Debug>( &self, cx: &AppContext, ) -> Vec> { @@ -1893,9 +1901,7 @@ impl Editor { }) .collect(); - this.change_selections(true, cx, |s| { - s.select(new_selections, Some(Autoscroll::Fit)) - }); + this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(new_selections)); this.request_autoscroll(Autoscroll::Fit, cx); }); @@ -1941,8 +1947,8 @@ impl Editor { .collect() }; - this.change_selections(true, cx, |s| { - s.select(selections, Some(Autoscroll::Fit)); + this.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(selections); }) }); } @@ -2004,7 +2010,7 @@ impl Editor { } drop(snapshot); - self.change_selections(true, cx, |s| s.select_anchors(selections, None)); + self.change_selections(None, cx, |s| s.select_anchors(selections)); true } else { false @@ -2102,8 +2108,8 @@ impl Editor { }); if let Some(new_selections) = new_selections { - self.change_selections(true, cx, |s| { - s.select(new_selections, None); + self.change_selections(None, cx, |s| { + s.select(new_selections); }); } if let Some(bracket_pair_state) = bracket_pair_state { @@ -2147,8 +2153,8 @@ impl Editor { }) .collect(); self.autoclose_stack.pop(); - self.change_selections(true, cx, |s| { - s.select(new_selections, Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(new_selections); }); true } else { @@ -2739,8 +2745,8 @@ impl Editor { }); if let Some(tabstop) = tabstops.first() { - self.change_selections(true, cx, |s| { - s.select_ranges(tabstop.iter().cloned(), Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select_ranges(tabstop.iter().cloned()); }); self.snippet_stack.push(SnippetState { active_index: 0, @@ -2780,15 +2786,18 @@ impl Editor { } } if let Some(current_ranges) = snippet.ranges.get(snippet.active_index) { - self.change_selections(true, cx, |s| { - s.select_anchor_ranges( - current_ranges.into_iter().cloned(), - Some(Autoscroll::Fit), - ) - }); + let snapshot = self.buffer.read(cx).snapshot(cx); + let current_ranges_resolved = current_ranges + .iter() + .map(|range| range.start.to_point(&snapshot)..range.end.to_point(&snapshot)) + .collect::>(); + dbg!(¤t_ranges, current_ranges_resolved); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select_anchor_ranges(current_ranges.into_iter().cloned()) + }); // If snippet state is not at the last tabstop, push it back on the stack - if snippet.active_index + 1 != snippet.ranges.len() { + if snippet.active_index + 1 < snippet.ranges.len() { self.snippet_stack.push(snippet); } return true; @@ -2836,14 +2845,14 @@ impl Editor { } self.transact(cx, |this, cx| { - this.change_selections(true, cx, |s| s.select(selections, Some(Autoscroll::Fit))); + this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections)); this.insert("", cx); }); } pub fn delete(&mut self, _: &Delete, cx: &mut ViewContext) { self.transact(cx, |this, cx| { - this.change_selections(true, cx, |s| { + this.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { if selection.is_empty() { let cursor = movement::right(map, selection.head()); @@ -2895,8 +2904,8 @@ impl Editor { selection.end = selection.start; } }); - this.change_selections(true, cx, |s| { - s.select(selections, Some(Autoscroll::Fit)); + this.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(selections); }); }); } else { @@ -2962,8 +2971,8 @@ impl Editor { } }); - this.change_selections(true, cx, |s| { - s.select(selections, Some(Autoscroll::Fit)); + this.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(selections); }); }); } @@ -3016,8 +3025,8 @@ impl Editor { ); }); let snapshot = this.buffer.read(cx).snapshot(cx); - this.change_selections(true, cx, |s| { - s.select(s.interleaved::(&snapshot), Some(Autoscroll::Fit)) + this.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(s.interleaved::(&snapshot)) }); }); } @@ -3099,8 +3108,8 @@ impl Editor { }) .collect(); - this.change_selections(true, cx, |s| { - s.select(new_selections, Some(Autoscroll::Fit)); + this.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(new_selections); }); }); } @@ -3251,8 +3260,8 @@ impl Editor { } }); this.fold_ranges(refold_ranges, cx); - this.change_selections(true, cx, |s| { - s.select(new_selections, Some(Autoscroll::Fit)); + this.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(new_selections); }) }); } @@ -3356,15 +3365,13 @@ impl Editor { } }); this.fold_ranges(refold_ranges, cx); - this.change_selections(true, cx, |s| { - s.select(new_selections, Some(Autoscroll::Fit)) - }); + this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(new_selections)); }); } pub fn transpose(&mut self, _: &Transpose, cx: &mut ViewContext) { self.transact(cx, |this, cx| { - let edits = this.change_selections(true, cx, |s| { + let edits = this.change_selections(Some(Autoscroll::Fit), cx, |s| { let mut edits: Vec<(Range, String)> = Default::default(); s.move_with(|display_map, selection| { if !selection.is_empty() { @@ -3406,8 +3413,8 @@ impl Editor { }); this.buffer.update(cx, |buffer, cx| buffer.edit(edits, cx)); let buffer = this.buffer.read(cx).snapshot(cx); - this.change_selections(true, cx, |s| { - s.select(s.interleaved::(&buffer), Some(Autoscroll::Fit)); + this.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(s.interleaved::(&buffer)); }); }); } @@ -3439,8 +3446,8 @@ impl Editor { } self.transact(cx, |this, cx| { - this.change_selections(true, cx, |s| { - s.select(selections, Some(Autoscroll::Fit)); + this.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(selections); }); this.insert("", cx); cx.write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections)); @@ -3540,9 +3547,7 @@ impl Editor { let selections = this .selections .interleaved::(&this.buffer.read(cx).read(cx)); - this.change_selections(true, cx, |s| { - s.select(selections, Some(Autoscroll::Fit)) - }); + this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections)); } else { this.insert(&clipboard_text, cx); } @@ -3553,10 +3558,10 @@ impl Editor { pub fn undo(&mut self, _: &Undo, cx: &mut ViewContext) { if let Some(tx_id) = self.buffer.update(cx, |buffer, cx| buffer.undo(cx)) { if let Some((selections, _)) = self.selection_history.transaction(tx_id).cloned() { - self.change_selections(true, cx, |s| { + self.change_selections(None, cx, |s| { // TODO: move to SelectionsCollection to preserve selection // invariants without rechecking - s.select_anchors(selections.to_vec(), None); + s.select_anchors(selections.to_vec()); }); } self.request_autoscroll(Autoscroll::Fit, cx); @@ -3568,10 +3573,10 @@ impl Editor { if let Some(tx_id) = self.buffer.update(cx, |buffer, cx| buffer.redo(cx)) { if let Some((_, Some(selections))) = self.selection_history.transaction(tx_id).cloned() { - self.change_selections(true, cx, |s| { + self.change_selections(None, cx, |s| { // TODO: move to SelectionsCollection to preserve selection // invariants without rechecking - s.select_anchors(selections.to_vec(), None); + s.select_anchors(selections.to_vec()); }); } self.request_autoscroll(Autoscroll::Fit, cx); @@ -3585,7 +3590,7 @@ impl Editor { } pub fn move_left(&mut self, _: &MoveLeft, cx: &mut ViewContext) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { let cursor = if selection.is_empty() { movement::left(map, selection.start) @@ -3598,13 +3603,13 @@ impl Editor { } pub fn select_left(&mut self, _: &SelectLeft, cx: &mut ViewContext) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_heads_with(|map, head, _| (movement::left(map, head), SelectionGoal::None)); }) } pub fn move_right(&mut self, _: &MoveRight, cx: &mut ViewContext) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { let cursor = if selection.is_empty() { movement::right(map, selection.end) @@ -3617,7 +3622,7 @@ impl Editor { } pub fn select_right(&mut self, _: &SelectRight, cx: &mut ViewContext) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_heads_with(|map, head, _| (movement::right(map, head), SelectionGoal::None)); }) } @@ -3638,7 +3643,7 @@ impl Editor { return; } - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { if !selection.is_empty() { selection.goal = SelectionGoal::None; @@ -3650,7 +3655,7 @@ impl Editor { } pub fn select_up(&mut self, _: &SelectUp, cx: &mut ViewContext) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_heads_with(|map, head, goal| movement::up(map, head, goal, false)) }) } @@ -3669,7 +3674,7 @@ impl Editor { return; } - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { if !selection.is_empty() { selection.goal = SelectionGoal::None; @@ -3681,7 +3686,7 @@ impl Editor { } pub fn select_down(&mut self, _: &SelectDown, cx: &mut ViewContext) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_heads_with(|map, head, goal| movement::down(map, head, goal, false)) }); } @@ -3691,7 +3696,7 @@ impl Editor { _: &MoveToPreviousWordStart, cx: &mut ViewContext, ) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_cursors_with(|map, head, _| { ( movement::previous_word_start(map, head), @@ -3706,7 +3711,7 @@ impl Editor { _: &MoveToPreviousSubwordStart, cx: &mut ViewContext, ) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_cursors_with(|map, head, _| { ( movement::previous_subword_start(map, head), @@ -3721,7 +3726,7 @@ impl Editor { _: &SelectToPreviousWordStart, cx: &mut ViewContext, ) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_heads_with(|map, head, _| { ( movement::previous_word_start(map, head), @@ -3736,7 +3741,7 @@ impl Editor { _: &SelectToPreviousSubwordStart, cx: &mut ViewContext, ) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_heads_with(|map, head, _| { ( movement::previous_subword_start(map, head), @@ -3752,7 +3757,7 @@ impl Editor { cx: &mut ViewContext, ) { self.transact(cx, |this, cx| { - this.change_selections(true, cx, |s| { + this.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { if selection.is_empty() { let cursor = movement::previous_word_start(map, selection.head()); @@ -3770,7 +3775,7 @@ impl Editor { cx: &mut ViewContext, ) { self.transact(cx, |this, cx| { - this.change_selections(true, cx, |s| { + this.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { if selection.is_empty() { let cursor = movement::previous_subword_start(map, selection.head()); @@ -3783,7 +3788,7 @@ impl Editor { } pub fn move_to_next_word_end(&mut self, _: &MoveToNextWordEnd, cx: &mut ViewContext) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_cursors_with(|map, head, _| { (movement::next_word_end(map, head), SelectionGoal::None) }); @@ -3795,7 +3800,7 @@ impl Editor { _: &MoveToNextSubwordEnd, cx: &mut ViewContext, ) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_cursors_with(|map, head, _| { (movement::next_subword_end(map, head), SelectionGoal::None) }); @@ -3803,7 +3808,7 @@ impl Editor { } pub fn select_to_next_word_end(&mut self, _: &SelectToNextWordEnd, cx: &mut ViewContext) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_heads_with(|map, head, _| { (movement::next_word_end(map, head), SelectionGoal::None) }); @@ -3815,7 +3820,7 @@ impl Editor { _: &SelectToNextSubwordEnd, cx: &mut ViewContext, ) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_heads_with(|map, head, _| { (movement::next_subword_end(map, head), SelectionGoal::None) }); @@ -3824,7 +3829,7 @@ impl Editor { pub fn delete_to_next_word_end(&mut self, _: &DeleteToNextWordEnd, cx: &mut ViewContext) { self.transact(cx, |this, cx| { - this.change_selections(true, cx, |s| { + this.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { if selection.is_empty() { let cursor = movement::next_word_end(map, selection.head()); @@ -3842,7 +3847,7 @@ impl Editor { cx: &mut ViewContext, ) { self.transact(cx, |this, cx| { - this.change_selections(true, cx, |s| { + this.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { if selection.is_empty() { let cursor = movement::next_subword_end(map, selection.head()); @@ -3859,7 +3864,7 @@ impl Editor { _: &MoveToBeginningOfLine, cx: &mut ViewContext, ) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_cursors_with(|map, head, _| { ( movement::line_beginning(map, head, true), @@ -3874,7 +3879,7 @@ impl Editor { action: &SelectToBeginningOfLine, cx: &mut ViewContext, ) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_heads_with(|map, head, _| { ( movement::line_beginning(map, head, action.stop_at_soft_wraps), @@ -3890,7 +3895,7 @@ impl Editor { cx: &mut ViewContext, ) { self.transact(cx, |this, cx| { - this.change_selections(true, cx, |s| { + this.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|_, selection| { selection.reversed = true; }); @@ -3907,7 +3912,7 @@ impl Editor { } pub fn move_to_end_of_line(&mut self, _: &MoveToEndOfLine, cx: &mut ViewContext) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_cursors_with(|map, head, _| { (movement::line_end(map, head, true), SelectionGoal::None) }); @@ -3919,7 +3924,7 @@ impl Editor { action: &SelectToEndOfLine, cx: &mut ViewContext, ) { - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_heads_with(|map, head, _| { ( movement::line_end(map, head, action.stop_at_soft_wraps), @@ -3959,8 +3964,8 @@ impl Editor { return; } - self.change_selections(true, cx, |s| { - s.select_ranges(vec![0..0], Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select_ranges(vec![0..0]); }); } @@ -3970,8 +3975,8 @@ impl Editor { .last::(&self.buffer.read(cx).read(cx)); selection.set_head(Point::zero(), SelectionGoal::None); - self.change_selections(true, cx, |s| { - s.select(vec![selection], Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(vec![selection]); }); } @@ -3982,8 +3987,8 @@ impl Editor { } let cursor = self.buffer.read(cx).read(cx).len(); - self.change_selections(true, cx, |s| { - s.select_ranges(vec![cursor..cursor], Some(Autoscroll::Fit)) + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select_ranges(vec![cursor..cursor]) }); } @@ -4028,15 +4033,15 @@ impl Editor { let buffer = self.buffer.read(cx).snapshot(cx); let mut selection = self.selections.first::(&buffer); selection.set_head(buffer.len(), SelectionGoal::None); - self.change_selections(true, cx, |s| { - s.select(vec![selection], Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(vec![selection]); }); } pub fn select_all(&mut self, _: &SelectAll, cx: &mut ViewContext) { let end = self.buffer.read(cx).read(cx).len(); - self.change_selections(true, cx, |s| { - s.select_ranges(vec![0..end], Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select_ranges(vec![0..end]); }); } @@ -4052,8 +4057,8 @@ impl Editor { selection.end = cmp::min(max_point, Point::new(rows.end, 0)); selection.reversed = false; } - self.change_selections(true, cx, |s| { - s.select(selections, Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(selections); }); } @@ -4077,8 +4082,8 @@ impl Editor { } } self.unfold_ranges(to_unfold, true, cx); - self.change_selections(true, cx, |s| { - s.select_ranges(new_selection_ranges, Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select_ranges(new_selection_ranges); }); } @@ -4180,8 +4185,8 @@ impl Editor { state.stack.pop(); } - self.change_selections(true, cx, |s| { - s.select(new_selections, Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(new_selections); }); if state.stack.len() > 1 { self.add_selections_state = Some(state); @@ -4229,11 +4234,11 @@ impl Editor { if let Some(next_selected_range) = next_selected_range { self.unfold_ranges([next_selected_range.clone()], false, cx); - self.change_selections(true, cx, |s| { + self.change_selections(Some(Autoscroll::Newest), cx, |s| { if action.replace_newest { s.delete(s.newest_anchor().id); } - s.insert_range(next_selected_range, Some(Autoscroll::Newest)); + s.insert_range(next_selected_range); }); } else { select_next_state.done = true; @@ -4262,8 +4267,8 @@ impl Editor { done: false, }; self.unfold_ranges([selection.start..selection.end], false, cx); - self.change_selections(true, cx, |s| { - s.select(selections, Some(Autoscroll::Newest)); + self.change_selections(Some(Autoscroll::Newest), cx, |s| { + s.select(selections); }); self.select_next_state = Some(select_state); } else { @@ -4388,8 +4393,8 @@ impl Editor { let selections = this .selections .interleaved::(&this.buffer.read(cx).read(cx)); - this.change_selections(true, cx, |s| { - s.select(selections, Some(Autoscroll::Fit)); + this.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(selections); }); }); } @@ -4437,8 +4442,8 @@ impl Editor { if selected_larger_node { stack.push(old_selections); - self.change_selections(true, cx, |s| { - s.select(new_selections, Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(new_selections); }); } self.select_larger_syntax_node_stack = stack; @@ -4451,8 +4456,8 @@ impl Editor { ) { let mut stack = mem::take(&mut self.select_larger_syntax_node_stack); if let Some(selections) = stack.pop() { - self.change_selections(true, cx, |s| { - s.select(selections.to_vec(), Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(selections.to_vec()); }); } self.select_larger_syntax_node_stack = stack; @@ -4482,8 +4487,8 @@ impl Editor { } } - self.change_selections(true, cx, |s| { - s.select(selections, Some(Autoscroll::Fit)); + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select(selections); }); } @@ -4491,10 +4496,10 @@ impl Editor { self.end_selection(cx); self.selection_history.mode = SelectionHistoryMode::Undoing; if let Some(entry) = self.selection_history.undo_stack.pop_back() { - self.change_selections(true, cx, |s| { + self.change_selections(None, cx, |s| { // TODO: Move to selections so selections invariants can be preserved rather than // rechecking them. - s.select_anchors(entry.selections.to_vec(), None) + s.select_anchors(entry.selections.to_vec()) }); self.select_next_state = entry.select_next_state; self.add_selections_state = entry.add_selections_state; @@ -4507,10 +4512,10 @@ impl Editor { self.end_selection(cx); self.selection_history.mode = SelectionHistoryMode::Redoing; if let Some(entry) = self.selection_history.redo_stack.pop_back() { - self.change_selections(true, cx, |s| { + self.change_selections(None, cx, |s| { // TODO: Move to selections so selections invariants can be preserved rather than // rechecking them. - s.select_anchors(entry.selections.to_vec(), None) + s.select_anchors(entry.selections.to_vec()) }); self.select_next_state = entry.select_next_state; self.add_selections_state = entry.add_selections_state; @@ -4566,17 +4571,14 @@ impl Editor { if let Some((primary_range, group_id)) = group { self.activate_diagnostics(group_id, cx); - self.change_selections(true, cx, |s| { - s.select( - vec![Selection { - id: selection.id, - start: primary_range.start, - end: primary_range.start, - reversed: false, - goal: SelectionGoal::None, - }], - Some(Autoscroll::Center), - ); + self.change_selections(Some(Autoscroll::Center), cx, |s| { + s.select(vec![Selection { + id: selection.id, + start: primary_range.start, + end: primary_range.start, + reversed: false, + goal: SelectionGoal::None, + }]); }); break; } else { @@ -4640,8 +4642,8 @@ impl Editor { if editor_handle != target_editor_handle { nav_history.borrow_mut().disable(); } - target_editor.change_selections(true, cx, |s| { - s.select_ranges([range], Some(Autoscroll::Center)); + target_editor.change_selections(Some(Autoscroll::Center), cx, |s| { + s.select_ranges([range]); }); nav_history.borrow_mut().enable(); @@ -4945,7 +4947,7 @@ impl Editor { reversed: false, goal: SelectionGoal::None, }; - self.change_selections(true, cx, |s| s.select(vec![new_selection], None)); + self.change_selections(None, cx, |s| s.select(vec![new_selection])); } Some(rename) @@ -5089,9 +5091,12 @@ impl Editor { selections: Vec>, cx: &mut ViewContext, ) { - self.change_selections(false, cx, |s| { - s.select_anchors(selections, None); - }); + let old_cursor_position = self.selections.newest_anchor().head(); + self.selections + .change_with(self.display_map.clone(), self.buffer.clone(), cx, |s| { + s.select_anchors(selections); + }); + self.selections_did_change(false, &old_cursor_position, cx); } fn push_to_selection_history(&mut self) { @@ -5650,8 +5655,8 @@ impl Editor { for (buffer, ranges) in new_selections_by_buffer.into_iter() { let editor = workspace.open_project_item::(buffer, cx); editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { - s.select_ranges(ranges, Some(Autoscroll::Newest)); + editor.change_selections(Some(Autoscroll::Newest), cx, |s| { + s.select_ranges(ranges); }); }); } @@ -6294,7 +6299,7 @@ mod tests { // No event is emitted when the mutation is a no-op. editor2.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| s.select_ranges([0..0], None)); + editor.change_selections(None, cx, |s| s.select_ranges([0..0])); editor.backspace(&Backspace, cx); }); @@ -6312,7 +6317,7 @@ mod tests { editor.update(cx, |editor, cx| { editor.start_transaction_at(now, cx); - editor.change_selections(true, cx, |s| s.select_ranges([2..4], None)); + editor.change_selections(None, cx, |s| s.select_ranges([2..4])); editor.insert("cd", cx); editor.end_transaction_at(now, cx); @@ -6320,14 +6325,14 @@ mod tests { assert_eq!(editor.selected_ranges(cx), vec![4..4]); editor.start_transaction_at(now, cx); - editor.change_selections(true, cx, |s| s.select_ranges([4..5], None)); + editor.change_selections(None, cx, |s| s.select_ranges([4..5])); editor.insert("e", cx); editor.end_transaction_at(now, cx); assert_eq!(editor.text(cx), "12cde6"); assert_eq!(editor.selected_ranges(cx), vec![5..5]); now += group_interval + Duration::from_millis(1); - editor.change_selections(true, cx, |s| s.select_ranges([2..2], None)); + editor.change_selections(None, cx, |s| s.select_ranges([2..2])); // Simulate an edit in another editor buffer.update(cx, |buffer, cx| { @@ -6481,17 +6486,17 @@ mod tests { // Move the cursor a small distance. // Nothing is added to the navigation history. - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]) }); - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)]) }); assert!(nav_history.borrow_mut().pop_backward().is_none()); // Move the cursor a large distance. // The history can jump back to the previous position. - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(13, 0)..DisplayPoint::new(13, 3)]) }); let nav_entry = nav_history.borrow_mut().pop_backward().unwrap(); @@ -6640,7 +6645,7 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(8, 0)..DisplayPoint::new(12, 0)]); }); view.fold(&Fold, cx); @@ -6758,7 +6763,7 @@ mod tests { &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] ); - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2)]); }); view.select_to_beginning(&SelectToBeginning, cx); @@ -6882,7 +6887,7 @@ mod tests { let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([empty_range(0, "ⓐⓑⓒⓓⓔ".len())]); }); view.move_down(&MoveDown, cx); @@ -6929,7 +6934,7 @@ mod tests { let buffer = MultiBuffer::build_simple("abc\n def", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4), @@ -7089,7 +7094,7 @@ mod tests { let buffer = MultiBuffer::build_simple("use std::str::{foo, bar}\n\n {baz.qux()}", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 11)..DisplayPoint::new(0, 11), DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4), @@ -7200,7 +7205,7 @@ mod tests { "use one::{\n two::three::\n four::five\n};" ); - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(1, 7)..DisplayPoint::new(1, 7)]); }); @@ -7251,7 +7256,7 @@ mod tests { let (_, editor) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| s.select_ranges(ranges, None)); + editor.change_selections(None, cx, |s| s.select_ranges(ranges)); editor.delete_to_beginning_of_line(&DeleteToBeginningOfLine, cx); assert_eq!(editor.text(cx), " four"); }); @@ -7264,7 +7269,7 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ // an empty selection - the preceding word fragment is deleted DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), @@ -7278,7 +7283,7 @@ mod tests { assert_eq!(buffer.read(cx).read(cx).text(), "e two te four"); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ // an empty selection - the following word fragment is deleted DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), @@ -7299,7 +7304,7 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), @@ -7332,14 +7337,11 @@ mod tests { let (_, editor) = cx.add_window(Default::default(), |cx| { let mut editor = build_editor(buffer.clone(), cx); - editor.change_selections(true, cx, |s| { - s.select_ranges( - [ - Point::new(2, 4)..Point::new(2, 5), - Point::new(5, 4)..Point::new(5, 5), - ], - None, - ) + editor.change_selections(None, cx, |s| { + s.select_ranges([ + Point::new(2, 4)..Point::new(2, 5), + Point::new(5, 4)..Point::new(5, 5), + ]) }); editor }); @@ -7403,7 +7405,7 @@ mod tests { let buffer = MultiBuffer::build_simple("a( X ), b( Y ), c( Z )", cx); let (_, editor) = cx.add_window(Default::default(), |cx| { let mut editor = build_editor(buffer.clone(), cx); - editor.change_selections(true, cx, |s| s.select_ranges([3..4, 11..12, 19..20], None)); + editor.change_selections(None, cx, |s| s.select_ranges([3..4, 11..12, 19..20])); editor }); @@ -7652,7 +7654,7 @@ mod tests { view.update(cx, |view, cx| { view.set_text("one two three\nfour five six\nseven eight nine\nten\n", cx); - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ // an empty selection - the preceding character is deleted DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), @@ -7666,7 +7668,7 @@ mod tests { assert_eq!(view.text(cx), "oe two three\nfou five six\nseven ten\n"); view.set_text(" one\n two\n three\n four", cx); - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ // cursors at the the end of leading indent - last indent is deleted DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4), @@ -7694,7 +7696,7 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer.clone(), cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ // an empty selection - the following character is deleted DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), @@ -7719,7 +7721,7 @@ mod tests { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1), @@ -7741,7 +7743,7 @@ mod tests { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)]) }); view.delete_line(&DeleteLine, cx); @@ -7759,7 +7761,7 @@ mod tests { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1), DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), @@ -7783,7 +7785,7 @@ mod tests { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(1, 2)..DisplayPoint::new(2, 1), @@ -7815,7 +7817,7 @@ mod tests { ], cx, ); - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1), @@ -7912,8 +7914,8 @@ mod tests { }], cx, ); - editor.change_selections(true, cx, |s| { - s.select_ranges([Point::new(2, 0)..Point::new(2, 0)], None) + editor.change_selections(None, cx, |s| { + s.select_ranges([Point::new(2, 0)..Point::new(2, 0)]) }); editor.move_line_down(&MoveLineDown, cx); }); @@ -7926,7 +7928,7 @@ mod tests { cx.add_window(Default::default(), |cx| { let mut editor = build_editor(MultiBuffer::build_simple("abc", cx), cx); - editor.change_selections(true, cx, |s| s.select_ranges([1..1], None)); + editor.change_selections(None, cx, |s| s.select_ranges([1..1])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bac"); assert_eq!(editor.selected_ranges(cx), [2..2]); @@ -7946,12 +7948,12 @@ mod tests { cx.add_window(Default::default(), |cx| { let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); - editor.change_selections(true, cx, |s| s.select_ranges([3..3], None)); + editor.change_selections(None, cx, |s| s.select_ranges([3..3])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acb\nde"); assert_eq!(editor.selected_ranges(cx), [3..3]); - editor.change_selections(true, cx, |s| s.select_ranges([4..4], None)); + editor.change_selections(None, cx, |s| s.select_ranges([4..4])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acbd\ne"); assert_eq!(editor.selected_ranges(cx), [5..5]); @@ -7971,7 +7973,7 @@ mod tests { cx.add_window(Default::default(), |cx| { let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); - editor.change_selections(true, cx, |s| s.select_ranges([1..1, 2..2, 4..4], None)); + editor.change_selections(None, cx, |s| s.select_ranges([1..1, 2..2, 4..4])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bacd\ne"); assert_eq!(editor.selected_ranges(cx), [2..2, 3..3, 5..5]); @@ -7999,7 +8001,7 @@ mod tests { cx.add_window(Default::default(), |cx| { let mut editor = build_editor(MultiBuffer::build_simple("🍐🏀✋", cx), cx); - editor.change_selections(true, cx, |s| s.select_ranges([4..4], None)); + editor.change_selections(None, cx, |s| s.select_ranges([4..4])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "🏀🍐✋"); assert_eq!(editor.selected_ranges(cx), [8..8]); @@ -8027,18 +8029,14 @@ mod tests { // Cut with three selections. Clipboard text is divided into three slices. view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { - s.select_ranges(vec![0..7, 11..17, 22..27], None) - }); + view.change_selections(None, cx, |s| s.select_ranges(vec![0..7, 11..17, 22..27])); view.cut(&Cut, cx); assert_eq!(view.display_text(cx), "two four six "); }); // Paste with three cursors. Each cursor pastes one slice of the clipboard text. view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { - s.select_ranges(vec![4..4, 9..9, 13..13], None) - }); + view.change_selections(None, cx, |s| s.select_ranges(vec![4..4, 9..9, 13..13])); view.paste(&Paste, cx); assert_eq!(view.display_text(cx), "two one✅ four three six five "); assert_eq!( @@ -8055,7 +8053,7 @@ mod tests { // match the number of slices in the clipboard, the entire clipboard text // is pasted at each cursor. view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| s.select_ranges(vec![0..0, 31..31], None)); + view.change_selections(None, cx, |s| s.select_ranges(vec![0..0, 31..31])); view.handle_input(&Input("( ".into()), cx); view.paste(&Paste, cx); view.handle_input(&Input(") ".into()), cx); @@ -8066,7 +8064,7 @@ mod tests { }); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| s.select_ranges(vec![0..0], None)); + view.change_selections(None, cx, |s| s.select_ranges(vec![0..0])); view.handle_input(&Input("123\n4567\n89\n".into()), cx); assert_eq!( view.display_text(cx), @@ -8076,7 +8074,7 @@ mod tests { // Cut with three selections, one of which is full-line. view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| s.select_display_ranges( + view.change_selections(None, cx, |s| s.select_display_ranges( [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), @@ -8093,7 +8091,7 @@ mod tests { // Paste with three selections, noticing how the copied selection that was full-line // gets inserted before the second cursor. view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| s.select_display_ranges( + view.change_selections(None, cx, |s| s.select_display_ranges( [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), @@ -8117,7 +8115,7 @@ mod tests { // Copy with a single cursor only, which writes the whole line into the clipboard. view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)]) }); view.copy(&Copy, cx); @@ -8126,7 +8124,7 @@ mod tests { // Paste with three selections, noticing how the copied full-line selection is inserted // before the empty selections but replaces the selection that is non-empty. view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| s.select_display_ranges( + view.change_selections(None, cx, |s| s.select_display_ranges( [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 2), @@ -8169,7 +8167,7 @@ mod tests { let buffer = MultiBuffer::build_simple(&sample_text(6, 5, 'a'), cx); let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1), DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), @@ -8221,7 +8219,7 @@ mod tests { ], cx, ); - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1), DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), @@ -8250,7 +8248,7 @@ mod tests { }); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(5, 0)..DisplayPoint::new(0, 1)]) }); view.split_selection_into_lines(&SplitSelectionIntoLines, cx); @@ -8281,7 +8279,7 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)]) }); }); @@ -8353,7 +8351,7 @@ mod tests { }); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)]) }); }); @@ -8396,7 +8394,7 @@ mod tests { }); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(0, 1)..DisplayPoint::new(1, 4)]) }); view.add_selection_below(&AddSelectionBelow, cx); @@ -8436,7 +8434,7 @@ mod tests { }); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(4, 3)..DisplayPoint::new(1, 1)]) }); }); @@ -8475,8 +8473,8 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, cx)); view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { - s.select_ranges([ranges[1].start + 1..ranges[1].start + 1], None) + view.change_selections(None, cx, |s| { + s.select_ranges([ranges[1].start + 1..ranges[1].start + 1]) }); view.select_next( &SelectNext { @@ -8542,7 +8540,7 @@ mod tests { .await; view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25), DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12), @@ -8701,7 +8699,7 @@ mod tests { .await; editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| s.select_ranges([5..5, 8..8, 9..9], None)); + editor.change_selections(None, cx, |s| s.select_ranges([5..5, 8..8, 9..9])); editor.newline(&Newline, cx); assert_eq!(editor.text(cx), "fn a(\n \n) {\n \n}\n"); assert_eq!( @@ -8755,7 +8753,7 @@ mod tests { .await; view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), @@ -8806,7 +8804,7 @@ mod tests { ); view.undo(&Undo, cx); - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0), @@ -8827,7 +8825,7 @@ mod tests { // Don't autoclose if the next character isn't whitespace and isn't // listed in the language's "autoclose_before" section. view.finalize_last_transaction(cx); - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]) }); view.handle_input(&Input("{".to_string()), cx); @@ -8843,7 +8841,7 @@ mod tests { ); view.undo(&Undo, cx); - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1)]) }); view.handle_input(&Input("{".to_string()), cx); @@ -8931,6 +8929,14 @@ mod tests { ); assert!(editor.move_to_next_snippet_tabstop(cx)); + assert( + editor, + cx, + indoc! {" + a.f(one, , three) b + a.f(one, , three) b + a.f(one, , three) b"}, + ); assert!(editor.move_to_next_snippet_tabstop(cx)); assert( editor, @@ -9113,8 +9119,8 @@ mod tests { editor.update(cx, |editor, cx| { editor.project = Some(project); - editor.change_selections(true, cx, |s| { - s.select_ranges([Point::new(0, 3)..Point::new(0, 3)], None) + editor.change_selections(None, cx, |s| { + s.select_ranges([Point::new(0, 3)..Point::new(0, 3)]) }); editor.handle_input(&Input(".".to_string()), cx); }); @@ -9168,14 +9174,11 @@ mod tests { ); editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { - s.select_ranges( - [ - Point::new(1, 3)..Point::new(1, 3), - Point::new(2, 5)..Point::new(2, 5), - ], - None, - ) + editor.change_selections(None, cx, |s| { + s.select_ranges([ + Point::new(1, 3)..Point::new(1, 3), + Point::new(2, 5)..Point::new(2, 5), + ]) }); editor.handle_input(&Input(" ".to_string()), cx); @@ -9329,7 +9332,7 @@ mod tests { view.update(cx, |editor, cx| { // If multiple selections intersect a line, the line is only // toggled once. - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(1, 3)..DisplayPoint::new(2, 3), DisplayPoint::new(3, 5)..DisplayPoint::new(3, 6), @@ -9350,7 +9353,7 @@ mod tests { // The comment prefix is inserted at the same column for every line // in a selection. - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(1, 3)..DisplayPoint::new(3, 6)]) }); editor.toggle_comments(&ToggleComments, cx); @@ -9367,7 +9370,7 @@ mod tests { ); // If a selection ends at the beginning of a line, that line is not toggled. - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(3, 0)]) }); editor.toggle_comments(&ToggleComments, cx); @@ -9407,14 +9410,11 @@ mod tests { let (_, view) = cx.add_window(Default::default(), |cx| build_editor(multibuffer, cx)); view.update(cx, |view, cx| { assert_eq!(view.text(cx), "aaaa\nbbbb"); - view.change_selections(true, cx, |s| { - s.select_ranges( - [ - Point::new(0, 0)..Point::new(0, 0), - Point::new(1, 0)..Point::new(1, 0), - ], - None, - ) + view.change_selections(None, cx, |s| { + s.select_ranges([ + Point::new(0, 0)..Point::new(0, 0), + Point::new(1, 0)..Point::new(1, 0), + ]) }); view.handle_input(&Input("X".to_string()), cx); @@ -9451,7 +9451,7 @@ mod tests { b|bb|b cccc"}); assert_eq!(view.text(cx), expected_text); - view.change_selections(true, cx, |s| s.select_ranges(selection_ranges, None)); + view.change_selections(None, cx, |s| s.select_ranges(selection_ranges)); view.handle_input(&Input("X".to_string()), cx); @@ -9505,8 +9505,8 @@ mod tests { let (_, editor) = cx.add_window(Default::default(), |cx| { let mut editor = build_editor(multibuffer.clone(), cx); let snapshot = editor.snapshot(cx); - editor.change_selections(true, cx, |s| { - s.select_ranges([Point::new(1, 3)..Point::new(1, 3)], None) + editor.change_selections(None, cx, |s| { + s.select_ranges([Point::new(1, 3)..Point::new(1, 3)]) }); editor.begin_selection(Point::new(2, 1).to_display_point(&snapshot), true, 1, cx); assert_eq!( @@ -9521,7 +9521,7 @@ mod tests { // Refreshing selections is a no-op when excerpts haven't changed. editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.refresh(); }); assert_eq!( @@ -9548,7 +9548,7 @@ mod tests { // Refreshing selections will relocate the first selection to the original buffer // location. - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.refresh(); }); assert_eq!( @@ -9607,7 +9607,7 @@ mod tests { ); // Ensure we don't panic when selections are refreshed and that the pending selection is finalized. - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.refresh(); }); assert_eq!( @@ -9657,7 +9657,7 @@ mod tests { .await; view.update(cx, |view, cx| { - view.change_selections(true, cx, |s| { + view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 3), DisplayPoint::new(2, 5)..DisplayPoint::new(2, 5), @@ -9796,7 +9796,7 @@ mod tests { // Update the selections only leader.update(cx, |leader, cx| { - leader.change_selections(true, cx, |s| s.select_ranges([1..1], None)); + leader.change_selections(None, cx, |s| s.select_ranges([1..1])); }); follower.update(cx, |follower, cx| { follower @@ -9821,7 +9821,7 @@ mod tests { // Update the selections and scroll position leader.update(cx, |leader, cx| { - leader.change_selections(true, cx, |s| s.select_ranges([0..0], None)); + leader.change_selections(None, cx, |s| s.select_ranges([0..0])); leader.request_autoscroll(Autoscroll::Newest, cx); leader.set_scroll_position(vec2f(1.5, 3.5), cx); }); @@ -9837,7 +9837,7 @@ mod tests { // Creating a pending selection that precedes another selection leader.update(cx, |leader, cx| { - leader.change_selections(true, cx, |s| s.select_ranges([1..1], None)); + leader.change_selections(None, cx, |s| s.select_ranges([1..1])); leader.begin_selection(DisplayPoint::new(0, 0), true, 1, cx); }); follower.update(cx, |follower, cx| { diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index b87719c130..1652334b38 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -276,8 +276,8 @@ impl Item for Editor { let nav_history = self.nav_history.take(); self.scroll_position = data.scroll_position; self.scroll_top_anchor = scroll_top_anchor; - self.change_selections(true, cx, |s| { - s.select_ranges([offset..offset], Some(Autoscroll::Fit)) + self.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select_ranges([offset..offset]) }); self.nav_history = nav_history; true diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs index fc2f563099..cbe4f0fbef 100644 --- a/crates/editor/src/selections_collection.rs +++ b/crates/editor/src/selections_collection.rs @@ -12,8 +12,7 @@ use util::post_inc; use crate::{ display_map::{DisplayMap, DisplaySnapshot, ToDisplayPoint}, - Anchor, Autoscroll, DisplayPoint, ExcerptId, MultiBuffer, MultiBufferSnapshot, SelectMode, - ToOffset, + Anchor, DisplayPoint, ExcerptId, MultiBuffer, MultiBufferSnapshot, SelectMode, ToOffset, }; #[derive(Clone)] @@ -79,10 +78,10 @@ impl SelectionsCollection { pub fn interleaved<'a, D>(&self, buffer: &MultiBufferSnapshot) -> Vec> where - D: 'a + TextDimension + Ord + Sub, + D: 'a + TextDimension + Ord + Sub + std::fmt::Debug, { - let anchor_disjoint = &self.disjoint; - let mut disjoint = resolve_multiple::(anchor_disjoint.iter(), &buffer).peekable(); + let disjoint_anchors = &self.disjoint; + let mut disjoint = resolve_multiple::(disjoint_anchors.iter(), &buffer).peekable(); let mut pending_opt = self.pending::(&buffer); @@ -197,36 +196,31 @@ impl SelectionsCollection { self.interleaved(&snapshot).last().unwrap().clone() } - // NOTE do not use. This should only be called from Editor::change_selections. - #[deprecated] - pub fn change_with( + pub(crate) fn change_with( &mut self, display_map: ModelHandle, buffer: ModelHandle, cx: &mut MutableAppContext, change: impl FnOnce(&mut MutableSelectionsCollection) -> R, - ) -> (Option, R) { + ) -> R { let mut mutable_collection = MutableSelectionsCollection { collection: self, - autoscroll: None, display_map, buffer, cx, }; let result = change(&mut mutable_collection); - assert!( !mutable_collection.disjoint.is_empty() || mutable_collection.pending.is_some(), "There must be at least one selection" ); - (mutable_collection.autoscroll, result) + result } } pub struct MutableSelectionsCollection<'a> { collection: &'a mut SelectionsCollection, - pub autoscroll: Option, buffer: ModelHandle, display_map: ModelHandle, cx: &'a mut MutableAppContext, @@ -307,7 +301,7 @@ impl<'a> MutableSelectionsCollection<'a> { } } - pub fn insert_range(&mut self, range: Range, autoscroll: Option) + pub fn insert_range(&mut self, range: Range) where T: 'a + ToOffset @@ -335,10 +329,10 @@ impl<'a> MutableSelectionsCollection<'a> { reversed, goal: SelectionGoal::None, }); - self.select(selections, autoscroll); + self.select(selections); } - pub fn select(&mut self, mut selections: Vec>, autoscroll: Option) + pub fn select(&mut self, mut selections: Vec>) where T: ToOffset + ToPoint + Ord + std::marker::Copy + std::fmt::Debug, { @@ -360,8 +354,6 @@ impl<'a> MutableSelectionsCollection<'a> { } } - self.autoscroll = autoscroll.or(self.autoscroll.take()); - self.collection.disjoint = Arc::from_iter(selections.into_iter().map(|selection| { let end_bias = if selection.end > selection.start { Bias::Left @@ -380,46 +372,14 @@ impl<'a> MutableSelectionsCollection<'a> { self.collection.pending = None; } - pub fn select_anchors( - &mut self, - mut selections: Vec>, - autoscroll: Option, - ) { + pub fn select_anchors(&mut self, selections: Vec>) { let buffer = self.buffer.read(self.cx).snapshot(self.cx); - selections.sort_unstable_by(|a, b| a.start.cmp(&b.start, &buffer)); - - // Merge overlapping selections. - let mut i = 1; - while i < selections.len() { - if selections[i - 1] - .end - .cmp(&selections[i].start, &buffer) - .is_ge() - { - let removed = selections.remove(i); - if removed.start.cmp(&selections[i - 1].start, &buffer).is_lt() { - selections[i - 1].start = removed.start; - } - if removed.end.cmp(&selections[i - 1].end, &buffer).is_gt() { - selections[i - 1].end = removed.end; - } - } else { - i += 1; - } - } - - self.autoscroll = autoscroll.or(self.autoscroll.take()); - - self.collection.disjoint = Arc::from_iter( - selections - .into_iter() - .map(|selection| reset_biases(selection, &buffer)), - ); - - self.collection.pending = None; + let resolved_selections = + resolve_multiple::(&selections, &buffer).collect::>(); + self.select(resolved_selections); } - pub fn select_ranges(&mut self, ranges: I, autoscroll: Option) + pub fn select_ranges(&mut self, ranges: I) where I: IntoIterator>, T: ToOffset, @@ -446,14 +406,10 @@ impl<'a> MutableSelectionsCollection<'a> { }) .collect::>(); - self.select(selections, autoscroll) + self.select(selections) } - pub fn select_anchor_ranges>>( - &mut self, - ranges: I, - autoscroll: Option, - ) { + pub fn select_anchor_ranges>>(&mut self, ranges: I) { let buffer = self.buffer.read(self.cx).snapshot(self.cx); let selections = ranges .into_iter() @@ -476,7 +432,7 @@ impl<'a> MutableSelectionsCollection<'a> { }) .collect::>(); - self.select_anchors(selections, autoscroll) + self.select_anchors(selections) } #[cfg(any(test, feature = "test-support"))] @@ -505,7 +461,7 @@ impl<'a> MutableSelectionsCollection<'a> { } }) .collect(); - self.select(selections, None); + self.select(selections); } pub fn move_with( @@ -523,7 +479,7 @@ impl<'a> MutableSelectionsCollection<'a> { }) .collect(); - self.select(selections, Some(Autoscroll::Fit)) + self.select(selections) } pub fn move_heads_with( @@ -572,7 +528,7 @@ impl<'a> MutableSelectionsCollection<'a> { } }) .collect(); - self.select(new_selections, None); + self.select(new_selections); } /// Compute new ranges for any selections that were located in excerpts that have @@ -620,10 +576,7 @@ impl<'a> MutableSelectionsCollection<'a> { .collect(); if !adjusted_disjoint.is_empty() { - self.select::( - resolve_multiple(adjusted_disjoint.iter(), &buffer).collect(), - None, - ); + self.select::(resolve_multiple(adjusted_disjoint.iter(), &buffer).collect()); } if let Some(pending) = pending.as_mut() { @@ -665,12 +618,16 @@ pub fn resolve_multiple<'a, D, I>( snapshot: &MultiBufferSnapshot, ) -> impl 'a + Iterator> where - D: TextDimension + Ord + Sub, + D: TextDimension + Ord + Sub + std::fmt::Debug, I: 'a + IntoIterator>, { let (to_summarize, selections) = selections.into_iter().tee(); let mut summaries = snapshot - .summaries_for_anchors::(to_summarize.flat_map(|s| [&s.start, &s.end])) + .summaries_for_anchors::( + to_summarize + .flat_map(|s| [&s.start, &s.end]) + .collect::>(), + ) .into_iter(); selections.map(move |s| Selection { id: s.id, @@ -692,7 +649,7 @@ fn reset_biases( mut selection: Selection, buffer: &MultiBufferSnapshot, ) -> Selection { - let end_bias = if selection.end.cmp(&selection.start, buffer).is_gt() { + let end_bias = if selection.end.to_offset(buffer) > selection.start.to_offset(buffer) { Bias::Left } else { Bias::Right diff --git a/crates/editor/src/test.rs b/crates/editor/src/test.rs index 407733c771..d707e55c3a 100644 --- a/crates/editor/src/test.rs +++ b/crates/editor/src/test.rs @@ -43,7 +43,7 @@ pub fn marked_display_snapshot( pub fn select_ranges(editor: &mut Editor, marked_text: &str, cx: &mut ViewContext) { let (umarked_text, text_ranges) = marked_text_ranges(marked_text); assert_eq!(editor.text(cx), umarked_text); - editor.change_selections(true, cx, |s| s.select_ranges(text_ranges, None)); + editor.change_selections(None, cx, |s| s.select_ranges(text_ranges)); } pub fn assert_text_with_selections( diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index 2f7219aa6f..bb889a5b37 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -80,8 +80,8 @@ impl GoToLine { if let Some(rows) = active_editor.highlighted_rows() { let snapshot = active_editor.snapshot(cx).display_snapshot; let position = DisplayPoint::new(rows.start, 0).to_point(&snapshot); - active_editor.change_selections(true, cx, |s| { - s.select_ranges([position..position], Some(Autoscroll::Center)) + active_editor.change_selections(Some(Autoscroll::Center), cx, |s| { + s.select_ranges([position..position]) }); } }); diff --git a/crates/journal/src/journal.rs b/crates/journal/src/journal.rs index ff0dfa5145..dd105fd4e3 100644 --- a/crates/journal/src/journal.rs +++ b/crates/journal/src/journal.rs @@ -57,8 +57,8 @@ pub fn new_journal_entry(app_state: Arc, cx: &mut MutableAppContext) { if let Some(editor) = item.downcast::() { editor.update(&mut cx, |editor, cx| { let len = editor.buffer().read(cx).read(cx).len(); - editor.change_selections(true, cx, |s| { - s.select_ranges([len..len], Some(Autoscroll::Center)) + editor.change_selections(Some(Autoscroll::Center), cx, |s| { + s.select_ranges([len..len]) }); if len > 0 { editor.insert("\n\n", cx); diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 7383b4b3a9..12f5168c9d 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -215,8 +215,8 @@ impl PickerDelegate for OutlineView { if let Some(rows) = active_editor.highlighted_rows() { let snapshot = active_editor.snapshot(cx).display_snapshot; let position = DisplayPoint::new(rows.start, 0).to_point(&snapshot); - active_editor.change_selections(true, cx, |s| { - s.select_ranges([position..position], Some(Autoscroll::Center)) + active_editor.change_selections(Some(Autoscroll::Center), cx, |s| { + s.select_ranges([position..position]) }); } }); diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index 80530ff5e6..a18039ecfd 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -145,8 +145,8 @@ impl ProjectSymbolsView { let editor = workspace.open_project_item::(buffer, cx); editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { - s.select_ranges([position..position], Some(Autoscroll::Center)) + editor.change_selections(Some(Autoscroll::Center), cx, |s| { + s.select_ranges([position..position]) }); }); }); diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 95ef808ab0..00205b634c 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -395,8 +395,8 @@ impl BufferSearchBar { ); let range_to_select = ranges[new_index].clone(); editor.unfold_ranges([range_to_select.clone()], false, cx); - editor.change_selections(true, cx, |s| { - s.select_ranges([range_to_select], Some(Autoscroll::Fit)) + editor.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select_ranges([range_to_select]) }); } }); @@ -538,12 +538,11 @@ impl BufferSearchBar { editor.update(cx, |editor, cx| { if select_closest_match { if let Some(match_ix) = this.active_match_index { - editor.change_selections(true, cx, |s| { - s.select_ranges( - [ranges[match_ix].clone()], - Some(Autoscroll::Fit), - ) - }); + editor.change_selections( + Some(Autoscroll::Fit), + cx, + |s| s.select_ranges([ranges[match_ix].clone()]), + ); } } @@ -725,7 +724,7 @@ mod tests { }); editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]) }); }); @@ -810,7 +809,7 @@ mod tests { // Park the cursor in between matches and ensure that going to the previous match selects // the closest match to the left. editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]) }); }); @@ -829,7 +828,7 @@ mod tests { // Park the cursor in between matches and ensure that going to the next match selects the // closest match to the right. editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]) }); }); @@ -848,7 +847,7 @@ mod tests { // Park the cursor after the last match and ensure that going to the previous match selects // the last match. editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(3, 60)..DisplayPoint::new(3, 60)]) }); }); @@ -867,7 +866,7 @@ mod tests { // Park the cursor after the last match and ensure that going to the next match selects the // first match. editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(3, 60)..DisplayPoint::new(3, 60)]) }); }); @@ -886,7 +885,7 @@ mod tests { // Park the cursor before the first match and ensure that going to the previous match // selects the last match. editor.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]) }); }); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 1e363ebf15..8bd043f86b 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -462,8 +462,8 @@ impl ProjectSearchView { let range_to_select = model.match_ranges[new_index].clone(); self.results_editor.update(cx, |editor, cx| { editor.unfold_ranges([range_to_select.clone()], false, cx); - editor.change_selections(true, cx, |s| { - s.select_ranges([range_to_select], Some(Autoscroll::Fit)) + editor.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select_ranges([range_to_select]) }); }); } @@ -479,9 +479,7 @@ impl ProjectSearchView { fn focus_results_editor(&self, cx: &mut ViewContext) { self.query_editor.update(cx, |query_editor, cx| { let cursor = query_editor.selections.newest_anchor().head(); - query_editor.change_selections(true, cx, |s| { - s.select_ranges([cursor.clone()..cursor], None) - }); + query_editor.change_selections(None, cx, |s| s.select_ranges([cursor.clone()..cursor])); }); cx.focus(&self.results_editor); } @@ -493,8 +491,8 @@ impl ProjectSearchView { } else { self.results_editor.update(cx, |editor, cx| { if reset_selections { - editor.change_selections(true, cx, |s| { - s.select_ranges(match_ranges.first().cloned(), Some(Autoscroll::Fit)) + editor.change_selections(Some(Autoscroll::Fit), cx, |s| { + s.select_ranges(match_ranges.first().cloned()) }); } editor.highlight_background::( diff --git a/crates/vim/src/insert.rs b/crates/vim/src/insert.rs index 69912cff18..1e19b7d918 100644 --- a/crates/vim/src/insert.rs +++ b/crates/vim/src/insert.rs @@ -1,5 +1,5 @@ use crate::{state::Mode, Vim}; -use editor::Bias; +use editor::{Autoscroll, Bias}; use gpui::{actions, MutableAppContext, ViewContext}; use language::SelectionGoal; use workspace::Workspace; @@ -13,7 +13,7 @@ pub fn init(cx: &mut MutableAppContext) { fn normal_before(_: &mut Workspace, _: &NormalBefore, cx: &mut ViewContext) { Vim::update(cx, |state, cx| { state.update_active_editor(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_cursors_with(|map, mut cursor, _| { *cursor.column_mut() = cursor.column().saturating_sub(1); (map.clip_point(cursor, Bias::Left), SelectionGoal::None) diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 7c4ac6a20c..be218592cc 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -8,7 +8,7 @@ use crate::{ }; use change::init as change_init; use collections::HashSet; -use editor::{Bias, DisplayPoint}; +use editor::{Autoscroll, Bias, DisplayPoint}; use gpui::{actions, MutableAppContext, ViewContext}; use language::SelectionGoal; use workspace::Workspace; @@ -76,7 +76,7 @@ pub fn normal_motion(motion: Motion, cx: &mut MutableAppContext) { fn move_cursor(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) { vim.update_active_editor(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_cursors_with(|map, cursor, goal| motion.move_point(map, cursor, goal)) }) }); @@ -86,7 +86,7 @@ fn insert_after(_: &mut Workspace, _: &InsertAfter, cx: &mut ViewContext = Default::default(); - editor.change_selections(true, cx, |s| { + editor.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { let original_head = selection.head(); motion.expand_selection(map, selection, true); @@ -19,7 +19,7 @@ pub fn delete_over(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) { // Fixup cursor position after the deletion editor.set_clip_at_line_ends(true, cx); - editor.change_selections(true, cx, |s| { + editor.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { let mut cursor = selection.head(); if motion.linewise() { diff --git a/crates/vim/src/vim_test_context.rs b/crates/vim/src/vim_test_context.rs index cfcfa8d2b4..28c15ffacd 100644 --- a/crates/vim/src/vim_test_context.rs +++ b/crates/vim/src/vim_test_context.rs @@ -3,7 +3,7 @@ use std::ops::{Deref, Range}; use collections::BTreeMap; use itertools::{Either, Itertools}; -use editor::display_map::ToDisplayPoint; +use editor::{display_map::ToDisplayPoint, Autoscroll}; use gpui::{json::json, keymap::Keystroke, ViewHandle}; use indoc::indoc; use language::Selection; @@ -128,7 +128,7 @@ impl<'a> VimTestContext<'a> { let (unmarked_text, markers) = marked_text(&text); editor.set_text(unmarked_text, cx); let cursor_offset = markers[0]; - editor.change_selections(true, cx, |s| { + editor.change_selections(Some(Autoscroll::Fit), cx, |s| { s.replace_cursors_with(|map| vec![cursor_offset.to_display_point(map)]) }); }) diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index c1b2771f7a..4d32d38c30 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -1,4 +1,4 @@ -use editor::Bias; +use editor::{Autoscroll, Bias}; use gpui::{actions, MutableAppContext, ViewContext}; use workspace::Workspace; @@ -14,7 +14,7 @@ pub fn init(cx: &mut MutableAppContext) { pub fn visual_motion(motion: Motion, cx: &mut MutableAppContext) { Vim::update(cx, |vim, cx| { vim.update_active_editor(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { let (new_head, goal) = motion.move_point(map, selection.head(), selection.goal); let new_head = map.clip_at_line_end(new_head); @@ -42,7 +42,7 @@ pub fn change(_: &mut Workspace, _: &VisualChange, cx: &mut ViewContext() .unwrap(); editor1.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(Some(Autoscroll::Fit), cx, |s| { s.select_display_ranges([DisplayPoint::new(10, 0)..DisplayPoint::new(10, 0)]) }); }); @@ -981,7 +981,7 @@ mod tests { editor3 .update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(Some(Autoscroll::Fit), cx, |s| { s.select_display_ranges([DisplayPoint::new(12, 0)..DisplayPoint::new(12, 0)]) }); editor.newline(&Default::default(), cx); @@ -1124,19 +1124,19 @@ mod tests { // Modify file to collapse multiple nav history entries into the same location. // Ensure we don't visit the same location twice when navigating. editor1.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(15, 0)..DisplayPoint::new(15, 0)]) }) }); for _ in 0..5 { editor1.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)]) }); }); editor1.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(13, 0)..DisplayPoint::new(13, 0)]) }) }); @@ -1144,7 +1144,7 @@ mod tests { editor1.update(cx, |editor, cx| { editor.transact(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(14, 0)]) }); editor.insert("", cx); @@ -1152,7 +1152,7 @@ mod tests { }); editor1.update(cx, |editor, cx| { - editor.change_selections(true, cx, |s| { + editor.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]) }) }); From de9dc279806131d736d4d00e5e1f17418e083656 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Thu, 12 May 2022 15:55:18 -0700 Subject: [PATCH 12/18] store buffer and display_map model handles on selections collection --- crates/collab/src/rpc.rs | 10 +- crates/diagnostics/src/diagnostics.rs | 8 +- crates/diagnostics/src/items.rs | 2 +- crates/editor/src/editor.rs | 526 +++++++++------------ crates/editor/src/element.rs | 4 +- crates/editor/src/items.rs | 4 +- crates/editor/src/selections_collection.rs | 117 +++-- crates/editor/src/test.rs | 2 +- crates/go_to_line/src/go_to_line.rs | 2 +- crates/outline/src/outline.rs | 2 +- crates/search/src/buffer_search.rs | 53 ++- crates/search/src/project_search.rs | 32 +- crates/vim/src/vim_test_context.rs | 2 +- crates/zed/src/zed.rs | 2 +- 14 files changed, 373 insertions(+), 393 deletions(-) diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 3ff9e13edb..2f182c1522 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -5499,11 +5499,11 @@ mod tests { Some((worktree_id, "2.txt").into()) ); assert_eq!( - editor_b2.read_with(cx_b, |editor, cx| editor.selected_ranges(cx)), + editor_b2.read_with(cx_b, |editor, cx| editor.selections.selected_ranges(cx)), vec![2..3] ); assert_eq!( - editor_b1.read_with(cx_b, |editor, cx| editor.selected_ranges(cx)), + editor_b1.read_with(cx_b, |editor, cx| editor.selections.selected_ranges(cx)), vec![0..1] ); @@ -5546,7 +5546,7 @@ mod tests { }); editor_b1 .condition(cx_b, |editor, cx| { - editor.selected_ranges(cx) == vec![1..1, 2..2] + editor.selections.selected_ranges(cx) == vec![1..1, 2..2] }) .await; @@ -5560,7 +5560,9 @@ mod tests { editor.set_scroll_position(vec2f(0., 100.), cx); }); editor_b1 - .condition(cx_b, |editor, cx| editor.selected_ranges(cx) == vec![3..3]) + .condition(cx_b, |editor, cx| { + editor.selections.selected_ranges(cx) == vec![3..3] + }) .await; // After unfollowing, client B stops receiving updates from client A. diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 7fb7bffb1e..d7eb089830 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -419,9 +419,7 @@ impl ProjectDiagnosticsEditor { groups = self.path_states.get(path_ix)?.diagnostic_groups.as_slice(); new_excerpt_ids_by_selection_id = editor.change_selections(Some(Autoscroll::Fit), cx, |s| s.refresh()); - selections = editor - .selections - .interleaved::(&editor.buffer().read(cx).read(cx)); + selections = editor.selections.interleaved::(cx); } // If any selection has lost its position, move it to start of the next primary diagnostic. @@ -899,7 +897,7 @@ mod tests { // Cursor is at the first diagnostic view.editor.update(cx, |editor, cx| { assert_eq!( - editor.selected_display_ranges(cx), + editor.selections.selected_display_ranges(cx), [DisplayPoint::new(12, 6)..DisplayPoint::new(12, 6)] ); }); @@ -1000,7 +998,7 @@ mod tests { // Cursor keeps its position. view.editor.update(cx, |editor, cx| { assert_eq!( - editor.selected_display_ranges(cx), + editor.selections.selected_display_ranges(cx), [DisplayPoint::new(19, 6)..DisplayPoint::new(19, 6)] ); }); diff --git a/crates/diagnostics/src/items.rs b/crates/diagnostics/src/items.rs index abc0b13181..752fc26f0f 100644 --- a/crates/diagnostics/src/items.rs +++ b/crates/diagnostics/src/items.rs @@ -58,7 +58,7 @@ impl DiagnosticIndicator { fn update(&mut self, editor: ViewHandle, cx: &mut ViewContext) { let editor = editor.read(cx); let buffer = editor.buffer().read(cx); - let cursor_position = editor.selections.newest::(&buffer.read(cx)).head(); + let cursor_position = editor.selections.newest::(cx).head(); let new_diagnostic = buffer .read(cx) .diagnostics_in_range::<_, usize>(cursor_position..cursor_position, false) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 6d907b2b76..60570360dc 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -51,12 +51,11 @@ use std::{ borrow::Cow, cmp::{self, Ordering, Reverse}, iter, mem, - ops::{Deref, DerefMut, Range, RangeInclusive, Sub}, + ops::{Deref, DerefMut, Range, RangeInclusive}, sync::Arc, time::{Duration, Instant}, }; pub use sum_tree::Bias; -use text::rope::TextDimension; use theme::{DiagnosticStyle, Theme}; use util::{post_inc, ResultExt, TryFutureExt}; use workspace::{ItemNavHistory, Workspace}; @@ -938,11 +937,13 @@ impl Editor { cx.observe(&display_map, Self::on_display_map_changed) .detach(); + let selections = SelectionsCollection::new(display_map.clone(), buffer.clone()); + let mut this = Self { handle: cx.weak_handle(), buffer, display_map, - selections: SelectionsCollection::new(), + selections, columnar_selection_tail: None, add_selections_state: None, select_next_state: None, @@ -1186,15 +1187,11 @@ impl Editor { first_cursor_top = highlighted_rows.start as f32; last_cursor_bottom = first_cursor_top + 1.; } else if autoscroll == Autoscroll::Newest { - let newest_selection = self - .selections - .newest::(&display_map.buffer_snapshot); + let newest_selection = self.selections.newest::(cx); first_cursor_top = newest_selection.head().to_display_point(&display_map).row() as f32; last_cursor_bottom = first_cursor_top + 1.; } else { - let selections = self - .selections - .interleaved::(&display_map.buffer_snapshot); + let selections = self.selections.interleaved::(cx); first_cursor_top = selections .first() .unwrap() @@ -1254,9 +1251,7 @@ impl Editor { cx: &mut ViewContext, ) -> bool { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = self - .selections - .interleaved::(&display_map.buffer_snapshot); + let selections = self.selections.interleaved::(cx); let mut target_left; let mut target_right; @@ -1387,9 +1382,7 @@ impl Editor { let old_cursor_position = self.selections.newest_anchor().head(); self.push_to_selection_history(); - let result = - self.selections - .change_with(self.display_map.clone(), self.buffer.clone(), cx, change); + let result = self.selections.change_with(cx, change); if let Some(autoscroll) = autoscroll { self.request_autoscroll(autoscroll, cx); @@ -1406,7 +1399,7 @@ impl Editor { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let selections = self .selections - .interleaved::(&display_map.buffer_snapshot) + .interleaved::(cx) .into_iter() .map(|selection| selection.map(|point| point.to_display_point(&display_map))) .collect(); @@ -1465,10 +1458,7 @@ impl Editor { cx: &mut ViewContext, ) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let tail = self - .selections - .newest::(&display_map.buffer_snapshot) - .tail(); + let tail = self.selections.newest::(cx).tail(); self.begin_selection(position, false, click_count, cx); let position = position.to_offset(&display_map, Bias::Left); @@ -1573,10 +1563,7 @@ impl Editor { } let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let tail = self - .selections - .newest::(&display_map.buffer_snapshot) - .tail(); + let tail = self.selections.newest::(cx).tail(); self.columnar_selection_tail = Some(display_map.buffer_snapshot.anchor_before(tail)); self.select_columns( @@ -1687,9 +1674,7 @@ impl Editor { fn end_selection(&mut self, cx: &mut ViewContext) { self.columnar_selection_tail.take(); if self.selections.pending_anchor().is_some() { - let selections = self - .selections - .interleaved::(&self.buffer.read(cx).snapshot(cx)); + let selections = self.selections.interleaved::(cx); self.change_selections(None, cx, |s| { s.select(selections); s.clear_pending(); @@ -1769,43 +1754,6 @@ impl Editor { cx.propagate_action(); } - #[cfg(any(test, feature = "test-support"))] - pub fn selected_ranges + std::fmt::Debug>( - &self, - cx: &AppContext, - ) -> Vec> { - self.selections - .interleaved::(&self.buffer.read(cx).read(cx)) - .iter() - .map(|s| { - if s.reversed { - s.end.clone()..s.start.clone() - } else { - s.start.clone()..s.end.clone() - } - }) - .collect() - } - - #[cfg(any(test, feature = "test-support"))] - pub fn selected_display_ranges(&self, cx: &mut MutableAppContext) -> Vec> { - let display_map = self - .display_map - .update(cx, |display_map, cx| display_map.snapshot(cx)); - self.selections - .disjoint_anchors() - .iter() - .chain(self.selections.pending_anchor().as_ref()) - .map(|s| { - if s.reversed { - s.end.to_display_point(&display_map)..s.start.to_display_point(&display_map) - } else { - s.start.to_display_point(&display_map)..s.end.to_display_point(&display_map) - } - }) - .collect() - } - pub fn handle_input(&mut self, action: &Input, cx: &mut ViewContext) { if !self.input_enabled { cx.propagate_action(); @@ -1827,8 +1775,9 @@ impl Editor { pub fn newline(&mut self, _: &Newline, cx: &mut ViewContext) { self.transact(cx, |this, cx| { let (edits, selection_fixup_info): (Vec<_>, Vec<_>) = { + let selections = this.selections.interleaved::(cx); + let buffer = this.buffer.read(cx).snapshot(cx); - let selections = this.selections.interleaved::(&buffer); selections .iter() .map(|selection| { @@ -1910,9 +1859,7 @@ impl Editor { pub fn insert(&mut self, text: &str, cx: &mut ViewContext) { let text: Arc = text.into(); self.transact(cx, |this, cx| { - let old_selections = this - .selections - .interleaved::(&this.buffer.read(cx).snapshot(cx)); + let old_selections = this.selections.interleaved::(cx); let selection_anchors = this.buffer.update(cx, |buffer, cx| { let anchors = { let snapshot = buffer.read(cx); @@ -1975,7 +1922,7 @@ impl Editor { { if self .selections - .interleaved::(&snapshot) + .interleaved::(cx) .iter() .any(|selection| selection.is_empty()) { @@ -2018,8 +1965,7 @@ impl Editor { } fn autoclose_bracket_pairs(&mut self, cx: &mut ViewContext) { - let snapshot = self.buffer.read(cx).snapshot(cx); - let selections = self.selections.interleaved::(&snapshot); + let selections = self.selections.interleaved::(cx); let mut bracket_pair_state = None; let mut new_selections = None; self.buffer.update(cx, |buffer, cx| { @@ -2119,7 +2065,7 @@ impl Editor { fn skip_autoclose_end(&mut self, text: &str, cx: &mut ViewContext) -> bool { let buffer = self.buffer.read(cx).snapshot(cx); - let old_selections = self.selections.interleaved::(&buffer); + let old_selections = self.selections.interleaved::(cx); let autoclose_pair = if let Some(autoclose_pair) = self.autoclose_stack.last() { autoclose_pair } else { @@ -2288,13 +2234,11 @@ impl Editor { snippet = None; text = completion.new_text.clone(); }; + let selections = self.selections.interleaved::(cx); let buffer = buffer_handle.read(cx); let old_range = completion.old_range.to_offset(&buffer); let old_text = buffer.text_for_range(old_range.clone()).collect::(); - let selections = self - .selections - .interleaved::(&self.buffer.read(cx).snapshot(cx)); let newest_selection = self.selections.newest_anchor(); if newest_selection.start.buffer_id != Some(buffer_handle.id()) { return None; @@ -2816,9 +2760,7 @@ impl Editor { pub fn backspace(&mut self, _: &Backspace, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let mut selections = self - .selections - .interleaved::(&display_map.buffer_snapshot); + let mut selections = self.selections.interleaved::(cx); for selection in &mut selections { if selection.is_empty() { let old_head = selection.head(); @@ -2877,9 +2819,7 @@ impl Editor { return; } - let mut selections = self - .selections - .interleaved::(&self.buffer.read(cx).read(cx)); + let mut selections = self.selections.interleaved::(cx); if selections.iter().all(|s| s.is_empty()) { self.transact(cx, |this, cx| { this.buffer.update(cx, |buffer, cx| { @@ -2914,9 +2854,7 @@ impl Editor { } pub fn indent(&mut self, _: &Indent, cx: &mut ViewContext) { - let mut selections = self - .selections - .interleaved::(&self.buffer.read(cx).read(cx)); + let mut selections = self.selections.interleaved::(cx); self.transact(cx, |this, cx| { let mut last_indent = None; this.buffer.update(cx, |buffer, cx| { @@ -2979,9 +2917,7 @@ impl Editor { pub fn outdent(&mut self, _: &Outdent, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = self - .selections - .interleaved::(&display_map.buffer_snapshot); + let selections = self.selections.interleaved::(cx); let mut deletion_ranges = Vec::new(); let mut last_outdent = None; { @@ -3024,18 +2960,17 @@ impl Editor { cx, ); }); - let snapshot = this.buffer.read(cx).snapshot(cx); this.change_selections(Some(Autoscroll::Fit), cx, |s| { - s.select(s.interleaved::(&snapshot)) + // TODO: Make sure this is a reasonable change + // This used to call select(local_selections) + s.refresh() }); }); } pub fn delete_line(&mut self, _: &DeleteLine, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = self - .selections - .interleaved::(&display_map.buffer_snapshot); + let selections = self.selections.interleaved::(cx); let mut new_cursors = Vec::new(); let mut edit_ranges = Vec::new(); @@ -3117,7 +3052,7 @@ impl Editor { pub fn duplicate_line(&mut self, _: &DuplicateLine, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = &display_map.buffer_snapshot; - let selections = self.selections.interleaved::(buffer); + let selections = self.selections.interleaved::(cx); let mut edits = Vec::new(); let mut selections_iter = selections.iter().peekable(); @@ -3162,7 +3097,7 @@ impl Editor { let mut unfold_ranges = Vec::new(); let mut refold_ranges = Vec::new(); - let selections = self.selections.interleaved::(&buffer); + let selections = self.selections.interleaved::(cx); let mut selections = selections.iter().peekable(); let mut contiguous_row_selections = Vec::new(); let mut new_selections = Vec::new(); @@ -3274,7 +3209,7 @@ impl Editor { let mut unfold_ranges = Vec::new(); let mut refold_ranges = Vec::new(); - let selections = self.selections.interleaved::(&buffer); + let selections = self.selections.interleaved::(cx); let mut selections = selections.iter().peekable(); let mut contiguous_row_selections = Vec::new(); let mut new_selections = Vec::new(); @@ -3412,9 +3347,10 @@ impl Editor { edits }); this.buffer.update(cx, |buffer, cx| buffer.edit(edits, cx)); - let buffer = this.buffer.read(cx).snapshot(cx); this.change_selections(Some(Autoscroll::Fit), cx, |s| { - s.select(s.interleaved::(&buffer)); + // TODO: Make sure this swap is reasonable. + // This was select(interleaved) + s.refresh(); }); }); } @@ -3422,7 +3358,7 @@ impl Editor { pub fn cut(&mut self, _: &Cut, cx: &mut ViewContext) { let mut text = String::new(); let buffer = self.buffer.read(cx).snapshot(cx); - let mut selections = self.selections.interleaved::(&buffer); + let mut selections = self.selections.interleaved::(cx); let mut clipboard_selections = Vec::with_capacity(selections.len()); { let max_point = buffer.max_point(); @@ -3455,8 +3391,8 @@ impl Editor { } pub fn copy(&mut self, _: &Copy, cx: &mut ViewContext) { + let selections = self.selections.interleaved::(cx); let buffer = self.buffer.read(cx).read(cx); - let selections = self.selections.interleaved::(&buffer); let mut text = String::new(); let mut clipboard_selections = Vec::with_capacity(selections.len()); { @@ -3489,9 +3425,7 @@ impl Editor { if let Some(item) = cx.as_mut().read_from_clipboard() { let mut clipboard_text = Cow::Borrowed(item.text()); if let Some(mut clipboard_selections) = item.metadata::>() { - let old_selections = this - .selections - .interleaved::(&this.buffer.read(cx).read(cx)); + let old_selections = this.selections.interleaved::(cx); let all_selections_were_entire_line = clipboard_selections.iter().all(|s| s.is_entire_line); if clipboard_selections.len() != old_selections.len() { @@ -3544,9 +3478,7 @@ impl Editor { buffer.edit_with_autoindent(edits, cx); }); - let selections = this - .selections - .interleaved::(&this.buffer.read(cx).read(cx)); + let selections = this.selections.interleaved::(cx); this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections)); } else { this.insert(&clipboard_text, cx); @@ -3970,9 +3902,7 @@ impl Editor { } pub fn select_to_beginning(&mut self, _: &SelectToBeginning, cx: &mut ViewContext) { - let mut selection = self - .selections - .last::(&self.buffer.read(cx).read(cx)); + let mut selection = self.selections.last::(cx); selection.set_head(Point::zero(), SelectionGoal::None); self.change_selections(Some(Autoscroll::Fit), cx, |s| { @@ -4031,7 +3961,7 @@ impl Editor { pub fn select_to_end(&mut self, _: &SelectToEnd, cx: &mut ViewContext) { let buffer = self.buffer.read(cx).snapshot(cx); - let mut selection = self.selections.first::(&buffer); + let mut selection = self.selections.first::(cx); selection.set_head(buffer.len(), SelectionGoal::None); self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.select(vec![selection]); @@ -4047,9 +3977,7 @@ impl Editor { pub fn select_line(&mut self, _: &SelectLine, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let mut selections = self - .selections - .interleaved::(&display_map.buffer_snapshot); + let mut selections = self.selections.interleaved::(cx); let max_point = display_map.buffer_snapshot.max_point(); for selection in &mut selections { let rows = selection.spanned_rows(true, &display_map); @@ -4070,8 +3998,8 @@ impl Editor { let mut to_unfold = Vec::new(); let mut new_selection_ranges = Vec::new(); { + let selections = self.selections.interleaved::(cx); let buffer = self.buffer.read(cx).read(cx); - let selections = self.selections.interleaved::(&buffer); for selection in selections { for row in selection.start.row..selection.end.row { let cursor = Point::new(row, buffer.line_len(row)); @@ -4098,9 +4026,7 @@ impl Editor { fn add_selection(&mut self, above: bool, cx: &mut ViewContext) { self.push_to_selection_history(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let mut selections = self - .selections - .interleaved::(&display_map.buffer_snapshot); + let mut selections = self.selections.interleaved::(cx); let mut state = self.add_selections_state.take().unwrap_or_else(|| { let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone(); let range = oldest_selection.display_range(&display_map).sorted(); @@ -4197,7 +4123,7 @@ impl Editor { self.push_to_selection_history(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = &display_map.buffer_snapshot; - let mut selections = self.selections.interleaved::(&buffer); + let mut selections = self.selections.interleaved::(cx); if let Some(mut select_next_state) = self.select_next_state.take() { let query = &select_next_state.query; if !select_next_state.done { @@ -4287,9 +4213,7 @@ impl Editor { pub fn toggle_comments(&mut self, _: &ToggleComments, cx: &mut ViewContext) { self.transact(cx, |this, cx| { - let mut selections = this - .selections - .interleaved::(&this.buffer.read(cx).snapshot(cx)); + let mut selections = this.selections.interleaved::(cx); let mut all_selection_lines_are_comments = true; let mut edit_ranges = Vec::new(); let mut last_toggled_row = None; @@ -4390,9 +4314,7 @@ impl Editor { } }); - let selections = this - .selections - .interleaved::(&this.buffer.read(cx).read(cx)); + let selections = this.selections.interleaved::(cx); this.change_selections(Some(Autoscroll::Fit), cx, |s| { s.select(selections); }); @@ -4406,10 +4328,7 @@ impl Editor { ) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = self.buffer.read(cx).snapshot(cx); - let old_selections = self - .selections - .interleaved::(&buffer) - .into_boxed_slice(); + let old_selections = self.selections.interleaved::(cx).into_boxed_slice(); let mut stack = mem::take(&mut self.select_larger_syntax_node_stack); let mut selected_larger_node = false; @@ -4469,7 +4388,7 @@ impl Editor { cx: &mut ViewContext, ) { let buffer = self.buffer.read(cx).snapshot(cx); - let mut selections = self.selections.interleaved::(&buffer); + let mut selections = self.selections.interleaved::(cx); for selection in &mut selections { if let Some((open_range, close_range)) = buffer.enclosing_bracket_ranges(selection.start..selection.end) @@ -4534,7 +4453,7 @@ impl Editor { pub fn go_to_diagnostic(&mut self, direction: Direction, cx: &mut ViewContext) { let buffer = self.buffer.read(cx).snapshot(cx); - let selection = self.selections.newest::(&buffer); + let selection = self.selections.newest::(cx); let mut active_primary_range = self.active_diagnostics.as_ref().map(|active_diagnostics| { active_diagnostics .primary_range @@ -4619,7 +4538,7 @@ impl Editor { let editor = editor_handle.read(cx); let buffer = editor.buffer.read(cx); - let head = editor.selections.newest::(&buffer.read(cx)).head(); + let head = editor.selections.newest::(cx).head(); let (buffer, head) = if let Some(text_anchor) = buffer.text_anchor_for_position(head, cx) { text_anchor } else { @@ -4666,7 +4585,7 @@ impl Editor { let editor = editor_handle.read(cx); let buffer = editor.buffer.read(cx); - let head = editor.selections.newest::(&buffer.read(cx)).head(); + let head = editor.selections.newest::(cx).head(); let (buffer, head) = buffer.text_anchor_for_position(head, cx)?; let replica_id = editor.replica_id(cx); @@ -4925,11 +4844,7 @@ impl Editor { if moving_cursor { let rename_editor = rename.editor.read(cx); - let rename_buffer = rename_editor.buffer.read(cx); - let cursor_in_rename_editor = rename_editor - .selections - .newest::(&rename_buffer.read(cx)) - .head(); + let cursor_in_rename_editor = rename_editor.selections.newest::(cx).head(); // Update the selection to match the position of the selection inside // the rename editor. @@ -5092,10 +5007,9 @@ impl Editor { cx: &mut ViewContext, ) { let old_cursor_position = self.selections.newest_anchor().head(); - self.selections - .change_with(self.display_map.clone(), self.buffer.clone(), cx, |s| { - s.select_anchors(selections); - }); + self.selections.change_with(cx, |s| { + s.select_anchors(selections); + }); self.selections_did_change(false, &old_cursor_position, cx); } @@ -5165,9 +5079,7 @@ impl Editor { let mut fold_ranges = Vec::new(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = self - .selections - .interleaved::(&display_map.buffer_snapshot); + let selections = self.selections.interleaved::(cx); for selection in selections { let range = selection.display_range(&display_map).sorted(); let buffer_start_row = range.start.to_point(&display_map).row; @@ -5191,7 +5103,7 @@ impl Editor { pub fn unfold_lines(&mut self, _: &UnfoldLines, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = &display_map.buffer_snapshot; - let selections = self.selections.interleaved::(buffer); + let selections = self.selections.interleaved::(cx); let ranges = selections .iter() .map(|s| { @@ -5249,9 +5161,7 @@ impl Editor { } pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext) { - let selections = self - .selections - .interleaved::(&self.buffer.read(cx).read(cx)); + let selections = self.selections.interleaved::(cx); let ranges = selections.into_iter().map(|s| s.start..s.end); self.fold_ranges(ranges, cx); } @@ -5628,7 +5538,7 @@ impl Editor { } let mut new_selections_by_buffer = HashMap::default(); - for selection in editor.selections.interleaved::(&buffer.read(cx)) { + for selection in editor.selections.interleaved::(cx) { for (buffer, mut range) in buffer.range_to_buffer_ranges(selection.start..selection.end, cx) { @@ -6322,14 +6232,14 @@ mod tests { editor.insert("cd", cx); editor.end_transaction_at(now, cx); assert_eq!(editor.text(cx), "12cd56"); - assert_eq!(editor.selected_ranges(cx), vec![4..4]); + assert_eq!(editor.selections.selected_ranges(cx), vec![4..4]); editor.start_transaction_at(now, cx); editor.change_selections(None, cx, |s| s.select_ranges([4..5])); editor.insert("e", cx); editor.end_transaction_at(now, cx); assert_eq!(editor.text(cx), "12cde6"); - assert_eq!(editor.selected_ranges(cx), vec![5..5]); + assert_eq!(editor.selections.selected_ranges(cx), vec![5..5]); now += group_interval + Duration::from_millis(1); editor.change_selections(None, cx, |s| s.select_ranges([2..2])); @@ -6343,30 +6253,30 @@ mod tests { }); assert_eq!(editor.text(cx), "ab2cde6"); - assert_eq!(editor.selected_ranges(cx), vec![3..3]); + assert_eq!(editor.selections.selected_ranges(cx), vec![3..3]); // Last transaction happened past the group interval in a different editor. // Undo it individually and don't restore selections. editor.undo(&Undo, cx); assert_eq!(editor.text(cx), "12cde6"); - assert_eq!(editor.selected_ranges(cx), vec![2..2]); + assert_eq!(editor.selections.selected_ranges(cx), vec![2..2]); // First two transactions happened within the group interval in this editor. // Undo them together and restore selections. editor.undo(&Undo, cx); editor.undo(&Undo, cx); // Undo stack is empty here, so this is a no-op. assert_eq!(editor.text(cx), "123456"); - assert_eq!(editor.selected_ranges(cx), vec![0..0]); + assert_eq!(editor.selections.selected_ranges(cx), vec![0..0]); // Redo the first two transactions together. editor.redo(&Redo, cx); assert_eq!(editor.text(cx), "12cde6"); - assert_eq!(editor.selected_ranges(cx), vec![5..5]); + assert_eq!(editor.selections.selected_ranges(cx), vec![5..5]); // Redo the last transaction on its own. editor.redo(&Redo, cx); assert_eq!(editor.text(cx), "ab2cde6"); - assert_eq!(editor.selected_ranges(cx), vec![6..6]); + assert_eq!(editor.selections.selected_ranges(cx), vec![6..6]); // Test empty transactions. editor.start_transaction_at(now, cx); @@ -6386,7 +6296,7 @@ mod tests { view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx); }); assert_eq!( - editor.update(cx, |view, cx| view.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)] ); @@ -6395,7 +6305,7 @@ mod tests { }); assert_eq!( - editor.update(cx, |view, cx| view.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)] ); @@ -6404,7 +6314,7 @@ mod tests { }); assert_eq!( - editor.update(cx, |view, cx| view.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)] ); @@ -6414,7 +6324,7 @@ mod tests { }); assert_eq!( - editor.update(cx, |view, cx| view.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)] ); @@ -6424,7 +6334,7 @@ mod tests { }); assert_eq!( - editor.update(cx, |view, cx| view.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), [ DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0) @@ -6436,7 +6346,7 @@ mod tests { }); assert_eq!( - editor.update(cx, |view, cx| view.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), [DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0)] ); } @@ -6450,7 +6360,7 @@ mod tests { view.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)] ); }); @@ -6458,7 +6368,7 @@ mod tests { view.update(cx, |view, cx| { view.update_selection(DisplayPoint::new(3, 3), 0, Vector2F::zero(), cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)] ); }); @@ -6467,7 +6377,7 @@ mod tests { view.cancel(&Cancel, cx); view.update_selection(DisplayPoint::new(1, 1), 0, Vector2F::zero(), cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)] ); }); @@ -6503,7 +6413,7 @@ mod tests { editor.navigate(nav_entry.data.unwrap(), cx); assert_eq!(nav_entry.item.id(), cx.view_id()); assert_eq!( - editor.selected_display_ranges(cx), + editor.selections.selected_display_ranges(cx), &[DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)] ); assert!(nav_history.borrow_mut().pop_backward().is_none()); @@ -6513,7 +6423,7 @@ mod tests { editor.begin_selection(DisplayPoint::new(5, 0), false, 1, cx); editor.end_selection(cx); assert_eq!( - editor.selected_display_ranges(cx), + editor.selections.selected_display_ranges(cx), &[DisplayPoint::new(5, 0)..DisplayPoint::new(5, 0)] ); assert!(nav_history.borrow_mut().pop_backward().is_none()); @@ -6523,14 +6433,14 @@ mod tests { editor.begin_selection(DisplayPoint::new(15, 0), false, 1, cx); editor.end_selection(cx); assert_eq!( - editor.selected_display_ranges(cx), + editor.selections.selected_display_ranges(cx), &[DisplayPoint::new(15, 0)..DisplayPoint::new(15, 0)] ); let nav_entry = nav_history.borrow_mut().pop_backward().unwrap(); editor.navigate(nav_entry.data.unwrap(), cx); assert_eq!(nav_entry.item.id(), cx.view_id()); assert_eq!( - editor.selected_display_ranges(cx), + editor.selections.selected_display_ranges(cx), &[DisplayPoint::new(5, 0)..DisplayPoint::new(5, 0)] ); assert!(nav_history.borrow_mut().pop_backward().is_none()); @@ -6566,7 +6476,7 @@ mod tests { cx, ); assert_eq!( - editor.selected_display_ranges(cx), + editor.selections.selected_display_ranges(cx), &[editor.max_point(cx)..editor.max_point(cx)] ); assert_eq!( @@ -6593,7 +6503,7 @@ mod tests { view.update_selection(DisplayPoint::new(0, 3), 0, Vector2F::zero(), cx); view.end_selection(cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1), @@ -6604,7 +6514,7 @@ mod tests { view.update(cx, |view, cx| { view.cancel(&Cancel, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), [DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1)] ); }); @@ -6612,7 +6522,7 @@ mod tests { view.update(cx, |view, cx| { view.cancel(&Cancel, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), [DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1)] ); }); @@ -6723,43 +6633,43 @@ mod tests { view.update(cx, |view, cx| { assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4)] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)] ); view.move_up(&MoveUp, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] ); view.move_to_end(&MoveToEnd, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(5, 6)..DisplayPoint::new(5, 6)] ); view.move_to_beginning(&MoveToBeginning, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] ); @@ -6768,13 +6678,13 @@ mod tests { }); view.select_to_beginning(&SelectToBeginning, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 0)] ); view.select_to_end(&SelectToEnd, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(0, 1)..DisplayPoint::new(5, 6)] ); }); @@ -6802,80 +6712,80 @@ mod tests { view.move_right(&MoveRight, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(0, "ⓐ".len())] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(0, "ⓐⓑ".len())] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(0, "ⓐⓑ…".len())] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(1, "ab…".len())] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(1, "ab".len())] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(1, "a".len())] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(2, "α".len())] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(2, "αβ".len())] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(2, "αβ…".len())] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(2, "αβ…ε".len())] ); view.move_up(&MoveUp, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(1, "ab…e".len())] ); view.move_up(&MoveUp, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(0, "ⓐⓑ…ⓔ".len())] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(0, "ⓐⓑ…".len())] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(0, "ⓐⓑ".len())] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(0, "ⓐ".len())] ); }); @@ -6892,37 +6802,37 @@ mod tests { }); view.move_down(&MoveDown, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(1, "abcd".len())] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(2, "αβγ".len())] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(3, "abcd".len())] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(4, "ⓐⓑⓒⓓⓔ".len())] ); view.move_up(&MoveUp, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(3, "abcd".len())] ); view.move_up(&MoveUp, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[empty_range(2, "αβγ".len())] ); }); @@ -6945,7 +6855,7 @@ mod tests { view.update(cx, |view, cx| { view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), @@ -6956,7 +6866,7 @@ mod tests { view.update(cx, |view, cx| { view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), @@ -6967,7 +6877,7 @@ mod tests { view.update(cx, |view, cx| { view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), @@ -6978,7 +6888,7 @@ mod tests { view.update(cx, |view, cx| { view.move_to_end_of_line(&MoveToEndOfLine, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5), @@ -6990,7 +6900,7 @@ mod tests { view.update(cx, |view, cx| { view.move_to_end_of_line(&MoveToEndOfLine, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5), @@ -7007,7 +6917,7 @@ mod tests { cx, ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2), @@ -7023,7 +6933,7 @@ mod tests { cx, ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 0), @@ -7039,7 +6949,7 @@ mod tests { cx, ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2), @@ -7055,7 +6965,7 @@ mod tests { cx, ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 5), @@ -7067,7 +6977,7 @@ mod tests { view.delete_to_end_of_line(&DeleteToEndOfLine, cx); assert_eq!(view.display_text(cx), "ab\n de"); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4), @@ -7079,7 +6989,7 @@ mod tests { view.delete_to_beginning_of_line(&DeleteToBeginningOfLine, cx); assert_eq!(view.display_text(cx), "\n"); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), @@ -7211,37 +7121,37 @@ mod tests { view.move_to_next_word_end(&MoveToNextWordEnd, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(1, 9)..DisplayPoint::new(1, 9)] ); view.move_to_next_word_end(&MoveToNextWordEnd, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(1, 14)..DisplayPoint::new(1, 14)] ); view.move_to_next_word_end(&MoveToNextWordEnd, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4)] ); view.move_to_next_word_end(&MoveToNextWordEnd, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(2, 8)..DisplayPoint::new(2, 8)] ); view.move_to_previous_word_start(&MoveToPreviousWordStart, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4)] ); view.move_to_previous_word_start(&MoveToPreviousWordStart, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(1, 14)..DisplayPoint::new(1, 14)] ); }); @@ -7368,7 +7278,7 @@ mod tests { editor.update(cx, |editor, cx| { assert_eq!( - editor.selected_ranges(cx), + editor.selections.selected_ranges(cx), &[ Point::new(1, 2)..Point::new(1, 2), Point::new(2, 2)..Point::new(2, 2), @@ -7390,7 +7300,7 @@ mod tests { // The selections are moved after the inserted newlines assert_eq!( - editor.selected_ranges(cx), + editor.selections.selected_ranges(cx), &[ Point::new(2, 0)..Point::new(2, 0), Point::new(4, 0)..Point::new(4, 0), @@ -7416,13 +7326,13 @@ mod tests { }); editor.update(cx, |editor, cx| { - assert_eq!(editor.selected_ranges(cx), &[2..2, 7..7, 12..12],); + assert_eq!(editor.selections.selected_ranges(cx), &[2..2, 7..7, 12..12],); editor.insert("Z", cx); assert_eq!(editor.text(cx), "a(Z), b(Z), c(Z)"); // The selections are moved after the inserted characters - assert_eq!(editor.selected_ranges(cx), &[3..3, 9..9, 15..15],); + assert_eq!(editor.selections.selected_ranges(cx), &[3..3, 9..9, 15..15],); }); } @@ -7731,7 +7641,7 @@ mod tests { view.delete_line(&DeleteLine, cx); assert_eq!(view.display_text(cx), "ghi"); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1) @@ -7749,7 +7659,7 @@ mod tests { view.delete_line(&DeleteLine, cx); assert_eq!(view.display_text(cx), "ghi\n"); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)] ); }); @@ -7772,7 +7682,7 @@ mod tests { view.duplicate_line(&DuplicateLine, cx); assert_eq!(view.display_text(cx), "abc\nabc\ndef\ndef\nghi\n\n"); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1), DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), @@ -7794,7 +7704,7 @@ mod tests { view.duplicate_line(&DuplicateLine, cx); assert_eq!(view.display_text(cx), "abc\ndef\nghi\nabc\ndef\nghi\n"); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(3, 1)..DisplayPoint::new(4, 1), DisplayPoint::new(4, 2)..DisplayPoint::new(5, 1), @@ -7836,7 +7746,7 @@ mod tests { "aa…bbb\nccc…eeee\nggggg\n…i\njjjjj\nfffff" ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), @@ -7853,7 +7763,7 @@ mod tests { "ccc…eeee\naa…bbb\nfffff\nggggg\n…i\njjjjj" ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1), @@ -7870,7 +7780,7 @@ mod tests { "ccc…eeee\nfffff\naa…bbb\nggggg\n…i\njjjjj" ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1), @@ -7887,7 +7797,7 @@ mod tests { "ccc…eeee\naa…bbb\nggggg\n…i\njjjjj\nfffff" ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), @@ -7931,15 +7841,15 @@ mod tests { editor.change_selections(None, cx, |s| s.select_ranges([1..1])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bac"); - assert_eq!(editor.selected_ranges(cx), [2..2]); + assert_eq!(editor.selections.selected_ranges(cx), [2..2]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bca"); - assert_eq!(editor.selected_ranges(cx), [3..3]); + assert_eq!(editor.selections.selected_ranges(cx), [3..3]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bac"); - assert_eq!(editor.selected_ranges(cx), [3..3]); + assert_eq!(editor.selections.selected_ranges(cx), [3..3]); editor }) @@ -7951,20 +7861,20 @@ mod tests { editor.change_selections(None, cx, |s| s.select_ranges([3..3])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acb\nde"); - assert_eq!(editor.selected_ranges(cx), [3..3]); + assert_eq!(editor.selections.selected_ranges(cx), [3..3]); editor.change_selections(None, cx, |s| s.select_ranges([4..4])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acbd\ne"); - assert_eq!(editor.selected_ranges(cx), [5..5]); + assert_eq!(editor.selections.selected_ranges(cx), [5..5]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acbde\n"); - assert_eq!(editor.selected_ranges(cx), [6..6]); + assert_eq!(editor.selections.selected_ranges(cx), [6..6]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acbd\ne"); - assert_eq!(editor.selected_ranges(cx), [6..6]); + assert_eq!(editor.selections.selected_ranges(cx), [6..6]); editor }) @@ -7976,23 +7886,23 @@ mod tests { editor.change_selections(None, cx, |s| s.select_ranges([1..1, 2..2, 4..4])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bacd\ne"); - assert_eq!(editor.selected_ranges(cx), [2..2, 3..3, 5..5]); + assert_eq!(editor.selections.selected_ranges(cx), [2..2, 3..3, 5..5]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bcade\n"); - assert_eq!(editor.selected_ranges(cx), [3..3, 4..4, 6..6]); + assert_eq!(editor.selections.selected_ranges(cx), [3..3, 4..4, 6..6]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bcda\ne"); - assert_eq!(editor.selected_ranges(cx), [4..4, 6..6]); + assert_eq!(editor.selections.selected_ranges(cx), [4..4, 6..6]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bcade\n"); - assert_eq!(editor.selected_ranges(cx), [4..4, 6..6]); + assert_eq!(editor.selections.selected_ranges(cx), [4..4, 6..6]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bcaed\n"); - assert_eq!(editor.selected_ranges(cx), [5..5, 6..6]); + assert_eq!(editor.selections.selected_ranges(cx), [5..5, 6..6]); editor }) @@ -8004,15 +7914,15 @@ mod tests { editor.change_selections(None, cx, |s| s.select_ranges([4..4])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "🏀🍐✋"); - assert_eq!(editor.selected_ranges(cx), [8..8]); + assert_eq!(editor.selections.selected_ranges(cx), [8..8]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "🏀✋🍐"); - assert_eq!(editor.selected_ranges(cx), [11..11]); + assert_eq!(editor.selections.selected_ranges(cx), [11..11]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "🏀🍐✋"); - assert_eq!(editor.selected_ranges(cx), [11..11]); + assert_eq!(editor.selections.selected_ranges(cx), [11..11]); editor }) @@ -8040,7 +7950,7 @@ mod tests { view.paste(&Paste, cx); assert_eq!(view.display_text(cx), "two one✅ four three six five "); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 11)..DisplayPoint::new(0, 11), DisplayPoint::new(0, 22)..DisplayPoint::new(0, 22), @@ -8104,7 +8014,7 @@ mod tests { "123\n4567\n9\n( 8ne✅ \nthree \nfive ) two one✅ four three six five ( one✅ \nthree \nfive ) " ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), @@ -8137,7 +8047,7 @@ mod tests { "123\n123\n123\n67\n123\n9\n( 8ne✅ \nthree \nfive ) two one✅ four three six five ( one✅ \nthree \nfive ) " ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[ DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0), @@ -8155,7 +8065,7 @@ mod tests { view.update(cx, |view, cx| { view.select_all(&SelectAll, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(2, 3)] ); }); @@ -8177,7 +8087,7 @@ mod tests { }); view.select_line(&SelectLine, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(0, 0)..DisplayPoint::new(2, 0), DisplayPoint::new(4, 0)..DisplayPoint::new(5, 0), @@ -8188,7 +8098,7 @@ mod tests { view.update(cx, |view, cx| { view.select_line(&SelectLine, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(0, 0)..DisplayPoint::new(3, 0), DisplayPoint::new(4, 0)..DisplayPoint::new(5, 5), @@ -8199,7 +8109,7 @@ mod tests { view.update(cx, |view, cx| { view.select_line(&SelectLine, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![DisplayPoint::new(0, 0)..DisplayPoint::new(5, 5)] ); }); @@ -8237,7 +8147,7 @@ mod tests { "aaaaa\nbbbbb\nccc…eeee\nfffff\nggggg\n…i" ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), @@ -8257,7 +8167,7 @@ mod tests { "aaaaa\nbbbbb\nccccc\nddddd\neeeee\nfffff\nggggg\nhhhhh\niiiii" ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), [ DisplayPoint::new(0, 5)..DisplayPoint::new(0, 5), DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5), @@ -8286,7 +8196,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3) @@ -8297,7 +8207,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3) @@ -8308,13 +8218,13 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)] ); view.undo_selection(&UndoSelection, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3) @@ -8323,7 +8233,7 @@ mod tests { view.redo_selection(&RedoSelection, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)] ); }); @@ -8331,7 +8241,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 3)..DisplayPoint::new(4, 3) @@ -8342,7 +8252,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 3)..DisplayPoint::new(4, 3) @@ -8358,7 +8268,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 4)..DisplayPoint::new(4, 3) @@ -8369,7 +8279,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 4)..DisplayPoint::new(4, 3) @@ -8380,7 +8290,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)] ); }); @@ -8388,7 +8298,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)] ); }); @@ -8399,7 +8309,7 @@ mod tests { }); view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4), @@ -8411,7 +8321,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4), @@ -8424,7 +8334,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4), @@ -8441,7 +8351,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 3)..DisplayPoint::new(1, 1), @@ -8454,7 +8364,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), vec![ DisplayPoint::new(1, 3)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 2)..DisplayPoint::new(3, 1), @@ -8482,7 +8392,7 @@ mod tests { }, cx, ); - assert_eq!(view.selected_ranges(cx), &ranges[1..2]); + assert_eq!(view.selections.selected_ranges(cx), &ranges[1..2]); view.select_next( &SelectNext { @@ -8490,13 +8400,13 @@ mod tests { }, cx, ); - assert_eq!(view.selected_ranges(cx), &ranges[1..3]); + assert_eq!(view.selections.selected_ranges(cx), &ranges[1..3]); view.undo_selection(&UndoSelection, cx); - assert_eq!(view.selected_ranges(cx), &ranges[1..2]); + assert_eq!(view.selections.selected_ranges(cx), &ranges[1..2]); view.redo_selection(&RedoSelection, cx); - assert_eq!(view.selected_ranges(cx), &ranges[1..3]); + assert_eq!(view.selections.selected_ranges(cx), &ranges[1..3]); view.select_next( &SelectNext { @@ -8504,7 +8414,7 @@ mod tests { }, cx, ); - assert_eq!(view.selected_ranges(cx), &ranges[1..4]); + assert_eq!(view.selections.selected_ranges(cx), &ranges[1..4]); view.select_next( &SelectNext { @@ -8512,7 +8422,7 @@ mod tests { }, cx, ); - assert_eq!(view.selected_ranges(cx), &ranges[0..4]); + assert_eq!(view.selections.selected_ranges(cx), &ranges[0..4]); }); } @@ -8550,7 +8460,9 @@ mod tests { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selected_display_ranges(cx)), + view.update(cx, |view, cx| { + view.selections.selected_display_ranges(cx) + }), &[ DisplayPoint::new(0, 23)..DisplayPoint::new(0, 27), DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7), @@ -8562,7 +8474,7 @@ mod tests { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), &[ DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28), DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0), @@ -8573,7 +8485,7 @@ mod tests { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), &[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)] ); @@ -8582,7 +8494,7 @@ mod tests { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), &[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)] ); @@ -8590,7 +8502,7 @@ mod tests { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), &[ DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28), DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0), @@ -8601,7 +8513,7 @@ mod tests { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), &[ DisplayPoint::new(0, 23)..DisplayPoint::new(0, 27), DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7), @@ -8613,7 +8525,7 @@ mod tests { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), &[ DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25), DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12), @@ -8626,7 +8538,7 @@ mod tests { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), &[ DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25), DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12), @@ -8647,7 +8559,7 @@ mod tests { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), &[ DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28), DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7), @@ -8703,7 +8615,7 @@ mod tests { editor.newline(&Newline, cx); assert_eq!(editor.text(cx), "fn a(\n \n) {\n \n}\n"); assert_eq!( - editor.selected_ranges(cx), + editor.selections.selected_ranges(cx), &[ Point::new(1, 4)..Point::new(1, 4), Point::new(3, 4)..Point::new(3, 4), @@ -8856,7 +8768,7 @@ mod tests { .unindent() ); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), [DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2)] ); }); @@ -8886,7 +8798,10 @@ mod tests { marked_text_ranges_by(marked_text_ranges, vec![range_markers.clone()]); let selection_ranges = selection_ranges_lookup.remove(&range_markers).unwrap(); assert_eq!(editor.text(cx), expected_text); - assert_eq!(editor.selected_ranges::(cx), selection_ranges); + assert_eq!( + editor.selections.selected_ranges::(cx), + selection_ranges + ); } assert( editor, @@ -9420,7 +9335,7 @@ mod tests { view.handle_input(&Input("X".to_string()), cx); assert_eq!(view.text(cx), "Xaaaa\nXbbbb"); assert_eq!( - view.selected_ranges(cx), + view.selections.selected_ranges(cx), [ Point::new(0, 1)..Point::new(0, 1), Point::new(1, 1)..Point::new(1, 1), @@ -9461,7 +9376,7 @@ mod tests { bX|bbX|b cccc"}); assert_eq!(view.text(cx), expected_text); - assert_eq!(view.selected_ranges(cx), expected_selections); + assert_eq!(view.selections.selected_ranges(cx), expected_selections); view.newline(&Newline, cx); let (expected_text, expected_selections) = marked_text_ranges(indoc! {" @@ -9474,7 +9389,7 @@ mod tests { |b cccc"}); assert_eq!(view.text(cx), expected_text); - assert_eq!(view.selected_ranges(cx), expected_selections); + assert_eq!(view.selections.selected_ranges(cx), expected_selections); }); } @@ -9510,7 +9425,7 @@ mod tests { }); editor.begin_selection(Point::new(2, 1).to_display_point(&snapshot), true, 1, cx); assert_eq!( - editor.selected_ranges(cx), + editor.selections.selected_ranges(cx), [ Point::new(1, 3)..Point::new(1, 3), Point::new(2, 1)..Point::new(2, 1), @@ -9525,7 +9440,7 @@ mod tests { s.refresh(); }); assert_eq!( - editor.selected_ranges(cx), + editor.selections.selected_ranges(cx), [ Point::new(1, 3)..Point::new(1, 3), Point::new(2, 1)..Point::new(2, 1), @@ -9539,7 +9454,7 @@ mod tests { editor.update(cx, |editor, cx| { // Removing an excerpt causes the first selection to become degenerate. assert_eq!( - editor.selected_ranges(cx), + editor.selections.selected_ranges(cx), [ Point::new(0, 0)..Point::new(0, 0), Point::new(0, 1)..Point::new(0, 1) @@ -9552,7 +9467,7 @@ mod tests { s.refresh(); }); assert_eq!( - editor.selected_ranges(cx), + editor.selections.selected_ranges(cx), [ Point::new(0, 1)..Point::new(0, 1), Point::new(0, 3)..Point::new(0, 3) @@ -9591,7 +9506,7 @@ mod tests { let snapshot = editor.snapshot(cx); editor.begin_selection(Point::new(1, 3).to_display_point(&snapshot), false, 1, cx); assert_eq!( - editor.selected_ranges(cx), + editor.selections.selected_ranges(cx), [Point::new(1, 3)..Point::new(1, 3)] ); editor @@ -9602,7 +9517,7 @@ mod tests { }); editor.update(cx, |editor, cx| { assert_eq!( - editor.selected_ranges(cx), + editor.selections.selected_ranges(cx), [Point::new(0, 0)..Point::new(0, 0)] ); @@ -9611,7 +9526,7 @@ mod tests { s.refresh(); }); assert_eq!( - editor.selected_ranges(cx), + editor.selections.selected_ranges(cx), [Point::new(0, 3)..Point::new(0, 3)] ); assert!(editor.selections.pending_anchor().is_some()); @@ -9803,7 +9718,7 @@ mod tests { .apply_update_proto(pending_update.borrow_mut().take().unwrap(), cx) .unwrap(); }); - assert_eq!(follower.read(cx).selected_ranges(cx), vec![1..1]); + assert_eq!(follower.read(cx).selections.selected_ranges(cx), vec![1..1]); // Update the scroll position only leader.update(cx, |leader, cx| { @@ -9833,7 +9748,7 @@ mod tests { assert_eq!(follower.scroll_position(cx), initial_scroll_position); assert!(follower.autoscroll_request.is_some()); }); - assert_eq!(follower.read(cx).selected_ranges(cx), vec![0..0]); + assert_eq!(follower.read(cx).selections.selected_ranges(cx), vec![0..0]); // Creating a pending selection that precedes another selection leader.update(cx, |leader, cx| { @@ -9845,7 +9760,10 @@ mod tests { .apply_update_proto(pending_update.borrow_mut().take().unwrap(), cx) .unwrap(); }); - assert_eq!(follower.read(cx).selected_ranges(cx), vec![0..0, 1..1]); + assert_eq!( + follower.read(cx).selections.selected_ranges(cx), + vec![0..0, 1..1] + ); // Extend the pending selection so that it surrounds another selection leader.update(cx, |leader, cx| { @@ -9856,7 +9774,7 @@ mod tests { .apply_update_proto(pending_update.borrow_mut().take().unwrap(), cx) .unwrap(); }); - assert_eq!(follower.read(cx).selected_ranges(cx), vec![0..2]); + assert_eq!(follower.read(cx).selections.selected_ranges(cx), vec![0..2]); } #[test] @@ -9959,7 +9877,7 @@ mod tests { }) .collect(); assert_eq!( - view.selected_display_ranges(cx), + view.selections.selected_display_ranges(cx), &asserted_ranges[..], "Assert selections are {}", marked_text diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index dcef624d01..06c11db137 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -959,7 +959,7 @@ impl Element for EditorElement { if view.show_local_selections { let local_selections = view .selections - .interleaved_in_range(start_anchor..end_anchor, &display_map.buffer_snapshot); + .interleaved_in_range(start_anchor..end_anchor, cx); for selection in &local_selections { let is_empty = selection.start == selection.end; let selection_start = snapshot.prev_line_boundary(selection.start).1; @@ -1043,7 +1043,7 @@ impl Element for EditorElement { let newest_selection_head = view .selections - .newest::(&snapshot.buffer_snapshot) + .newest::(cx) .head() .to_display_point(&snapshot); diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 1652334b38..165f4ca676 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -252,13 +252,13 @@ fn deserialize_selection( impl Item for Editor { fn navigate(&mut self, data: Box, cx: &mut ViewContext) -> bool { if let Ok(data) = data.downcast::() { + let newest_selection = self.selections.newest::(cx); let buffer = self.buffer.read(cx).read(cx); let offset = if buffer.can_resolve(&data.cursor_anchor) { data.cursor_anchor.to_point(&buffer) } else { buffer.clip_point(data.cursor_position, Bias::Left) }; - let newest_selection = self.selections.newest::(&buffer); let scroll_top_anchor = if buffer.can_resolve(&data.scroll_top_anchor) { data.scroll_top_anchor @@ -465,7 +465,7 @@ impl CursorPosition { self.selected_count = 0; let mut last_selection: Option> = None; - for selection in editor.selections.interleaved::(&buffer) { + for selection in editor.selections.interleaved::(cx) { self.selected_count += selection.end - selection.start; if last_selection .as_ref() diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs index cbe4f0fbef..a5fac015d6 100644 --- a/crates/editor/src/selections_collection.rs +++ b/crates/editor/src/selections_collection.rs @@ -5,7 +5,7 @@ use std::{ }; use collections::HashMap; -use gpui::{ModelHandle, MutableAppContext}; +use gpui::{AppContext, ModelHandle, MutableAppContext}; use itertools::Itertools; use language::{rope::TextDimension, Bias, Point, Selection, SelectionGoal, ToPoint}; use util::post_inc; @@ -22,14 +22,18 @@ pub struct PendingSelection { } pub struct SelectionsCollection { + display_map: ModelHandle, + buffer: ModelHandle, pub next_selection_id: usize, disjoint: Arc<[Selection]>, pending: Option, } impl SelectionsCollection { - pub fn new() -> Self { + pub fn new(display_map: ModelHandle, buffer: ModelHandle) -> Self { Self { + display_map, + buffer, next_selection_id: 1, disjoint: Arc::from([]), pending: Some(PendingSelection { @@ -45,6 +49,14 @@ impl SelectionsCollection { } } + fn display_map(&self, cx: &mut MutableAppContext) -> DisplaySnapshot { + self.display_map.update(cx, |map, cx| map.snapshot(cx)) + } + + fn buffer(&self, cx: &AppContext) -> MultiBufferSnapshot { + self.buffer.read(cx).snapshot(cx) + } + pub fn count<'a>(&self) -> usize { let mut count = self.disjoint.len(); if self.pending.is_some() { @@ -65,25 +77,26 @@ impl SelectionsCollection { pub fn pending>( &self, - snapshot: &MultiBufferSnapshot, + cx: &AppContext, ) -> Option> { self.pending_anchor() .as_ref() - .map(|pending| pending.map(|p| p.summary::(&snapshot))) + .map(|pending| pending.map(|p| p.summary::(&self.buffer(cx)))) } pub fn pending_mode(&self) -> Option { self.pending.as_ref().map(|pending| pending.mode.clone()) } - pub fn interleaved<'a, D>(&self, buffer: &MultiBufferSnapshot) -> Vec> + pub fn interleaved<'a, D>(&self, cx: &AppContext) -> Vec> where D: 'a + TextDimension + Ord + Sub + std::fmt::Debug, { let disjoint_anchors = &self.disjoint; - let mut disjoint = resolve_multiple::(disjoint_anchors.iter(), &buffer).peekable(); + let mut disjoint = + resolve_multiple::(disjoint_anchors.iter(), &self.buffer(cx)).peekable(); - let mut pending_opt = self.pending::(&buffer); + let mut pending_opt = self.pending::(cx); iter::from_fn(move || { if let Some(pending) = pending_opt.as_mut() { @@ -114,8 +127,9 @@ impl SelectionsCollection { pub fn interleaved_in_range<'a>( &self, range: Range, - buffer: &MultiBufferSnapshot, + cx: &AppContext, ) -> Vec> { + let buffer = self.buffer(cx); let start_ix = match self .disjoint .binary_search_by(|probe| probe.end.cmp(&range.start, &buffer)) @@ -162,9 +176,9 @@ impl SelectionsCollection { pub fn newest>( &self, - snapshot: &MultiBufferSnapshot, + cx: &AppContext, ) -> Selection { - resolve(self.newest_anchor(), snapshot) + resolve(self.newest_anchor(), &self.buffer(cx)) } pub fn oldest_anchor(&self) -> &Selection { @@ -177,36 +191,65 @@ impl SelectionsCollection { pub fn oldest>( &self, - snapshot: &MultiBufferSnapshot, + cx: &AppContext, ) -> Selection { - resolve(self.oldest_anchor(), snapshot) + resolve(self.oldest_anchor(), &self.buffer(cx)) } pub fn first>( &self, - snapshot: &MultiBufferSnapshot, + cx: &AppContext, ) -> Selection { - self.interleaved(&snapshot).first().unwrap().clone() + self.interleaved(cx).first().unwrap().clone() } pub fn last>( &self, - snapshot: &MultiBufferSnapshot, + cx: &AppContext, ) -> Selection { - self.interleaved(&snapshot).last().unwrap().clone() + self.interleaved(cx).last().unwrap().clone() + } + + #[cfg(any(test, feature = "test-support"))] + pub fn selected_ranges + std::fmt::Debug>( + &self, + cx: &AppContext, + ) -> Vec> { + self.interleaved::(cx) + .iter() + .map(|s| { + if s.reversed { + s.end.clone()..s.start.clone() + } else { + s.start.clone()..s.end.clone() + } + }) + .collect() + } + + #[cfg(any(test, feature = "test-support"))] + pub fn selected_display_ranges(&self, cx: &mut MutableAppContext) -> Vec> { + let display_map = self.display_map(cx); + self.disjoint_anchors() + .iter() + .chain(self.pending_anchor().as_ref()) + .map(|s| { + if s.reversed { + s.end.to_display_point(&display_map)..s.start.to_display_point(&display_map) + } else { + s.start.to_display_point(&display_map)..s.end.to_display_point(&display_map) + } + }) + .collect() } pub(crate) fn change_with( &mut self, - display_map: ModelHandle, - buffer: ModelHandle, cx: &mut MutableAppContext, change: impl FnOnce(&mut MutableSelectionsCollection) -> R, ) -> R { let mut mutable_collection = MutableSelectionsCollection { collection: self, - display_map, - buffer, cx, }; @@ -221,12 +264,18 @@ impl SelectionsCollection { pub struct MutableSelectionsCollection<'a> { collection: &'a mut SelectionsCollection, - buffer: ModelHandle, - display_map: ModelHandle, cx: &'a mut MutableAppContext, } impl<'a> MutableSelectionsCollection<'a> { + fn display_map(&mut self) -> DisplaySnapshot { + self.collection.display_map(self.cx) + } + + fn buffer(&mut self) -> MultiBufferSnapshot { + self.collection.buffer(self.cx) + } + pub fn clear_disjoint(&mut self) { self.collection.disjoint = Arc::from([]); } @@ -303,19 +352,11 @@ impl<'a> MutableSelectionsCollection<'a> { pub fn insert_range(&mut self, range: Range) where - T: 'a - + ToOffset - + ToPoint - + TextDimension - + Ord - + Sub - + std::marker::Copy - + std::fmt::Debug, + T: 'a + ToOffset + ToPoint + TextDimension + Ord + Sub + std::marker::Copy, { - let buffer = self.buffer.read(self.cx).snapshot(self.cx); - let mut selections = self.interleaved(&buffer); - let mut start = range.start.to_offset(&buffer); - let mut end = range.end.to_offset(&buffer); + let mut selections = self.interleaved(self.cx); + let mut start = range.start.to_offset(&self.buffer()); + let mut end = range.end.to_offset(&self.buffer()); let reversed = if start > end { mem::swap(&mut start, &mut end); true @@ -440,7 +481,7 @@ impl<'a> MutableSelectionsCollection<'a> { where T: IntoIterator>, { - let display_map = self.display_map.update(self.cx, |map, cx| map.snapshot(cx)); + let display_map = self.display_map(); let selections = ranges .into_iter() .map(|range| { @@ -468,9 +509,9 @@ impl<'a> MutableSelectionsCollection<'a> { &mut self, mut move_selection: impl FnMut(&DisplaySnapshot, &mut Selection), ) { - let display_map = self.display_map.update(self.cx, |map, cx| map.snapshot(cx)); + let display_map = self.display_map(); let selections = self - .interleaved::(&display_map.buffer_snapshot) + .interleaved::(self.cx) .into_iter() .map(|selection| { let mut selection = selection.map(|point| point.to_display_point(&display_map)); @@ -514,7 +555,7 @@ impl<'a> MutableSelectionsCollection<'a> { &mut self, mut find_replacement_cursors: impl FnMut(&DisplaySnapshot) -> Vec, ) { - let display_map = self.display_map.update(self.cx, |map, cx| map.snapshot(cx)); + let display_map = self.display_map(); let new_selections = find_replacement_cursors(&display_map) .into_iter() .map(|cursor| { diff --git a/crates/editor/src/test.rs b/crates/editor/src/test.rs index d707e55c3a..822b033dc3 100644 --- a/crates/editor/src/test.rs +++ b/crates/editor/src/test.rs @@ -54,5 +54,5 @@ pub fn assert_text_with_selections( let (unmarked_text, text_ranges) = marked_text_ranges(marked_text); assert_eq!(editor.text(cx), unmarked_text); - assert_eq!(editor.selected_ranges(cx), text_ranges); + assert_eq!(editor.selections.selected_ranges(cx), text_ranges); } diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index bb889a5b37..f71f0c02f6 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -43,7 +43,7 @@ impl GoToLine { let buffer = editor.buffer().read(cx).read(cx); ( Some(scroll_position), - editor.selections.newest(&buffer).head(), + editor.selections.newest(cx).head(), buffer.max_point(), ) }); diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 12f5168c9d..0687048713 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -172,7 +172,7 @@ impl PickerDelegate for OutlineView { let editor = self.active_editor.read(cx); let buffer = editor.buffer().read(cx).read(cx); - let cursor_offset = editor.selections.newest::(&buffer).head(); + let cursor_offset = editor.selections.newest::(cx).head(); selected_index = self .outline .items diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 00205b634c..2209578295 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -225,10 +225,7 @@ impl BufferSearchBar { let display_map = editor .update(cx, |editor, cx| editor.snapshot(cx)) .display_snapshot; - let selection = editor - .read(cx) - .selections - .newest::(&display_map.buffer_snapshot); + let selection = editor.read(cx).selections.newest::(cx); let mut text: String; if selection.start == selection.end { @@ -732,7 +729,9 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(0)); search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)] ); }); @@ -743,7 +742,9 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(3, 11)..DisplayPoint::new(3, 13)] ); }); @@ -754,7 +755,9 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)] ); }); @@ -765,7 +768,9 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)] ); }); @@ -776,7 +781,9 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)] ); }); @@ -787,7 +794,9 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(3, 11)..DisplayPoint::new(3, 13)] ); }); @@ -798,7 +807,9 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)] ); }); @@ -817,7 +828,9 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(1)); search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)] ); }); @@ -836,7 +849,9 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(1)); search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(3, 11)..DisplayPoint::new(3, 13)] ); }); @@ -855,7 +870,9 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(2)); search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)] ); }); @@ -874,7 +891,9 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(2)); search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)] ); }); @@ -893,7 +912,9 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(0)); search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor.selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)] ); }); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 8bd043f86b..cac8b449c7 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -891,7 +891,7 @@ mod tests { assert_eq!( search_view .results_editor - .update(cx, |editor, cx| editor.selected_display_ranges(cx)), + .update(cx, |editor, cx| editor.selections.selected_display_ranges(cx)), [DisplayPoint::new(2, 32)..DisplayPoint::new(2, 35)] ); @@ -901,9 +901,9 @@ mod tests { search_view.update(cx, |search_view, cx| { assert_eq!(search_view.active_match_index, Some(1)); assert_eq!( - search_view - .results_editor - .update(cx, |editor, cx| editor.selected_display_ranges(cx)), + search_view.results_editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(2, 37)..DisplayPoint::new(2, 40)] ); search_view.select_match(Direction::Next, cx); @@ -912,9 +912,9 @@ mod tests { search_view.update(cx, |search_view, cx| { assert_eq!(search_view.active_match_index, Some(2)); assert_eq!( - search_view - .results_editor - .update(cx, |editor, cx| editor.selected_display_ranges(cx)), + search_view.results_editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(5, 6)..DisplayPoint::new(5, 9)] ); search_view.select_match(Direction::Next, cx); @@ -923,9 +923,9 @@ mod tests { search_view.update(cx, |search_view, cx| { assert_eq!(search_view.active_match_index, Some(0)); assert_eq!( - search_view - .results_editor - .update(cx, |editor, cx| editor.selected_display_ranges(cx)), + search_view.results_editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(2, 32)..DisplayPoint::new(2, 35)] ); search_view.select_match(Direction::Prev, cx); @@ -934,9 +934,9 @@ mod tests { search_view.update(cx, |search_view, cx| { assert_eq!(search_view.active_match_index, Some(2)); assert_eq!( - search_view - .results_editor - .update(cx, |editor, cx| editor.selected_display_ranges(cx)), + search_view.results_editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(5, 6)..DisplayPoint::new(5, 9)] ); search_view.select_match(Direction::Prev, cx); @@ -945,9 +945,9 @@ mod tests { search_view.update(cx, |search_view, cx| { assert_eq!(search_view.active_match_index, Some(1)); assert_eq!( - search_view - .results_editor - .update(cx, |editor, cx| editor.selected_display_ranges(cx)), + search_view.results_editor.update(cx, |editor, cx| editor + .selections + .selected_display_ranges(cx)), [DisplayPoint::new(2, 37)..DisplayPoint::new(2, 40)] ); }); diff --git a/crates/vim/src/vim_test_context.rs b/crates/vim/src/vim_test_context.rs index 28c15ffacd..f68e3f26d9 100644 --- a/crates/vim/src/vim_test_context.rs +++ b/crates/vim/src/vim_test_context.rs @@ -200,7 +200,7 @@ impl<'a> VimTestContext<'a> { self.editor.read_with(self.cx, |editor, cx| { let (empty_selections, non_empty_selections): (Vec<_>, Vec<_>) = editor .selections - .interleaved::(&editor.buffer().read(cx).read(cx)) + .interleaved::(cx) .into_iter() .partition_map(|selection| { if selection.is_empty() { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 09d26517ba..a2fb6f740b 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1180,7 +1180,7 @@ mod tests { let editor = item.downcast::().unwrap(); let (selections, scroll_position) = editor.update(cx, |editor, cx| { ( - editor.selected_display_ranges(cx), + editor.selections.selected_display_ranges(cx), editor.scroll_position(cx), ) }); From c3a36e6d8af163e43e4aaf24d9b6852158b7541c Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Thu, 12 May 2022 16:04:27 -0700 Subject: [PATCH 13/18] Rename selected_ranges and selected_display_ranges to remove redundant selected --- crates/collab/src/rpc.rs | 8 +- crates/diagnostics/src/diagnostics.rs | 4 +- crates/editor/src/editor.rs | 320 ++++++++++----------- crates/editor/src/selections_collection.rs | 7 +- crates/editor/src/test.rs | 2 +- crates/search/src/buffer_search.rs | 48 +--- crates/search/src/project_search.rs | 32 +-- crates/zed/src/zed.rs | 2 +- 8 files changed, 197 insertions(+), 226 deletions(-) diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 2f182c1522..4bdb5459b1 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -5499,11 +5499,11 @@ mod tests { Some((worktree_id, "2.txt").into()) ); assert_eq!( - editor_b2.read_with(cx_b, |editor, cx| editor.selections.selected_ranges(cx)), + editor_b2.read_with(cx_b, |editor, cx| editor.selections.ranges(cx)), vec![2..3] ); assert_eq!( - editor_b1.read_with(cx_b, |editor, cx| editor.selections.selected_ranges(cx)), + editor_b1.read_with(cx_b, |editor, cx| editor.selections.ranges(cx)), vec![0..1] ); @@ -5546,7 +5546,7 @@ mod tests { }); editor_b1 .condition(cx_b, |editor, cx| { - editor.selections.selected_ranges(cx) == vec![1..1, 2..2] + editor.selections.ranges(cx) == vec![1..1, 2..2] }) .await; @@ -5561,7 +5561,7 @@ mod tests { }); editor_b1 .condition(cx_b, |editor, cx| { - editor.selections.selected_ranges(cx) == vec![3..3] + editor.selections.ranges(cx) == vec![3..3] }) .await; diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index d7eb089830..54fde4f4ad 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -897,7 +897,7 @@ mod tests { // Cursor is at the first diagnostic view.editor.update(cx, |editor, cx| { assert_eq!( - editor.selections.selected_display_ranges(cx), + editor.selections.display_ranges(cx), [DisplayPoint::new(12, 6)..DisplayPoint::new(12, 6)] ); }); @@ -998,7 +998,7 @@ mod tests { // Cursor keeps its position. view.editor.update(cx, |editor, cx| { assert_eq!( - editor.selections.selected_display_ranges(cx), + editor.selections.display_ranges(cx), [DisplayPoint::new(19, 6)..DisplayPoint::new(19, 6)] ); }); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 60570360dc..8c6cf33e09 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -6232,14 +6232,14 @@ mod tests { editor.insert("cd", cx); editor.end_transaction_at(now, cx); assert_eq!(editor.text(cx), "12cd56"); - assert_eq!(editor.selections.selected_ranges(cx), vec![4..4]); + assert_eq!(editor.selections.ranges(cx), vec![4..4]); editor.start_transaction_at(now, cx); editor.change_selections(None, cx, |s| s.select_ranges([4..5])); editor.insert("e", cx); editor.end_transaction_at(now, cx); assert_eq!(editor.text(cx), "12cde6"); - assert_eq!(editor.selections.selected_ranges(cx), vec![5..5]); + assert_eq!(editor.selections.ranges(cx), vec![5..5]); now += group_interval + Duration::from_millis(1); editor.change_selections(None, cx, |s| s.select_ranges([2..2])); @@ -6253,30 +6253,30 @@ mod tests { }); assert_eq!(editor.text(cx), "ab2cde6"); - assert_eq!(editor.selections.selected_ranges(cx), vec![3..3]); + assert_eq!(editor.selections.ranges(cx), vec![3..3]); // Last transaction happened past the group interval in a different editor. // Undo it individually and don't restore selections. editor.undo(&Undo, cx); assert_eq!(editor.text(cx), "12cde6"); - assert_eq!(editor.selections.selected_ranges(cx), vec![2..2]); + assert_eq!(editor.selections.ranges(cx), vec![2..2]); // First two transactions happened within the group interval in this editor. // Undo them together and restore selections. editor.undo(&Undo, cx); editor.undo(&Undo, cx); // Undo stack is empty here, so this is a no-op. assert_eq!(editor.text(cx), "123456"); - assert_eq!(editor.selections.selected_ranges(cx), vec![0..0]); + assert_eq!(editor.selections.ranges(cx), vec![0..0]); // Redo the first two transactions together. editor.redo(&Redo, cx); assert_eq!(editor.text(cx), "12cde6"); - assert_eq!(editor.selections.selected_ranges(cx), vec![5..5]); + assert_eq!(editor.selections.ranges(cx), vec![5..5]); // Redo the last transaction on its own. editor.redo(&Redo, cx); assert_eq!(editor.text(cx), "ab2cde6"); - assert_eq!(editor.selections.selected_ranges(cx), vec![6..6]); + assert_eq!(editor.selections.ranges(cx), vec![6..6]); // Test empty transactions. editor.start_transaction_at(now, cx); @@ -6296,7 +6296,7 @@ mod tests { view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx); }); assert_eq!( - editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.display_ranges(cx)), [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)] ); @@ -6305,7 +6305,7 @@ mod tests { }); assert_eq!( - editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.display_ranges(cx)), [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)] ); @@ -6314,7 +6314,7 @@ mod tests { }); assert_eq!( - editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.display_ranges(cx)), [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)] ); @@ -6324,7 +6324,7 @@ mod tests { }); assert_eq!( - editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.display_ranges(cx)), [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)] ); @@ -6334,7 +6334,7 @@ mod tests { }); assert_eq!( - editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.display_ranges(cx)), [ DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0) @@ -6346,7 +6346,7 @@ mod tests { }); assert_eq!( - editor.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + editor.update(cx, |view, cx| view.selections.display_ranges(cx)), [DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0)] ); } @@ -6360,7 +6360,7 @@ mod tests { view.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)] ); }); @@ -6368,7 +6368,7 @@ mod tests { view.update(cx, |view, cx| { view.update_selection(DisplayPoint::new(3, 3), 0, Vector2F::zero(), cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)] ); }); @@ -6377,7 +6377,7 @@ mod tests { view.cancel(&Cancel, cx); view.update_selection(DisplayPoint::new(1, 1), 0, Vector2F::zero(), cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)] ); }); @@ -6413,7 +6413,7 @@ mod tests { editor.navigate(nav_entry.data.unwrap(), cx); assert_eq!(nav_entry.item.id(), cx.view_id()); assert_eq!( - editor.selections.selected_display_ranges(cx), + editor.selections.display_ranges(cx), &[DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)] ); assert!(nav_history.borrow_mut().pop_backward().is_none()); @@ -6423,7 +6423,7 @@ mod tests { editor.begin_selection(DisplayPoint::new(5, 0), false, 1, cx); editor.end_selection(cx); assert_eq!( - editor.selections.selected_display_ranges(cx), + editor.selections.display_ranges(cx), &[DisplayPoint::new(5, 0)..DisplayPoint::new(5, 0)] ); assert!(nav_history.borrow_mut().pop_backward().is_none()); @@ -6433,14 +6433,14 @@ mod tests { editor.begin_selection(DisplayPoint::new(15, 0), false, 1, cx); editor.end_selection(cx); assert_eq!( - editor.selections.selected_display_ranges(cx), + editor.selections.display_ranges(cx), &[DisplayPoint::new(15, 0)..DisplayPoint::new(15, 0)] ); let nav_entry = nav_history.borrow_mut().pop_backward().unwrap(); editor.navigate(nav_entry.data.unwrap(), cx); assert_eq!(nav_entry.item.id(), cx.view_id()); assert_eq!( - editor.selections.selected_display_ranges(cx), + editor.selections.display_ranges(cx), &[DisplayPoint::new(5, 0)..DisplayPoint::new(5, 0)] ); assert!(nav_history.borrow_mut().pop_backward().is_none()); @@ -6476,7 +6476,7 @@ mod tests { cx, ); assert_eq!( - editor.selections.selected_display_ranges(cx), + editor.selections.display_ranges(cx), &[editor.max_point(cx)..editor.max_point(cx)] ); assert_eq!( @@ -6503,7 +6503,7 @@ mod tests { view.update_selection(DisplayPoint::new(0, 3), 0, Vector2F::zero(), cx); view.end_selection(cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1), @@ -6514,7 +6514,7 @@ mod tests { view.update(cx, |view, cx| { view.cancel(&Cancel, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), [DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1)] ); }); @@ -6522,7 +6522,7 @@ mod tests { view.update(cx, |view, cx| { view.cancel(&Cancel, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), [DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1)] ); }); @@ -6633,43 +6633,43 @@ mod tests { view.update(cx, |view, cx| { assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4)] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)] ); view.move_up(&MoveUp, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] ); view.move_to_end(&MoveToEnd, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(5, 6)..DisplayPoint::new(5, 6)] ); view.move_to_beginning(&MoveToBeginning, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] ); @@ -6678,13 +6678,13 @@ mod tests { }); view.select_to_beginning(&SelectToBeginning, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 0)] ); view.select_to_end(&SelectToEnd, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(0, 1)..DisplayPoint::new(5, 6)] ); }); @@ -6712,80 +6712,80 @@ mod tests { view.move_right(&MoveRight, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(0, "ⓐ".len())] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(0, "ⓐⓑ".len())] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(0, "ⓐⓑ…".len())] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(1, "ab…".len())] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(1, "ab".len())] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(1, "a".len())] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(2, "α".len())] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(2, "αβ".len())] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(2, "αβ…".len())] ); view.move_right(&MoveRight, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(2, "αβ…ε".len())] ); view.move_up(&MoveUp, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(1, "ab…e".len())] ); view.move_up(&MoveUp, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(0, "ⓐⓑ…ⓔ".len())] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(0, "ⓐⓑ…".len())] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(0, "ⓐⓑ".len())] ); view.move_left(&MoveLeft, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(0, "ⓐ".len())] ); }); @@ -6802,37 +6802,37 @@ mod tests { }); view.move_down(&MoveDown, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(1, "abcd".len())] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(2, "αβγ".len())] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(3, "abcd".len())] ); view.move_down(&MoveDown, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(4, "ⓐⓑⓒⓓⓔ".len())] ); view.move_up(&MoveUp, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(3, "abcd".len())] ); view.move_up(&MoveUp, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[empty_range(2, "αβγ".len())] ); }); @@ -6855,7 +6855,7 @@ mod tests { view.update(cx, |view, cx| { view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), @@ -6866,7 +6866,7 @@ mod tests { view.update(cx, |view, cx| { view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), @@ -6877,7 +6877,7 @@ mod tests { view.update(cx, |view, cx| { view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), @@ -6888,7 +6888,7 @@ mod tests { view.update(cx, |view, cx| { view.move_to_end_of_line(&MoveToEndOfLine, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5), @@ -6900,7 +6900,7 @@ mod tests { view.update(cx, |view, cx| { view.move_to_end_of_line(&MoveToEndOfLine, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5), @@ -6917,7 +6917,7 @@ mod tests { cx, ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2), @@ -6933,7 +6933,7 @@ mod tests { cx, ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 0), @@ -6949,7 +6949,7 @@ mod tests { cx, ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2), @@ -6965,7 +6965,7 @@ mod tests { cx, ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 5), @@ -6977,7 +6977,7 @@ mod tests { view.delete_to_end_of_line(&DeleteToEndOfLine, cx); assert_eq!(view.display_text(cx), "ab\n de"); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4), @@ -6989,7 +6989,7 @@ mod tests { view.delete_to_beginning_of_line(&DeleteToBeginningOfLine, cx); assert_eq!(view.display_text(cx), "\n"); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), @@ -7121,37 +7121,37 @@ mod tests { view.move_to_next_word_end(&MoveToNextWordEnd, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(1, 9)..DisplayPoint::new(1, 9)] ); view.move_to_next_word_end(&MoveToNextWordEnd, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(1, 14)..DisplayPoint::new(1, 14)] ); view.move_to_next_word_end(&MoveToNextWordEnd, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4)] ); view.move_to_next_word_end(&MoveToNextWordEnd, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(2, 8)..DisplayPoint::new(2, 8)] ); view.move_to_previous_word_start(&MoveToPreviousWordStart, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4)] ); view.move_to_previous_word_start(&MoveToPreviousWordStart, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(1, 14)..DisplayPoint::new(1, 14)] ); }); @@ -7278,7 +7278,7 @@ mod tests { editor.update(cx, |editor, cx| { assert_eq!( - editor.selections.selected_ranges(cx), + editor.selections.ranges(cx), &[ Point::new(1, 2)..Point::new(1, 2), Point::new(2, 2)..Point::new(2, 2), @@ -7300,7 +7300,7 @@ mod tests { // The selections are moved after the inserted newlines assert_eq!( - editor.selections.selected_ranges(cx), + editor.selections.ranges(cx), &[ Point::new(2, 0)..Point::new(2, 0), Point::new(4, 0)..Point::new(4, 0), @@ -7326,13 +7326,13 @@ mod tests { }); editor.update(cx, |editor, cx| { - assert_eq!(editor.selections.selected_ranges(cx), &[2..2, 7..7, 12..12],); + assert_eq!(editor.selections.ranges(cx), &[2..2, 7..7, 12..12],); editor.insert("Z", cx); assert_eq!(editor.text(cx), "a(Z), b(Z), c(Z)"); // The selections are moved after the inserted characters - assert_eq!(editor.selections.selected_ranges(cx), &[3..3, 9..9, 15..15],); + assert_eq!(editor.selections.ranges(cx), &[3..3, 9..9, 15..15],); }); } @@ -7641,7 +7641,7 @@ mod tests { view.delete_line(&DeleteLine, cx); assert_eq!(view.display_text(cx), "ghi"); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1) @@ -7659,7 +7659,7 @@ mod tests { view.delete_line(&DeleteLine, cx); assert_eq!(view.display_text(cx), "ghi\n"); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)] ); }); @@ -7682,7 +7682,7 @@ mod tests { view.duplicate_line(&DuplicateLine, cx); assert_eq!(view.display_text(cx), "abc\nabc\ndef\ndef\nghi\n\n"); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1), DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), @@ -7704,7 +7704,7 @@ mod tests { view.duplicate_line(&DuplicateLine, cx); assert_eq!(view.display_text(cx), "abc\ndef\nghi\nabc\ndef\nghi\n"); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(3, 1)..DisplayPoint::new(4, 1), DisplayPoint::new(4, 2)..DisplayPoint::new(5, 1), @@ -7746,7 +7746,7 @@ mod tests { "aa…bbb\nccc…eeee\nggggg\n…i\njjjjj\nfffff" ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), @@ -7763,7 +7763,7 @@ mod tests { "ccc…eeee\naa…bbb\nfffff\nggggg\n…i\njjjjj" ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1), @@ -7780,7 +7780,7 @@ mod tests { "ccc…eeee\nfffff\naa…bbb\nggggg\n…i\njjjjj" ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1), @@ -7797,7 +7797,7 @@ mod tests { "ccc…eeee\naa…bbb\nggggg\n…i\njjjjj\nfffff" ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), @@ -7841,15 +7841,15 @@ mod tests { editor.change_selections(None, cx, |s| s.select_ranges([1..1])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bac"); - assert_eq!(editor.selections.selected_ranges(cx), [2..2]); + assert_eq!(editor.selections.ranges(cx), [2..2]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bca"); - assert_eq!(editor.selections.selected_ranges(cx), [3..3]); + assert_eq!(editor.selections.ranges(cx), [3..3]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bac"); - assert_eq!(editor.selections.selected_ranges(cx), [3..3]); + assert_eq!(editor.selections.ranges(cx), [3..3]); editor }) @@ -7861,20 +7861,20 @@ mod tests { editor.change_selections(None, cx, |s| s.select_ranges([3..3])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acb\nde"); - assert_eq!(editor.selections.selected_ranges(cx), [3..3]); + assert_eq!(editor.selections.ranges(cx), [3..3]); editor.change_selections(None, cx, |s| s.select_ranges([4..4])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acbd\ne"); - assert_eq!(editor.selections.selected_ranges(cx), [5..5]); + assert_eq!(editor.selections.ranges(cx), [5..5]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acbde\n"); - assert_eq!(editor.selections.selected_ranges(cx), [6..6]); + assert_eq!(editor.selections.ranges(cx), [6..6]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "acbd\ne"); - assert_eq!(editor.selections.selected_ranges(cx), [6..6]); + assert_eq!(editor.selections.ranges(cx), [6..6]); editor }) @@ -7886,23 +7886,23 @@ mod tests { editor.change_selections(None, cx, |s| s.select_ranges([1..1, 2..2, 4..4])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bacd\ne"); - assert_eq!(editor.selections.selected_ranges(cx), [2..2, 3..3, 5..5]); + assert_eq!(editor.selections.ranges(cx), [2..2, 3..3, 5..5]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bcade\n"); - assert_eq!(editor.selections.selected_ranges(cx), [3..3, 4..4, 6..6]); + assert_eq!(editor.selections.ranges(cx), [3..3, 4..4, 6..6]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bcda\ne"); - assert_eq!(editor.selections.selected_ranges(cx), [4..4, 6..6]); + assert_eq!(editor.selections.ranges(cx), [4..4, 6..6]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bcade\n"); - assert_eq!(editor.selections.selected_ranges(cx), [4..4, 6..6]); + assert_eq!(editor.selections.ranges(cx), [4..4, 6..6]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "bcaed\n"); - assert_eq!(editor.selections.selected_ranges(cx), [5..5, 6..6]); + assert_eq!(editor.selections.ranges(cx), [5..5, 6..6]); editor }) @@ -7914,15 +7914,15 @@ mod tests { editor.change_selections(None, cx, |s| s.select_ranges([4..4])); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "🏀🍐✋"); - assert_eq!(editor.selections.selected_ranges(cx), [8..8]); + assert_eq!(editor.selections.ranges(cx), [8..8]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "🏀✋🍐"); - assert_eq!(editor.selections.selected_ranges(cx), [11..11]); + assert_eq!(editor.selections.ranges(cx), [11..11]); editor.transpose(&Default::default(), cx); assert_eq!(editor.text(cx), "🏀🍐✋"); - assert_eq!(editor.selections.selected_ranges(cx), [11..11]); + assert_eq!(editor.selections.ranges(cx), [11..11]); editor }) @@ -7950,7 +7950,7 @@ mod tests { view.paste(&Paste, cx); assert_eq!(view.display_text(cx), "two one✅ four three six five "); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 11)..DisplayPoint::new(0, 11), DisplayPoint::new(0, 22)..DisplayPoint::new(0, 22), @@ -8014,7 +8014,7 @@ mod tests { "123\n4567\n9\n( 8ne✅ \nthree \nfive ) two one✅ four three six five ( one✅ \nthree \nfive ) " ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), @@ -8047,7 +8047,7 @@ mod tests { "123\n123\n123\n67\n123\n9\n( 8ne✅ \nthree \nfive ) two one✅ four three six five ( one✅ \nthree \nfive ) " ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[ DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0), @@ -8065,7 +8065,7 @@ mod tests { view.update(cx, |view, cx| { view.select_all(&SelectAll, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(2, 3)] ); }); @@ -8087,7 +8087,7 @@ mod tests { }); view.select_line(&SelectLine, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(0, 0)..DisplayPoint::new(2, 0), DisplayPoint::new(4, 0)..DisplayPoint::new(5, 0), @@ -8098,7 +8098,7 @@ mod tests { view.update(cx, |view, cx| { view.select_line(&SelectLine, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(0, 0)..DisplayPoint::new(3, 0), DisplayPoint::new(4, 0)..DisplayPoint::new(5, 5), @@ -8109,7 +8109,7 @@ mod tests { view.update(cx, |view, cx| { view.select_line(&SelectLine, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![DisplayPoint::new(0, 0)..DisplayPoint::new(5, 5)] ); }); @@ -8147,7 +8147,7 @@ mod tests { "aaaaa\nbbbbb\nccc…eeee\nfffff\nggggg\n…i" ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), @@ -8167,7 +8167,7 @@ mod tests { "aaaaa\nbbbbb\nccccc\nddddd\neeeee\nfffff\nggggg\nhhhhh\niiiii" ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), [ DisplayPoint::new(0, 5)..DisplayPoint::new(0, 5), DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5), @@ -8196,7 +8196,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3) @@ -8207,7 +8207,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3) @@ -8218,13 +8218,13 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)] ); view.undo_selection(&UndoSelection, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3) @@ -8233,7 +8233,7 @@ mod tests { view.redo_selection(&RedoSelection, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)] ); }); @@ -8241,7 +8241,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 3)..DisplayPoint::new(4, 3) @@ -8252,7 +8252,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 3)..DisplayPoint::new(4, 3) @@ -8268,7 +8268,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 4)..DisplayPoint::new(4, 3) @@ -8279,7 +8279,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 4)..DisplayPoint::new(4, 3) @@ -8290,7 +8290,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)] ); }); @@ -8298,7 +8298,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)] ); }); @@ -8309,7 +8309,7 @@ mod tests { }); view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4), @@ -8321,7 +8321,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4), @@ -8334,7 +8334,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4), @@ -8351,7 +8351,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_above(&AddSelectionAbove, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 3)..DisplayPoint::new(1, 1), @@ -8364,7 +8364,7 @@ mod tests { view.update(cx, |view, cx| { view.add_selection_below(&AddSelectionBelow, cx); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), vec![ DisplayPoint::new(1, 3)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 2)..DisplayPoint::new(3, 1), @@ -8392,7 +8392,7 @@ mod tests { }, cx, ); - assert_eq!(view.selections.selected_ranges(cx), &ranges[1..2]); + assert_eq!(view.selections.ranges(cx), &ranges[1..2]); view.select_next( &SelectNext { @@ -8400,13 +8400,13 @@ mod tests { }, cx, ); - assert_eq!(view.selections.selected_ranges(cx), &ranges[1..3]); + assert_eq!(view.selections.ranges(cx), &ranges[1..3]); view.undo_selection(&UndoSelection, cx); - assert_eq!(view.selections.selected_ranges(cx), &ranges[1..2]); + assert_eq!(view.selections.ranges(cx), &ranges[1..2]); view.redo_selection(&RedoSelection, cx); - assert_eq!(view.selections.selected_ranges(cx), &ranges[1..3]); + assert_eq!(view.selections.ranges(cx), &ranges[1..3]); view.select_next( &SelectNext { @@ -8414,7 +8414,7 @@ mod tests { }, cx, ); - assert_eq!(view.selections.selected_ranges(cx), &ranges[1..4]); + assert_eq!(view.selections.ranges(cx), &ranges[1..4]); view.select_next( &SelectNext { @@ -8422,7 +8422,7 @@ mod tests { }, cx, ); - assert_eq!(view.selections.selected_ranges(cx), &ranges[0..4]); + assert_eq!(view.selections.ranges(cx), &ranges[0..4]); }); } @@ -8460,9 +8460,7 @@ mod tests { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| { - view.selections.selected_display_ranges(cx) - }), + view.update(cx, |view, cx| { view.selections.display_ranges(cx) }), &[ DisplayPoint::new(0, 23)..DisplayPoint::new(0, 27), DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7), @@ -8474,7 +8472,7 @@ mod tests { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.display_ranges(cx)), &[ DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28), DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0), @@ -8485,7 +8483,7 @@ mod tests { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.display_ranges(cx)), &[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)] ); @@ -8494,7 +8492,7 @@ mod tests { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.display_ranges(cx)), &[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)] ); @@ -8502,7 +8500,7 @@ mod tests { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.display_ranges(cx)), &[ DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28), DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0), @@ -8513,7 +8511,7 @@ mod tests { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.display_ranges(cx)), &[ DisplayPoint::new(0, 23)..DisplayPoint::new(0, 27), DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7), @@ -8525,7 +8523,7 @@ mod tests { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.display_ranges(cx)), &[ DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25), DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12), @@ -8538,7 +8536,7 @@ mod tests { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.display_ranges(cx)), &[ DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25), DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12), @@ -8559,7 +8557,7 @@ mod tests { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( - view.update(cx, |view, cx| view.selections.selected_display_ranges(cx)), + view.update(cx, |view, cx| view.selections.display_ranges(cx)), &[ DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28), DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7), @@ -8615,7 +8613,7 @@ mod tests { editor.newline(&Newline, cx); assert_eq!(editor.text(cx), "fn a(\n \n) {\n \n}\n"); assert_eq!( - editor.selections.selected_ranges(cx), + editor.selections.ranges(cx), &[ Point::new(1, 4)..Point::new(1, 4), Point::new(3, 4)..Point::new(3, 4), @@ -8768,7 +8766,7 @@ mod tests { .unindent() ); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), [DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2)] ); }); @@ -8798,10 +8796,7 @@ mod tests { marked_text_ranges_by(marked_text_ranges, vec![range_markers.clone()]); let selection_ranges = selection_ranges_lookup.remove(&range_markers).unwrap(); assert_eq!(editor.text(cx), expected_text); - assert_eq!( - editor.selections.selected_ranges::(cx), - selection_ranges - ); + assert_eq!(editor.selections.ranges::(cx), selection_ranges); } assert( editor, @@ -9335,7 +9330,7 @@ mod tests { view.handle_input(&Input("X".to_string()), cx); assert_eq!(view.text(cx), "Xaaaa\nXbbbb"); assert_eq!( - view.selections.selected_ranges(cx), + view.selections.ranges(cx), [ Point::new(0, 1)..Point::new(0, 1), Point::new(1, 1)..Point::new(1, 1), @@ -9376,7 +9371,7 @@ mod tests { bX|bbX|b cccc"}); assert_eq!(view.text(cx), expected_text); - assert_eq!(view.selections.selected_ranges(cx), expected_selections); + assert_eq!(view.selections.ranges(cx), expected_selections); view.newline(&Newline, cx); let (expected_text, expected_selections) = marked_text_ranges(indoc! {" @@ -9389,7 +9384,7 @@ mod tests { |b cccc"}); assert_eq!(view.text(cx), expected_text); - assert_eq!(view.selections.selected_ranges(cx), expected_selections); + assert_eq!(view.selections.ranges(cx), expected_selections); }); } @@ -9425,7 +9420,7 @@ mod tests { }); editor.begin_selection(Point::new(2, 1).to_display_point(&snapshot), true, 1, cx); assert_eq!( - editor.selections.selected_ranges(cx), + editor.selections.ranges(cx), [ Point::new(1, 3)..Point::new(1, 3), Point::new(2, 1)..Point::new(2, 1), @@ -9440,7 +9435,7 @@ mod tests { s.refresh(); }); assert_eq!( - editor.selections.selected_ranges(cx), + editor.selections.ranges(cx), [ Point::new(1, 3)..Point::new(1, 3), Point::new(2, 1)..Point::new(2, 1), @@ -9454,7 +9449,7 @@ mod tests { editor.update(cx, |editor, cx| { // Removing an excerpt causes the first selection to become degenerate. assert_eq!( - editor.selections.selected_ranges(cx), + editor.selections.ranges(cx), [ Point::new(0, 0)..Point::new(0, 0), Point::new(0, 1)..Point::new(0, 1) @@ -9467,7 +9462,7 @@ mod tests { s.refresh(); }); assert_eq!( - editor.selections.selected_ranges(cx), + editor.selections.ranges(cx), [ Point::new(0, 1)..Point::new(0, 1), Point::new(0, 3)..Point::new(0, 3) @@ -9506,7 +9501,7 @@ mod tests { let snapshot = editor.snapshot(cx); editor.begin_selection(Point::new(1, 3).to_display_point(&snapshot), false, 1, cx); assert_eq!( - editor.selections.selected_ranges(cx), + editor.selections.ranges(cx), [Point::new(1, 3)..Point::new(1, 3)] ); editor @@ -9517,7 +9512,7 @@ mod tests { }); editor.update(cx, |editor, cx| { assert_eq!( - editor.selections.selected_ranges(cx), + editor.selections.ranges(cx), [Point::new(0, 0)..Point::new(0, 0)] ); @@ -9526,7 +9521,7 @@ mod tests { s.refresh(); }); assert_eq!( - editor.selections.selected_ranges(cx), + editor.selections.ranges(cx), [Point::new(0, 3)..Point::new(0, 3)] ); assert!(editor.selections.pending_anchor().is_some()); @@ -9718,7 +9713,7 @@ mod tests { .apply_update_proto(pending_update.borrow_mut().take().unwrap(), cx) .unwrap(); }); - assert_eq!(follower.read(cx).selections.selected_ranges(cx), vec![1..1]); + assert_eq!(follower.read(cx).selections.ranges(cx), vec![1..1]); // Update the scroll position only leader.update(cx, |leader, cx| { @@ -9748,7 +9743,7 @@ mod tests { assert_eq!(follower.scroll_position(cx), initial_scroll_position); assert!(follower.autoscroll_request.is_some()); }); - assert_eq!(follower.read(cx).selections.selected_ranges(cx), vec![0..0]); + assert_eq!(follower.read(cx).selections.ranges(cx), vec![0..0]); // Creating a pending selection that precedes another selection leader.update(cx, |leader, cx| { @@ -9760,10 +9755,7 @@ mod tests { .apply_update_proto(pending_update.borrow_mut().take().unwrap(), cx) .unwrap(); }); - assert_eq!( - follower.read(cx).selections.selected_ranges(cx), - vec![0..0, 1..1] - ); + assert_eq!(follower.read(cx).selections.ranges(cx), vec![0..0, 1..1]); // Extend the pending selection so that it surrounds another selection leader.update(cx, |leader, cx| { @@ -9774,7 +9766,7 @@ mod tests { .apply_update_proto(pending_update.borrow_mut().take().unwrap(), cx) .unwrap(); }); - assert_eq!(follower.read(cx).selections.selected_ranges(cx), vec![0..2]); + assert_eq!(follower.read(cx).selections.ranges(cx), vec![0..2]); } #[test] @@ -9877,7 +9869,7 @@ mod tests { }) .collect(); assert_eq!( - view.selections.selected_display_ranges(cx), + view.selections.display_ranges(cx), &asserted_ranges[..], "Assert selections are {}", marked_text diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs index a5fac015d6..5965ad58f3 100644 --- a/crates/editor/src/selections_collection.rs +++ b/crates/editor/src/selections_collection.rs @@ -129,6 +129,9 @@ impl SelectionsCollection { range: Range, cx: &AppContext, ) -> Vec> { + // TODO: Make sure pending selection is handled correctly here + // if it is interleaved properly, we can sue resolve_multiple + // to improve performance let buffer = self.buffer(cx); let start_ix = match self .disjoint @@ -211,7 +214,7 @@ impl SelectionsCollection { } #[cfg(any(test, feature = "test-support"))] - pub fn selected_ranges + std::fmt::Debug>( + pub fn ranges + std::fmt::Debug>( &self, cx: &AppContext, ) -> Vec> { @@ -228,7 +231,7 @@ impl SelectionsCollection { } #[cfg(any(test, feature = "test-support"))] - pub fn selected_display_ranges(&self, cx: &mut MutableAppContext) -> Vec> { + pub fn display_ranges(&self, cx: &mut MutableAppContext) -> Vec> { let display_map = self.display_map(cx); self.disjoint_anchors() .iter() diff --git a/crates/editor/src/test.rs b/crates/editor/src/test.rs index 822b033dc3..cb064be545 100644 --- a/crates/editor/src/test.rs +++ b/crates/editor/src/test.rs @@ -54,5 +54,5 @@ pub fn assert_text_with_selections( let (unmarked_text, text_ranges) = marked_text_ranges(marked_text); assert_eq!(editor.text(cx), unmarked_text); - assert_eq!(editor.selections.selected_ranges(cx), text_ranges); + assert_eq!(editor.selections.ranges(cx), text_ranges); } diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 2209578295..ec09fd45b5 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -729,9 +729,7 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(0)); search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)] ); }); @@ -742,9 +740,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(3, 11)..DisplayPoint::new(3, 13)] ); }); @@ -755,9 +751,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)] ); }); @@ -768,9 +762,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)] ); }); @@ -781,9 +773,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)] ); }); @@ -794,9 +784,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(3, 11)..DisplayPoint::new(3, 13)] ); }); @@ -807,9 +795,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)] ); }); @@ -828,9 +814,7 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(1)); search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)] ); }); @@ -849,9 +833,7 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(1)); search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(3, 11)..DisplayPoint::new(3, 13)] ); }); @@ -870,9 +852,7 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(2)); search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)] ); }); @@ -891,9 +871,7 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(2)); search_bar.select_next_match(&SelectNextMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)] ); }); @@ -912,9 +890,7 @@ mod tests { assert_eq!(search_bar.active_match_index, Some(0)); search_bar.select_prev_match(&SelectPrevMatch, cx); assert_eq!( - editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)] ); }); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index cac8b449c7..4915d50ec9 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -891,7 +891,7 @@ mod tests { assert_eq!( search_view .results_editor - .update(cx, |editor, cx| editor.selections.selected_display_ranges(cx)), + .update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(2, 32)..DisplayPoint::new(2, 35)] ); @@ -901,9 +901,9 @@ mod tests { search_view.update(cx, |search_view, cx| { assert_eq!(search_view.active_match_index, Some(1)); assert_eq!( - search_view.results_editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + search_view + .results_editor + .update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(2, 37)..DisplayPoint::new(2, 40)] ); search_view.select_match(Direction::Next, cx); @@ -912,9 +912,9 @@ mod tests { search_view.update(cx, |search_view, cx| { assert_eq!(search_view.active_match_index, Some(2)); assert_eq!( - search_view.results_editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + search_view + .results_editor + .update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(5, 6)..DisplayPoint::new(5, 9)] ); search_view.select_match(Direction::Next, cx); @@ -923,9 +923,9 @@ mod tests { search_view.update(cx, |search_view, cx| { assert_eq!(search_view.active_match_index, Some(0)); assert_eq!( - search_view.results_editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + search_view + .results_editor + .update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(2, 32)..DisplayPoint::new(2, 35)] ); search_view.select_match(Direction::Prev, cx); @@ -934,9 +934,9 @@ mod tests { search_view.update(cx, |search_view, cx| { assert_eq!(search_view.active_match_index, Some(2)); assert_eq!( - search_view.results_editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + search_view + .results_editor + .update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(5, 6)..DisplayPoint::new(5, 9)] ); search_view.select_match(Direction::Prev, cx); @@ -945,9 +945,9 @@ mod tests { search_view.update(cx, |search_view, cx| { assert_eq!(search_view.active_match_index, Some(1)); assert_eq!( - search_view.results_editor.update(cx, |editor, cx| editor - .selections - .selected_display_ranges(cx)), + search_view + .results_editor + .update(cx, |editor, cx| editor.selections.display_ranges(cx)), [DisplayPoint::new(2, 37)..DisplayPoint::new(2, 40)] ); }); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index a2fb6f740b..fc8c9b3534 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1180,7 +1180,7 @@ mod tests { let editor = item.downcast::().unwrap(); let (selections, scroll_position) = editor.update(cx, |editor, cx| { ( - editor.selections.selected_display_ranges(cx), + editor.selections.display_ranges(cx), editor.scroll_position(cx), ) }); From 20c97637a4a5dda781dc1d8e5342604055f242fa Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Fri, 13 May 2022 12:55:15 -0700 Subject: [PATCH 14/18] minor tweaks to selections collection api --- crates/editor/src/editor.rs | 78 +++++++--------------- crates/editor/src/selections_collection.rs | 24 +++++-- crates/vim/src/normal.rs | 4 +- 3 files changed, 46 insertions(+), 60 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 8c6cf33e09..3a9934e5c6 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1392,20 +1392,6 @@ impl Editor { result } - pub fn display_selections( - &mut self, - cx: &mut ViewContext, - ) -> (DisplaySnapshot, Vec>) { - let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = self - .selections - .interleaved::(cx) - .into_iter() - .map(|selection| selection.map(|point| point.to_display_point(&display_map))) - .collect(); - (display_map, selections) - } - pub fn edit(&mut self, edits: I, cx: &mut ViewContext) where I: IntoIterator, T)>, @@ -1464,25 +1450,27 @@ impl Editor { let position = position.to_offset(&display_map, Bias::Left); let tail_anchor = display_map.buffer_snapshot.anchor_before(tail); + let mut pending_selection = self + .selections + .pending_anchor() + .expect("extend_selection not called with pending selection"); + if position >= tail { + pending_selection.start = tail_anchor.clone(); + } else { + pending_selection.end = tail_anchor.clone(); + pending_selection.reversed = true; + } + + let mut pending_mode = self.selections.pending_mode().unwrap(); + match &mut pending_mode { + SelectMode::Word(range) | SelectMode::Line(range) => { + *range = tail_anchor.clone()..tail_anchor + } + _ => {} + } + self.change_selections(Some(Autoscroll::Fit), cx, |s| { - let mut pending = s - .pending_mut() - .as_mut() - .expect("extend_selection not called with pending selection"); - - if position >= tail { - pending.selection.start = tail_anchor.clone(); - } else { - pending.selection.end = tail_anchor.clone(); - pending.selection.reversed = true; - } - - match &mut pending.mode { - SelectMode::Word(range) | SelectMode::Line(range) => { - *range = tail_anchor.clone()..tail_anchor - } - _ => {} - } + s.set_pending(pending_selection, pending_mode) }); } @@ -1591,7 +1579,8 @@ impl Editor { let buffer = self.buffer.read(cx).snapshot(cx); let head; let tail; - match &self.selections.pending_mode().unwrap() { + let mode = self.selections.pending_mode().unwrap(); + match &mode { SelectMode::Character => { head = position.to_point(&display_map); tail = pending.tail().to_point(&buffer); @@ -1660,7 +1649,7 @@ impl Editor { } self.change_selections(None, cx, |s| { - s.pending_mut().as_mut().unwrap().selection = pending; + s.set_pending(pending, mode); }); } else { log::error!("update_selection dispatched with no pending selection"); @@ -1745,8 +1734,7 @@ impl Editor { return; } - if self.change_selections(None, cx, |s| s.try_cancel()) { - self.request_autoscroll(Autoscroll::Fit, cx); + if self.change_selections(Some(Autoscroll::Fit), cx, |s| s.try_cancel()) { return; } } @@ -1851,8 +1839,6 @@ impl Editor { .collect(); this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(new_selections)); - - this.request_autoscroll(Autoscroll::Fit, cx); }); } @@ -1972,13 +1958,7 @@ impl Editor { let mut snapshot = buffer.snapshot(cx); let left_biased_selections = selections .iter() - .map(|selection| Selection { - id: selection.id, - start: snapshot.anchor_before(selection.start), - end: snapshot.anchor_before(selection.end), - reversed: selection.reversed, - goal: selection.goal, - }) + .map(|selection| selection.map(|p| snapshot.anchor_before(p))) .collect::>(); let autoclose_pair = snapshot.language().and_then(|language| { @@ -2730,13 +2710,6 @@ impl Editor { } } if let Some(current_ranges) = snippet.ranges.get(snippet.active_index) { - let snapshot = self.buffer.read(cx).snapshot(cx); - let current_ranges_resolved = current_ranges - .iter() - .map(|range| range.start.to_point(&snapshot)..range.end.to_point(&snapshot)) - .collect::>(); - dbg!(¤t_ranges, current_ranges_resolved); - self.change_selections(Some(Autoscroll::Fit), cx, |s| { s.select_anchor_ranges(current_ranges.into_iter().cloned()) }); @@ -4024,7 +3997,6 @@ impl Editor { } fn add_selection(&mut self, above: bool, cx: &mut ViewContext) { - self.push_to_selection_history(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let mut selections = self.selections.interleaved::(cx); let mut state = self.add_selections_state.take().unwrap_or_else(|| { diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs index 5965ad58f3..d889d14c14 100644 --- a/crates/editor/src/selections_collection.rs +++ b/crates/editor/src/selections_collection.rs @@ -169,6 +169,19 @@ impl SelectionsCollection { .collect() } + pub fn display_interleaved( + &mut self, + cx: &mut MutableAppContext, + ) -> (DisplaySnapshot, Vec>) { + let display_map = self.display_map(cx); + let selections = self + .interleaved::(cx) + .into_iter() + .map(|selection| selection.map(|point| point.to_display_point(&display_map))) + .collect(); + (display_map, selections) + } + pub fn newest_anchor(&self) -> &Selection { self.pending .as_ref() @@ -308,12 +321,12 @@ impl<'a> MutableSelectionsCollection<'a> { mode, }) } - pub fn pending_mut(&mut self) -> &mut Option { - &mut self.collection.pending + + pub fn set_pending(&mut self, selection: Selection, mode: SelectMode) { + self.collection.pending = Some(PendingSelection { selection, mode }); } pub fn try_cancel(&mut self) -> bool { - let buffer = self.buffer.read(self.cx).snapshot(self.cx); if let Some(pending) = self.collection.pending.take() { if self.disjoint.is_empty() { self.collection.disjoint = Arc::from([pending.selection]); @@ -327,7 +340,7 @@ impl<'a> MutableSelectionsCollection<'a> { return true; } - if !oldest.start.cmp(&oldest.end, &buffer).is_eq() { + if !oldest.start.cmp(&oldest.end, &self.buffer()).is_eq() { let head = oldest.head(); oldest.start = head.clone(); oldest.end = head; @@ -584,7 +597,8 @@ impl<'a> MutableSelectionsCollection<'a> { pub fn refresh(&mut self) -> HashMap { // TODO: Pull disjoint constraint out of update_selections so we don't have to // store the pending_selection here. - let buffer = self.buffer.read(self.cx).snapshot(self.cx); + let buffer = self.buffer(); + let mut pending = self.collection.pending.take(); let mut selections_with_lost_position = HashMap::default(); diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index be218592cc..36fec6fbfc 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -130,7 +130,7 @@ fn insert_line_above(_: &mut Workspace, _: &InsertLineAbove, cx: &mut ViewContex vim.switch_mode(Mode::Insert, cx); vim.update_active_editor(cx, |editor, cx| { editor.transact(cx, |editor, cx| { - let (map, old_selections) = editor.display_selections(cx); + let (map, old_selections) = editor.selections.display_interleaved(cx); let selection_start_rows: HashSet = old_selections .into_iter() .map(|selection| selection.start.row()) @@ -162,7 +162,7 @@ fn insert_line_below(_: &mut Workspace, _: &InsertLineBelow, cx: &mut ViewContex vim.switch_mode(Mode::Insert, cx); vim.update_active_editor(cx, |editor, cx| { editor.transact(cx, |editor, cx| { - let (map, old_selections) = editor.display_selections(cx); + let (map, old_selections) = editor.selections.display_interleaved(cx); let selection_end_rows: HashSet = old_selections .into_iter() .map(|selection| selection.end.row()) From 45ea3d4c38832aa37564d0928e9c6fdbe7d31f9b Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Fri, 13 May 2022 15:49:14 -0700 Subject: [PATCH 15/18] Review fixes --- crates/diagnostics/src/diagnostics.rs | 2 +- crates/editor/src/editor.rs | 141 +++++++-------------- crates/editor/src/element.rs | 5 +- crates/editor/src/items.rs | 2 +- crates/editor/src/selections_collection.rs | 105 ++++++++------- crates/vim/src/normal.rs | 4 +- crates/vim/src/vim_test_context.rs | 2 +- 7 files changed, 111 insertions(+), 150 deletions(-) diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 54fde4f4ad..5e94bbe055 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -419,7 +419,7 @@ impl ProjectDiagnosticsEditor { groups = self.path_states.get(path_ix)?.diagnostic_groups.as_slice(); new_excerpt_ids_by_selection_id = editor.change_selections(Some(Autoscroll::Fit), cx, |s| s.refresh()); - selections = editor.selections.interleaved::(cx); + selections = editor.selections.all::(cx); } // If any selection has lost its position, move it to start of the next primary diagnostic. diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 3a9934e5c6..9b160acf64 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1191,7 +1191,7 @@ impl Editor { first_cursor_top = newest_selection.head().to_display_point(&display_map).row() as f32; last_cursor_bottom = first_cursor_top + 1.; } else { - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); first_cursor_top = selections .first() .unwrap() @@ -1251,7 +1251,7 @@ impl Editor { cx: &mut ViewContext, ) -> bool { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let mut target_left; let mut target_right; @@ -1663,7 +1663,7 @@ impl Editor { fn end_selection(&mut self, cx: &mut ViewContext) { self.columnar_selection_tail.take(); if self.selections.pending_anchor().is_some() { - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); self.change_selections(None, cx, |s| { s.select(selections); s.clear_pending(); @@ -1763,7 +1763,7 @@ impl Editor { pub fn newline(&mut self, _: &Newline, cx: &mut ViewContext) { self.transact(cx, |this, cx| { let (edits, selection_fixup_info): (Vec<_>, Vec<_>) = { - let selections = this.selections.interleaved::(cx); + let selections = this.selections.all::(cx); let buffer = this.buffer.read(cx).snapshot(cx); selections @@ -1845,7 +1845,7 @@ impl Editor { pub fn insert(&mut self, text: &str, cx: &mut ViewContext) { let text: Arc = text.into(); self.transact(cx, |this, cx| { - let old_selections = this.selections.interleaved::(cx); + let old_selections = this.selections.all::(cx); let selection_anchors = this.buffer.update(cx, |buffer, cx| { let anchors = { let snapshot = buffer.read(cx); @@ -1908,7 +1908,7 @@ impl Editor { { if self .selections - .interleaved::(cx) + .all::(cx) .iter() .any(|selection| selection.is_empty()) { @@ -1951,7 +1951,7 @@ impl Editor { } fn autoclose_bracket_pairs(&mut self, cx: &mut ViewContext) { - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let mut bracket_pair_state = None; let mut new_selections = None; self.buffer.update(cx, |buffer, cx| { @@ -2045,7 +2045,7 @@ impl Editor { fn skip_autoclose_end(&mut self, text: &str, cx: &mut ViewContext) -> bool { let buffer = self.buffer.read(cx).snapshot(cx); - let old_selections = self.selections.interleaved::(cx); + let old_selections = self.selections.all::(cx); let autoclose_pair = if let Some(autoclose_pair) = self.autoclose_stack.last() { autoclose_pair } else { @@ -2214,7 +2214,7 @@ impl Editor { snippet = None; text = completion.new_text.clone(); }; - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let buffer = buffer_handle.read(cx); let old_range = completion.old_range.to_offset(&buffer); let old_text = buffer.text_for_range(old_range.clone()).collect::(); @@ -2733,7 +2733,7 @@ impl Editor { pub fn backspace(&mut self, _: &Backspace, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let mut selections = self.selections.interleaved::(cx); + let mut selections = self.selections.all::(cx); for selection in &mut selections { if selection.is_empty() { let old_head = selection.head(); @@ -2792,7 +2792,7 @@ impl Editor { return; } - let mut selections = self.selections.interleaved::(cx); + let mut selections = self.selections.all::(cx); if selections.iter().all(|s| s.is_empty()) { self.transact(cx, |this, cx| { this.buffer.update(cx, |buffer, cx| { @@ -2827,7 +2827,7 @@ impl Editor { } pub fn indent(&mut self, _: &Indent, cx: &mut ViewContext) { - let mut selections = self.selections.interleaved::(cx); + let mut selections = self.selections.all::(cx); self.transact(cx, |this, cx| { let mut last_indent = None; this.buffer.update(cx, |buffer, cx| { @@ -2890,7 +2890,7 @@ impl Editor { pub fn outdent(&mut self, _: &Outdent, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let mut deletion_ranges = Vec::new(); let mut last_outdent = None; { @@ -2933,17 +2933,14 @@ impl Editor { cx, ); }); - this.change_selections(Some(Autoscroll::Fit), cx, |s| { - // TODO: Make sure this is a reasonable change - // This used to call select(local_selections) - s.refresh() - }); + let selections = this.selections.all::(cx); + this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections)); }); } pub fn delete_line(&mut self, _: &DeleteLine, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let mut new_cursors = Vec::new(); let mut edit_ranges = Vec::new(); @@ -3025,7 +3022,7 @@ impl Editor { pub fn duplicate_line(&mut self, _: &DuplicateLine, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = &display_map.buffer_snapshot; - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let mut edits = Vec::new(); let mut selections_iter = selections.iter().peekable(); @@ -3070,7 +3067,7 @@ impl Editor { let mut unfold_ranges = Vec::new(); let mut refold_ranges = Vec::new(); - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let mut selections = selections.iter().peekable(); let mut contiguous_row_selections = Vec::new(); let mut new_selections = Vec::new(); @@ -3182,7 +3179,7 @@ impl Editor { let mut unfold_ranges = Vec::new(); let mut refold_ranges = Vec::new(); - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let mut selections = selections.iter().peekable(); let mut contiguous_row_selections = Vec::new(); let mut new_selections = Vec::new(); @@ -3320,10 +3317,9 @@ impl Editor { edits }); this.buffer.update(cx, |buffer, cx| buffer.edit(edits, cx)); + let selections = this.selections.all::(cx); this.change_selections(Some(Autoscroll::Fit), cx, |s| { - // TODO: Make sure this swap is reasonable. - // This was select(interleaved) - s.refresh(); + s.select(selections); }); }); } @@ -3331,7 +3327,7 @@ impl Editor { pub fn cut(&mut self, _: &Cut, cx: &mut ViewContext) { let mut text = String::new(); let buffer = self.buffer.read(cx).snapshot(cx); - let mut selections = self.selections.interleaved::(cx); + let mut selections = self.selections.all::(cx); let mut clipboard_selections = Vec::with_capacity(selections.len()); { let max_point = buffer.max_point(); @@ -3364,7 +3360,7 @@ impl Editor { } pub fn copy(&mut self, _: &Copy, cx: &mut ViewContext) { - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let buffer = self.buffer.read(cx).read(cx); let mut text = String::new(); let mut clipboard_selections = Vec::with_capacity(selections.len()); @@ -3398,7 +3394,7 @@ impl Editor { if let Some(item) = cx.as_mut().read_from_clipboard() { let mut clipboard_text = Cow::Borrowed(item.text()); if let Some(mut clipboard_selections) = item.metadata::>() { - let old_selections = this.selections.interleaved::(cx); + let old_selections = this.selections.all::(cx); let all_selections_were_entire_line = clipboard_selections.iter().all(|s| s.is_entire_line); if clipboard_selections.len() != old_selections.len() { @@ -3451,7 +3447,7 @@ impl Editor { buffer.edit_with_autoindent(edits, cx); }); - let selections = this.selections.interleaved::(cx); + let selections = this.selections.all::(cx); this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections)); } else { this.insert(&clipboard_text, cx); @@ -3464,8 +3460,6 @@ impl Editor { if let Some(tx_id) = self.buffer.update(cx, |buffer, cx| buffer.undo(cx)) { if let Some((selections, _)) = self.selection_history.transaction(tx_id).cloned() { self.change_selections(None, cx, |s| { - // TODO: move to SelectionsCollection to preserve selection - // invariants without rechecking s.select_anchors(selections.to_vec()); }); } @@ -3479,8 +3473,6 @@ impl Editor { if let Some((_, Some(selections))) = self.selection_history.transaction(tx_id).cloned() { self.change_selections(None, cx, |s| { - // TODO: move to SelectionsCollection to preserve selection - // invariants without rechecking s.select_anchors(selections.to_vec()); }); } @@ -3950,7 +3942,7 @@ impl Editor { pub fn select_line(&mut self, _: &SelectLine, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let mut selections = self.selections.interleaved::(cx); + let mut selections = self.selections.all::(cx); let max_point = display_map.buffer_snapshot.max_point(); for selection in &mut selections { let rows = selection.spanned_rows(true, &display_map); @@ -3971,7 +3963,7 @@ impl Editor { let mut to_unfold = Vec::new(); let mut new_selection_ranges = Vec::new(); { - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let buffer = self.buffer.read(cx).read(cx); for selection in selections { for row in selection.start.row..selection.end.row { @@ -3998,7 +3990,7 @@ impl Editor { fn add_selection(&mut self, above: bool, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let mut selections = self.selections.interleaved::(cx); + let mut selections = self.selections.all::(cx); let mut state = self.add_selections_state.take().unwrap_or_else(|| { let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone(); let range = oldest_selection.display_range(&display_map).sorted(); @@ -4008,7 +4000,7 @@ impl Editor { selections.clear(); let mut stack = Vec::new(); for row in range.start.row()..=range.end.row() { - if let Some(selection) = self.build_columnar_selection( + if let Some(selection) = self.selections.build_columnar_selection( &display_map, row, &columns, @@ -4055,7 +4047,7 @@ impl Editor { row += 1; } - if let Some(new_selection) = self.build_columnar_selection( + if let Some(new_selection) = self.selections.build_columnar_selection( &display_map, row, &columns, @@ -4095,7 +4087,7 @@ impl Editor { self.push_to_selection_history(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = &display_map.buffer_snapshot; - let mut selections = self.selections.interleaved::(cx); + let mut selections = self.selections.all::(cx); if let Some(mut select_next_state) = self.select_next_state.take() { let query = &select_next_state.query; if !select_next_state.done { @@ -4185,7 +4177,7 @@ impl Editor { pub fn toggle_comments(&mut self, _: &ToggleComments, cx: &mut ViewContext) { self.transact(cx, |this, cx| { - let mut selections = this.selections.interleaved::(cx); + let mut selections = this.selections.all::(cx); let mut all_selection_lines_are_comments = true; let mut edit_ranges = Vec::new(); let mut last_toggled_row = None; @@ -4286,10 +4278,8 @@ impl Editor { } }); - let selections = this.selections.interleaved::(cx); - this.change_selections(Some(Autoscroll::Fit), cx, |s| { - s.select(selections); - }); + let selections = this.selections.all::(cx); + this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections)); }); } @@ -4300,7 +4290,7 @@ impl Editor { ) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = self.buffer.read(cx).snapshot(cx); - let old_selections = self.selections.interleaved::(cx).into_boxed_slice(); + let old_selections = self.selections.all::(cx).into_boxed_slice(); let mut stack = mem::take(&mut self.select_larger_syntax_node_stack); let mut selected_larger_node = false; @@ -4360,7 +4350,7 @@ impl Editor { cx: &mut ViewContext, ) { let buffer = self.buffer.read(cx).snapshot(cx); - let mut selections = self.selections.interleaved::(cx); + let mut selections = self.selections.all::(cx); for selection in &mut selections { if let Some((open_range, close_range)) = buffer.enclosing_bracket_ranges(selection.start..selection.end) @@ -4387,11 +4377,7 @@ impl Editor { self.end_selection(cx); self.selection_history.mode = SelectionHistoryMode::Undoing; if let Some(entry) = self.selection_history.undo_stack.pop_back() { - self.change_selections(None, cx, |s| { - // TODO: Move to selections so selections invariants can be preserved rather than - // rechecking them. - s.select_anchors(entry.selections.to_vec()) - }); + self.change_selections(None, cx, |s| s.select_anchors(entry.selections.to_vec())); self.select_next_state = entry.select_next_state; self.add_selections_state = entry.add_selections_state; self.request_autoscroll(Autoscroll::Newest, cx); @@ -4403,11 +4389,7 @@ impl Editor { self.end_selection(cx); self.selection_history.mode = SelectionHistoryMode::Redoing; if let Some(entry) = self.selection_history.redo_stack.pop_back() { - self.change_selections(None, cx, |s| { - // TODO: Move to selections so selections invariants can be preserved rather than - // rechecking them. - s.select_anchors(entry.selections.to_vec()) - }); + self.change_selections(None, cx, |s| s.select_anchors(entry.selections.to_vec())); self.select_next_state = entry.select_next_state; self.add_selections_state = entry.add_selections_state; self.request_autoscroll(Autoscroll::Newest, cx); @@ -4827,14 +4809,9 @@ impl Editor { .min(rename_range.end); drop(snapshot); - let new_selection = Selection { - id: self.selections.newest_anchor().id, - start: cursor_in_editor, - end: cursor_in_editor, - reversed: false, - goal: SelectionGoal::None, - }; - self.change_selections(None, cx, |s| s.select(vec![new_selection])); + self.change_selections(None, cx, |s| { + s.select_ranges(vec![cursor_in_editor..cursor_in_editor]) + }); } Some(rename) @@ -4945,34 +4922,6 @@ impl Editor { } } - fn build_columnar_selection( - &mut self, - display_map: &DisplaySnapshot, - row: u32, - columns: &Range, - reversed: bool, - ) -> Option> { - let is_empty = columns.start == columns.end; - let line_len = display_map.line_len(row); - if columns.start < line_len || (is_empty && columns.start == line_len) { - let start = DisplayPoint::new(row, columns.start); - let end = DisplayPoint::new(row, cmp::min(columns.end, line_len)); - // TODO: Don't expose next_selection_id - Some(Selection { - id: post_inc(&mut self.selections.next_selection_id), - start: start.to_point(display_map), - end: end.to_point(display_map), - reversed, - goal: SelectionGoal::ColumnRange { - start: columns.start, - end: columns.end, - }, - }) - } else { - None - } - } - pub fn set_selections_from_remote( &mut self, selections: Vec>, @@ -5051,7 +5000,7 @@ impl Editor { let mut fold_ranges = Vec::new(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); for selection in selections { let range = selection.display_range(&display_map).sorted(); let buffer_start_row = range.start.to_point(&display_map).row; @@ -5075,7 +5024,7 @@ impl Editor { pub fn unfold_lines(&mut self, _: &UnfoldLines, cx: &mut ViewContext) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let buffer = &display_map.buffer_snapshot; - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let ranges = selections .iter() .map(|s| { @@ -5133,7 +5082,7 @@ impl Editor { } pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext) { - let selections = self.selections.interleaved::(cx); + let selections = self.selections.all::(cx); let ranges = selections.into_iter().map(|s| s.start..s.end); self.fold_ranges(ranges, cx); } @@ -5510,7 +5459,7 @@ impl Editor { } let mut new_selections_by_buffer = HashMap::default(); - for selection in editor.selections.interleaved::(cx) { + for selection in editor.selections.all::(cx) { for (buffer, mut range) in buffer.range_to_buffer_ranges(selection.start..selection.end, cx) { diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 06c11db137..d3d67060f2 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -957,9 +957,10 @@ impl Element for EditorElement { selections.extend(remote_selections); if view.show_local_selections { - let local_selections = view + let mut local_selections = view .selections - .interleaved_in_range(start_anchor..end_anchor, cx); + .disjoint_in_range(start_anchor..end_anchor, cx); + local_selections.extend(view.selections.pending(cx)); for selection in &local_selections { let is_empty = selection.start == selection.end; let selection_start = snapshot.prev_line_boundary(selection.start).1; diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 165f4ca676..4b4df09c3a 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -465,7 +465,7 @@ impl CursorPosition { self.selected_count = 0; let mut last_selection: Option> = None; - for selection in editor.selections.interleaved::(cx) { + for selection in editor.selections.all::(cx) { self.selected_count += selection.end - selection.start; if last_selection .as_ref() diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs index d889d14c14..aabfb676ff 100644 --- a/crates/editor/src/selections_collection.rs +++ b/crates/editor/src/selections_collection.rs @@ -1,5 +1,6 @@ use std::{ - iter, mem, + cell::Ref, + cmp, iter, mem, ops::{Deref, Range, Sub}, sync::Arc, }; @@ -53,8 +54,8 @@ impl SelectionsCollection { self.display_map.update(cx, |map, cx| map.snapshot(cx)) } - fn buffer(&self, cx: &AppContext) -> MultiBufferSnapshot { - self.buffer.read(cx).snapshot(cx) + fn buffer<'a>(&self, cx: &'a AppContext) -> Ref<'a, MultiBufferSnapshot> { + self.buffer.read(cx).read(cx) } pub fn count<'a>(&self) -> usize { @@ -88,7 +89,7 @@ impl SelectionsCollection { self.pending.as_ref().map(|pending| pending.mode.clone()) } - pub fn interleaved<'a, D>(&self, cx: &AppContext) -> Vec> + pub fn all<'a, D>(&self, cx: &AppContext) -> Vec> where D: 'a + TextDimension + Ord + Sub + std::fmt::Debug, { @@ -124,14 +125,14 @@ impl SelectionsCollection { .collect() } - pub fn interleaved_in_range<'a>( + pub fn disjoint_in_range<'a, D>( &self, range: Range, cx: &AppContext, - ) -> Vec> { - // TODO: Make sure pending selection is handled correctly here - // if it is interleaved properly, we can sue resolve_multiple - // to improve performance + ) -> Vec> + where + D: 'a + TextDimension + Ord + Sub + std::fmt::Debug, + { let buffer = self.buffer(cx); let start_ix = match self .disjoint @@ -146,36 +147,16 @@ impl SelectionsCollection { Ok(ix) => ix + 1, Err(ix) => ix, }; - - fn point_selection( - selection: &Selection, - buffer: &MultiBufferSnapshot, - ) -> Selection { - let start = crate::ToPoint::to_point(&selection.start, &buffer); - let end = crate::ToPoint::to_point(&selection.end, &buffer); - Selection { - id: selection.id, - start, - end, - reversed: selection.reversed, - goal: selection.goal, - } - } - - self.disjoint[start_ix..end_ix] - .iter() - .chain(self.pending.as_ref().map(|pending| &pending.selection)) - .map(|s| point_selection(s, &buffer)) - .collect() + resolve_multiple(&self.disjoint[start_ix..end_ix], &buffer).collect() } - pub fn display_interleaved( + pub fn all_display( &mut self, cx: &mut MutableAppContext, ) -> (DisplaySnapshot, Vec>) { let display_map = self.display_map(cx); let selections = self - .interleaved::(cx) + .all::(cx) .into_iter() .map(|selection| selection.map(|point| point.to_display_point(&display_map))) .collect(); @@ -216,14 +197,14 @@ impl SelectionsCollection { &self, cx: &AppContext, ) -> Selection { - self.interleaved(cx).first().unwrap().clone() + self.all(cx).first().unwrap().clone() } pub fn last>( &self, cx: &AppContext, ) -> Selection { - self.interleaved(cx).last().unwrap().clone() + self.all(cx).last().unwrap().clone() } #[cfg(any(test, feature = "test-support"))] @@ -231,7 +212,7 @@ impl SelectionsCollection { &self, cx: &AppContext, ) -> Vec> { - self.interleaved::(cx) + self.all::(cx) .iter() .map(|s| { if s.reversed { @@ -259,6 +240,34 @@ impl SelectionsCollection { .collect() } + pub fn build_columnar_selection( + &mut self, + display_map: &DisplaySnapshot, + row: u32, + columns: &Range, + reversed: bool, + ) -> Option> { + let is_empty = columns.start == columns.end; + let line_len = display_map.line_len(row); + if columns.start < line_len || (is_empty && columns.start == line_len) { + let start = DisplayPoint::new(row, columns.start); + let end = DisplayPoint::new(row, cmp::min(columns.end, line_len)); + + Some(Selection { + id: post_inc(&mut self.next_selection_id), + start: start.to_point(display_map), + end: end.to_point(display_map), + reversed, + goal: SelectionGoal::ColumnRange { + start: columns.start, + end: columns.end, + }, + }) + } else { + None + } + } + pub(crate) fn change_with( &mut self, cx: &mut MutableAppContext, @@ -288,7 +297,7 @@ impl<'a> MutableSelectionsCollection<'a> { self.collection.display_map(self.cx) } - fn buffer(&mut self) -> MultiBufferSnapshot { + fn buffer(&self) -> Ref { self.collection.buffer(self.cx) } @@ -370,7 +379,7 @@ impl<'a> MutableSelectionsCollection<'a> { where T: 'a + ToOffset + ToPoint + TextDimension + Ord + Sub + std::marker::Copy, { - let mut selections = self.interleaved(self.cx); + let mut selections = self.all(self.cx); let mut start = range.start.to_offset(&self.buffer()); let mut end = range.end.to_offset(&self.buffer()); let reversed = if start > end { @@ -527,7 +536,7 @@ impl<'a> MutableSelectionsCollection<'a> { ) { let display_map = self.display_map(); let selections = self - .interleaved::(self.cx) + .all::(self.cx) .into_iter() .map(|selection| { let mut selection = selection.map(|point| point.to_display_point(&display_map)); @@ -595,18 +604,17 @@ impl<'a> MutableSelectionsCollection<'a> { /// was no longer present. The keys of the map are selection ids. The values are /// the id of the new excerpt where the head of the selection has been moved. pub fn refresh(&mut self) -> HashMap { - // TODO: Pull disjoint constraint out of update_selections so we don't have to - // store the pending_selection here. - let buffer = self.buffer(); - let mut pending = self.collection.pending.take(); let mut selections_with_lost_position = HashMap::default(); - let anchors_with_status = buffer.refresh_anchors( - self.disjoint + let anchors_with_status = { + let buffer = self.buffer(); + let disjoint_anchors = self + .disjoint .iter() - .flat_map(|selection| [&selection.start, &selection.end]), - ); + .flat_map(|selection| [&selection.start, &selection.end]); + buffer.refresh_anchors(disjoint_anchors) + }; let adjusted_disjoint: Vec<_> = anchors_with_status .chunks(2) .map(|selection_anchors| { @@ -634,10 +642,13 @@ impl<'a> MutableSelectionsCollection<'a> { .collect(); if !adjusted_disjoint.is_empty() { - self.select::(resolve_multiple(adjusted_disjoint.iter(), &buffer).collect()); + let resolved_selections = + resolve_multiple(adjusted_disjoint.iter(), &self.buffer()).collect(); + self.select::(resolved_selections); } if let Some(pending) = pending.as_mut() { + let buffer = self.buffer(); let anchors = buffer.refresh_anchors([&pending.selection.start, &pending.selection.end]); let (_, start, kept_start) = anchors[0].clone(); diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 36fec6fbfc..2a391676fa 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -130,7 +130,7 @@ fn insert_line_above(_: &mut Workspace, _: &InsertLineAbove, cx: &mut ViewContex vim.switch_mode(Mode::Insert, cx); vim.update_active_editor(cx, |editor, cx| { editor.transact(cx, |editor, cx| { - let (map, old_selections) = editor.selections.display_interleaved(cx); + let (map, old_selections) = editor.selections.all_display(cx); let selection_start_rows: HashSet = old_selections .into_iter() .map(|selection| selection.start.row()) @@ -162,7 +162,7 @@ fn insert_line_below(_: &mut Workspace, _: &InsertLineBelow, cx: &mut ViewContex vim.switch_mode(Mode::Insert, cx); vim.update_active_editor(cx, |editor, cx| { editor.transact(cx, |editor, cx| { - let (map, old_selections) = editor.selections.display_interleaved(cx); + let (map, old_selections) = editor.selections.all_display(cx); let selection_end_rows: HashSet = old_selections .into_iter() .map(|selection| selection.end.row()) diff --git a/crates/vim/src/vim_test_context.rs b/crates/vim/src/vim_test_context.rs index f68e3f26d9..4122c46059 100644 --- a/crates/vim/src/vim_test_context.rs +++ b/crates/vim/src/vim_test_context.rs @@ -200,7 +200,7 @@ impl<'a> VimTestContext<'a> { self.editor.read_with(self.cx, |editor, cx| { let (empty_selections, non_empty_selections): (Vec<_>, Vec<_>) = editor .selections - .interleaved::(cx) + .all::(cx) .into_iter() .partition_map(|selection| { if selection.is_empty() { From a2fd41174f447560e42af5cc66943a312d06a00c Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Fri, 13 May 2022 16:58:30 -0700 Subject: [PATCH 16/18] Reduce accessibility of multibuffer read to reduce risk of borrowing snapshot and buffer refcells twice --- crates/breadcrumbs/src/breadcrumbs.rs | 4 +--- crates/diagnostics/src/diagnostics.rs | 4 ++-- crates/diagnostics/src/items.rs | 2 +- crates/editor/src/multi_buffer.rs | 23 ++++++++++++++++++++++- crates/go_to_line/src/go_to_line.rs | 4 ++-- crates/journal/src/journal.rs | 2 +- crates/outline/src/outline.rs | 4 ++-- crates/search/src/buffer_search.rs | 6 +++--- crates/search/src/project_search.rs | 4 ++-- 9 files changed, 36 insertions(+), 17 deletions(-) diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs index bbd11deac8..2d8089c120 100644 --- a/crates/breadcrumbs/src/breadcrumbs.rs +++ b/crates/breadcrumbs/src/breadcrumbs.rs @@ -39,9 +39,7 @@ impl Breadcrumbs { let editor = self.editor.as_ref()?.read(cx); let cursor = editor.selections.newest_anchor().head(); let multibuffer = &editor.buffer().read(cx); - let (buffer_id, symbols) = multibuffer - .read(cx) - .symbols_containing(cursor, Some(theme))?; + let (buffer_id, symbols) = multibuffer.symbols_containing(cursor, Some(theme), cx)?; let buffer = multibuffer.buffer(buffer_id)?; Some((buffer, symbols)) } diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 5e94bbe055..8f2aa6cea2 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -489,11 +489,11 @@ impl workspace::Item for ProjectDiagnosticsEditor { } fn is_dirty(&self, cx: &AppContext) -> bool { - self.excerpts.read(cx).read(cx).is_dirty() + self.excerpts.read(cx).is_dirty(cx) } fn has_conflict(&self, cx: &AppContext) -> bool { - self.excerpts.read(cx).read(cx).has_conflict() + self.excerpts.read(cx).has_conflict(cx) } fn can_save(&self, _: &AppContext) -> bool { diff --git a/crates/diagnostics/src/items.rs b/crates/diagnostics/src/items.rs index 752fc26f0f..426f25629d 100644 --- a/crates/diagnostics/src/items.rs +++ b/crates/diagnostics/src/items.rs @@ -60,7 +60,7 @@ impl DiagnosticIndicator { let buffer = editor.buffer().read(cx); let cursor_position = editor.selections.newest::(cx).head(); let new_diagnostic = buffer - .read(cx) + .snapshot(cx) .diagnostics_in_range::<_, usize>(cursor_position..cursor_position, false) .filter(|entry| !entry.range.is_empty()) .min_by_key(|entry| (entry.diagnostic.severity, entry.range.len())) diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index 2f41ce09a0..a8e3363cac 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -226,7 +226,7 @@ impl MultiBuffer { self.snapshot.borrow().clone() } - pub fn read(&self, cx: &AppContext) -> Ref { + pub(crate) fn read(&self, cx: &AppContext) -> Ref { self.sync(cx); self.snapshot.borrow() } @@ -255,6 +255,27 @@ impl MultiBuffer { self.subscriptions.subscribe() } + pub fn is_dirty(&self, cx: &AppContext) -> bool { + self.read(cx).is_dirty() + } + + pub fn has_conflict(&self, cx: &AppContext) -> bool { + self.read(cx).has_conflict() + } + + pub fn len(&self, cx: &AppContext) -> usize { + self.read(cx).len() + } + + pub fn symbols_containing( + &self, + offset: T, + theme: Option<&SyntaxTheme>, + cx: &AppContext, + ) -> Option<(usize, Vec>)> { + self.read(cx).symbols_containing(offset, theme) + } + pub fn edit(&mut self, edits: I, cx: &mut ModelContext) where I: IntoIterator, T)>, diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index a2753483b3..bae5ffc46c 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -40,7 +40,7 @@ impl GoToLine { let (scroll_position, cursor_point, max_point) = active_editor.update(cx, |editor, cx| { let scroll_position = editor.scroll_position(cx); - let buffer = editor.buffer().read(cx).read(cx); + let buffer = editor.buffer().read(cx).snapshot(cx); ( Some(scroll_position), editor.selections.newest(cx).head(), @@ -108,7 +108,7 @@ impl GoToLine { match event { editor::Event::Blurred => cx.emit(Event::Dismissed), editor::Event::BufferEdited { .. } => { - let line_editor = self.line_editor.read(cx).buffer().read(cx).read(cx).text(); + let line_editor = self.line_editor.read(cx).text(cx); let mut components = line_editor.trim().split(&[',', ':'][..]); let row = components.next().and_then(|row| row.parse::().ok()); let column = components.next().and_then(|row| row.parse::().ok()); diff --git a/crates/journal/src/journal.rs b/crates/journal/src/journal.rs index dd105fd4e3..13ef3a2420 100644 --- a/crates/journal/src/journal.rs +++ b/crates/journal/src/journal.rs @@ -56,7 +56,7 @@ pub fn new_journal_entry(app_state: Arc, cx: &mut MutableAppContext) { if let Some(Some(Ok(item))) = opened.first() { if let Some(editor) = item.downcast::() { editor.update(&mut cx, |editor, cx| { - let len = editor.buffer().read(cx).read(cx).len(); + let len = editor.buffer().read(cx).len(cx); editor.change_selections(Some(Autoscroll::Center), cx, |s| { s.select_ranges([len..len]) }); diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 47b022304b..57c7441bfe 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -84,7 +84,7 @@ impl OutlineView { .read(cx) .buffer() .read(cx) - .read(cx) + .snapshot(cx) .outline(Some(cx.global::().theme.editor.syntax.as_ref())); if let Some(outline) = buffer { workspace.toggle_modal(cx, |_, cx| { @@ -171,8 +171,8 @@ impl PickerDelegate for OutlineView { .collect(); let editor = self.active_editor.read(cx); - let buffer = editor.buffer().read(cx).read(cx); let cursor_offset = editor.selections.newest::(cx).head(); + let buffer = editor.buffer().read(cx).snapshot(cx); selected_index = self .outline .items diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index ec09fd45b5..5581cbd608 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -265,7 +265,7 @@ impl BufferSearchBar { fn set_query(&mut self, query: &str, cx: &mut ViewContext) { self.query_editor.update(cx, |query_editor, cx| { query_editor.buffer().update(cx, |query_buffer, cx| { - let len = query_buffer.read(cx).len(); + let len = query_buffer.len(cx); query_buffer.edit([(0..len, query)], cx); }); }); @@ -388,7 +388,7 @@ impl BufferSearchBar { &editor.selections.newest_anchor().head(), index, direction, - &editor.buffer().read(cx).read(cx), + &editor.buffer().read(cx).snapshot(cx), ); let range_to_select = ranges[new_index].clone(); editor.unfold_ranges([range_to_select.clone()], false, cx); @@ -565,7 +565,7 @@ impl BufferSearchBar { active_match_index( &ranges, &editor.selections.newest_anchor().head(), - &editor.buffer().read(cx).read(cx), + &editor.buffer().read(cx).snapshot(cx), ) }); if new_index != self.active_match_index { diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 4915d50ec9..636c055f1c 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -457,7 +457,7 @@ impl ProjectSearchView { &results_editor.selections.newest_anchor().head(), index, direction, - &results_editor.buffer().read(cx).read(cx), + &results_editor.buffer().read(cx).snapshot(cx), ); let range_to_select = model.match_ranges[new_index].clone(); self.results_editor.update(cx, |editor, cx| { @@ -515,7 +515,7 @@ impl ProjectSearchView { let new_index = active_match_index( &self.model.read(cx).match_ranges, &results_editor.selections.newest_anchor().head(), - &results_editor.buffer().read(cx).read(cx), + &results_editor.buffer().read(cx).snapshot(cx), ); if self.active_match_index != new_index { self.active_match_index = new_index; From 7d22ede8047231556eb81eb3366c875d89d699fd Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 16 May 2022 15:38:06 -0400 Subject: [PATCH 17/18] Remove the `focused` token Currently we don't have any concept of a true focus state. All states we currently use focus should actually be `active`. Removing this token until we introduce a distinction between active and focused states. --- styles/src/themes/base16.ts | 12 +----------- styles/src/themes/dark.ts | 12 +----------- styles/src/themes/light.ts | 10 ---------- styles/src/themes/theme.ts | 2 -- 4 files changed, 2 insertions(+), 34 deletions(-) diff --git a/styles/src/themes/base16.ts b/styles/src/themes/base16.ts index 98f1fb4878..f2a1909d89 100644 --- a/styles/src/themes/base16.ts +++ b/styles/src/themes/base16.ts @@ -24,55 +24,46 @@ export function createTheme(name: string, isLight: boolean, neutral: ColorToken[ base: neutral[1], hovered: withOpacity(neutral[2], blend), active: withOpacity(neutral[2], blend * 1.5), - focused: withOpacity(neutral[2], blend), }, 300: { base: neutral[1], hovered: withOpacity(neutral[2], blend), active: withOpacity(neutral[2], blend * 1.5), - focused: withOpacity(neutral[2], blend), }, 500: { base: neutral[0], hovered: withOpacity(neutral[1], blend), active: withOpacity(neutral[1], blend * 1.5), - focused: withOpacity(neutral[1], blend), }, on300: { base: neutral[0], hovered: withOpacity(neutral[1], blend), active: withOpacity(neutral[1], blend * 2), - focused: withOpacity(neutral[1], blend), }, on500: { base: neutral[1], hovered: withOpacity(neutral[2], blend), active: withOpacity(neutral[2], blend * 2), - focused: withOpacity(neutral[2], blend), }, ok: { base: withOpacity(accent.green, 0.15), hovered: withOpacity(accent.green, 0.20), active: withOpacity(accent.green, 0.25), - focused: withOpacity(accent.green, 0.20), }, error: { base: withOpacity(accent.red, 0.15), hovered: withOpacity(accent.red, 0.20), active: withOpacity(accent.red, 0.25), - focused: withOpacity(accent.red, 0.20), }, warning: { base: withOpacity(accent.yellow, 0.15), hovered: withOpacity(accent.yellow, 0.20), active: withOpacity(accent.yellow, 0.25), - focused: withOpacity(accent.yellow, 0.20), }, info: { base: withOpacity(accent.blue, 0.15), hovered: withOpacity(accent.blue, 0.20), active: withOpacity(accent.blue, 0.25), - focused: withOpacity(accent.blue, 0.20), }, }; @@ -80,7 +71,6 @@ export function createTheme(name: string, isLight: boolean, neutral: ColorToken[ primary: neutral[0], secondary: neutral[1], muted: neutral[3], - focused: neutral[3], active: neutral[3], onMedia: withOpacity(neutral[0], 0.1), ok: withOpacity(accent.green, 0.15), @@ -131,7 +121,7 @@ export function createTheme(name: string, isLight: boolean, neutral: ColorToken[ matchingBracket: backgroundColor[500].active, match: withOpacity(accent.violet, blend * 2), activeMatch: withOpacity(accent.violet, blend * 3), - related: backgroundColor[500].focused, + related: backgroundColor[500].hovered, }, gutter: { primary: textColor.placeholder, diff --git a/styles/src/themes/dark.ts b/styles/src/themes/dark.ts index 77eb493591..8614414fa7 100644 --- a/styles/src/themes/dark.ts +++ b/styles/src/themes/dark.ts @@ -7,55 +7,46 @@ const backgroundColor = { base: colors.neutral[750], hovered: colors.neutral[725], active: colors.neutral[800], - focused: colors.neutral[675], }, 300: { base: colors.neutral[800], hovered: colors.neutral[775], active: colors.neutral[750], - focused: colors.neutral[775], }, 500: { base: colors.neutral[900], hovered: withOpacity(colors.neutral[0], 0.08), active: withOpacity(colors.neutral[0], 0.12), - focused: colors.neutral[825], }, on300: { base: withOpacity(colors.neutral[850], 0.5), hovered: colors.neutral[875], active: colors.neutral[900], - focused: colors.neutral[875], }, on500: { base: colors.neutral[850], hovered: colors.neutral[800], active: colors.neutral[775], - focused: colors.neutral[800], }, ok: { base: withOpacity(colors.green[600], 0.15), hovered: withOpacity(colors.green[600], 0.20), active: withOpacity(colors.green[600], 0.25), - focused: withOpacity(colors.green[600], 0.20), }, error: { base: withOpacity(colors.red[600], 0.15), hovered: withOpacity(colors.red[600], 0.20), active: withOpacity(colors.red[600], 0.25), - focused: withOpacity(colors.red[600], 0.20), }, warning: { base: withOpacity(colors.amber[400], 0.15), hovered: withOpacity(colors.amber[400], 0.20), active: withOpacity(colors.amber[400], 0.25), - focused: withOpacity(colors.amber[400], 0.20), }, info: { base: withOpacity(colors.blue[500], 0.15), hovered: withOpacity(colors.blue[500], 0.20), active: withOpacity(colors.blue[500], 0.25), - focused: withOpacity(colors.blue[500], 0.20), }, }; @@ -63,7 +54,6 @@ const borderColor = { primary: colors.neutral[875], secondary: colors.neutral[775], muted: colors.neutral[675], - focused: colors.indigo[500], active: colors.neutral[900], onMedia: withOpacity(colors.neutral[875], 0.1), ok: withOpacity(colors.green[600], 0.15), @@ -127,7 +117,7 @@ const editor = { matchingBracket: backgroundColor[500].active, match: withOpacity(colors.violet[700], 0.5), activeMatch: withOpacity(colors.violet[600], 0.7), - related: backgroundColor[500].focused, + related: backgroundColor[500].hovered, }, gutter: { primary: textColor.placeholder, diff --git a/styles/src/themes/light.ts b/styles/src/themes/light.ts index a244267f46..c2eecf5391 100644 --- a/styles/src/themes/light.ts +++ b/styles/src/themes/light.ts @@ -7,55 +7,46 @@ const backgroundColor = { base: colors.neutral[75], hovered: colors.neutral[100], active: colors.neutral[150], - focused: colors.neutral[100], }, 300: { base: colors.neutral[25], hovered: colors.neutral[75], active: colors.neutral[100], - focused: colors.neutral[75], }, 500: { base: colors.neutral[0], hovered: withOpacity(colors.neutral[900], 0.03), active: withOpacity(colors.neutral[900], 0.06), - focused: colors.neutral[50], }, on300: { base: colors.neutral[50], hovered: colors.neutral[100], active: colors.neutral[150], - focused: colors.neutral[100], }, on500: { base: colors.neutral[50], hovered: colors.neutral[25], active: colors.neutral[0], - focused: colors.neutral[25], }, ok: { base: withOpacity(colors.green[600], 0.15), hovered: withOpacity(colors.green[600], 0.20), active: withOpacity(colors.green[600], 0.25), - focused: withOpacity(colors.green[600], 0.20), }, error: { base: withOpacity(colors.red[600], 0.15), hovered: withOpacity(colors.red[600], 0.20), active: withOpacity(colors.red[600], 0.25), - focused: withOpacity(colors.red[600], 0.20), }, warning: { base: withOpacity(colors.amber[400], 0.15), hovered: withOpacity(colors.amber[400], 0.20), active: withOpacity(colors.amber[400], 0.25), - focused: withOpacity(colors.amber[400], 0.20), }, info: { base: withOpacity(colors.blue[500], 0.15), hovered: withOpacity(colors.blue[500], 0.20), active: withOpacity(colors.blue[500], 0.25), - focused: withOpacity(colors.blue[500], 0.20), }, }; @@ -63,7 +54,6 @@ const borderColor = { primary: colors.neutral[150], secondary: colors.neutral[150], muted: colors.neutral[100], - focused: colors.indigo[500], active: colors.neutral[250], onMedia: withOpacity(colors.neutral[250], 0.3), ok: withOpacity(colors.green[600], 0.15), diff --git a/styles/src/themes/theme.ts b/styles/src/themes/theme.ts index 7113ee555c..d1196d21fa 100644 --- a/styles/src/themes/theme.ts +++ b/styles/src/themes/theme.ts @@ -32,7 +32,6 @@ export interface BackgroundColorSet { base: ColorToken; hovered: ColorToken; active: ColorToken; - focused: ColorToken; } export interface Syntax { @@ -85,7 +84,6 @@ export default interface Theme { primary: ColorToken; secondary: ColorToken; muted: ColorToken; - focused: ColorToken; active: ColorToken; /** * Used for rendering borders on top of media like avatars, images, video, etc. From af5bb92847b9f6db0763efc21a8e1aa6b496fdb1 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 16 May 2022 18:11:22 -0400 Subject: [PATCH 18/18] Rework color schemes Co-Authored-By: Keith Simmons --- assets/themes/cave-dark.json | 86 +- assets/themes/cave-light.json | 154 +-- assets/themes/dark.json | 1734 -------------------------- assets/themes/light.json | 1734 -------------------------- assets/themes/solarized-dark.json | 86 +- assets/themes/solarized-light.json | 154 +-- assets/themes/sulphurpool-dark.json | 86 +- assets/themes/sulphurpool-light.json | 154 +-- crates/theme/src/theme.rs | 2 +- styles/dist/dark.json | 405 ++---- styles/dist/light.json | 403 ++---- styles/dist/solarized-dark.json | 40 - styles/dist/solarized-light.json | 40 - styles/dist/tokens.json | 892 ++++--------- styles/src/buildThemes.ts | 11 +- styles/src/buildTokens.ts | 4 +- styles/src/themes/base16.ts | 202 +-- styles/src/themes/cave.ts | 40 +- styles/src/themes/dark.ts | 230 ---- styles/src/themes/gruvbox.ts | 30 + styles/src/themes/light.ts | 230 ---- styles/src/themes/solarized.ts | 40 +- styles/src/themes/sulphurpool.ts | 40 +- styles/src/themes/theme.ts | 3 - 24 files changed, 1030 insertions(+), 5770 deletions(-) delete mode 100644 assets/themes/dark.json delete mode 100644 assets/themes/light.json delete mode 100644 styles/src/themes/dark.ts create mode 100644 styles/src/themes/gruvbox.ts delete mode 100644 styles/src/themes/light.ts diff --git a/assets/themes/cave-dark.json b/assets/themes/cave-dark.json index 13eb8f2473..bbb7130f75 100644 --- a/assets/themes/cave-dark.json +++ b/assets/themes/cave-dark.json @@ -23,7 +23,7 @@ "size": 14 }, "active": { - "background": "#5852605c", + "background": "#3f3b45", "text": { "family": "Zed Sans", "color": "#e2dfe7", @@ -31,7 +31,7 @@ } }, "hover": { - "background": "#5852603d" + "background": "#332f38" } }, "border": { @@ -215,7 +215,7 @@ "size": 14 }, "icon_color": "#e2dfe7", - "background": "#5852603d" + "background": "#332f38" } }, "diagnostic_message": { @@ -288,7 +288,7 @@ "left": 7, "right": 7 }, - "background": "#5852603d" + "background": "#332f38" }, "container_warning": { "corner_radius": 6, @@ -335,11 +335,11 @@ "icon_color": "#8b8792", "hover": { "icon_color": "#e2dfe7", - "background": "#5852603d" + "background": "#332f38" }, "active": { "icon_color": "#efecf4", - "background": "#5852605c" + "background": "#3f3b45" } }, "badge": { @@ -361,7 +361,7 @@ "avatar_width": 18, "avatar_margin": 8, "height": 33, - "background": "#26232a", + "background": "#332f38", "padding": { "left": 80, "right": 6 @@ -426,15 +426,15 @@ }, "color": "#8b8792", "hover": { - "background": "#5852603d", + "background": "#3f3b45", "color": "#8b8792" }, "active": { - "background": "#5852605c", + "background": "#4c4653", "color": "#efecf4" }, "active_hover": { - "background": "#5852603d", + "background": "#3f3b45", "color": "#efecf4" } }, @@ -515,16 +515,16 @@ "editor": { "text_color": "#efecf4", "background": "#19171c", - "active_line_background": "#efecf412", + "active_line_background": "#26232a", "code_actions_indicator": "#8b8792", "diff_background_deleted": "#be467826", "diff_background_inserted": "#2a929226", - "document_highlight_read_background": "#efecf41f", - "document_highlight_write_background": "#efecf43d", + "document_highlight_read_background": "#5852603d", + "document_highlight_write_background": "#5852607a", "error_color": "#be4678", "gutter_background": "#19171c", "gutter_padding_factor": 3.5, - "highlighted_line_background": "#efecf41f", + "highlighted_line_background": "#332f38", "line_number": "#7e7887", "line_number_active": "#efecf4", "rename_fade": 0.6, @@ -588,7 +588,7 @@ "right": 6, "top": 2 }, - "background": "#26232a3d" + "background": "#1c1a20" }, "margin": { "left": -14 @@ -606,7 +606,7 @@ "right": 6, "top": 2 }, - "background": "#26232a5c" + "background": "#201d23" } }, "diagnostic_header": { @@ -642,7 +642,7 @@ } }, "diagnostic_path_header": { - "background": "#efecf412", + "background": "#26232a", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", @@ -852,7 +852,7 @@ "weight": "normal" }, "punctuation": { - "color": "#8b8792", + "color": "#e2dfe7", "weight": "normal" }, "constant": { @@ -989,7 +989,7 @@ "size": 14 }, "hover": { - "background": "#5852603d", + "background": "#332f38", "text": { "family": "Zed Mono", "color": "#e2dfe7", @@ -997,7 +997,7 @@ } }, "active": { - "background": "#5852605c", + "background": "#3f3b45", "text": { "family": "Zed Mono", "color": "#e2dfe7", @@ -1005,7 +1005,7 @@ } }, "active_hover": { - "background": "#5852603d", + "background": "#332f38", "text": { "family": "Zed Mono", "color": "#efecf4", @@ -1014,7 +1014,7 @@ } }, "filename_editor": { - "background": "#26232a5c", + "background": "#201d23", "text": { "family": "Zed Mono", "color": "#e2dfe7", @@ -1098,7 +1098,7 @@ "right": 8 } }, - "background": "#5852603d", + "background": "#332f38", "corner_radius": 6 }, "active_item": { @@ -1133,7 +1133,7 @@ "right": 8 } }, - "background": "#5852603d", + "background": "#332f38", "corner_radius": 6 }, "menu": { @@ -1307,7 +1307,7 @@ "family": "Zed Mono", "color": "#e2dfe7", "size": 14, - "background": "#5852605c" + "background": "#4c4653" } }, "contact_row": { @@ -1316,7 +1316,7 @@ "right": 12 }, "active": { - "background": "#5852605c" + "background": "#4c4653" } }, "tree_branch": { @@ -1343,17 +1343,17 @@ }, "contact_button_spacing": 8, "contact_button": { - "background": "#26232a", + "background": "#332f38", "color": "#e2dfe7", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#5852603d" + "background": "#3f3b45" } }, "disabled_contact_button": { - "background": "#26232a", + "background": "#332f38", "color": "#8b8792", "icon_width": 8, "button_width": 16, @@ -1387,10 +1387,10 @@ }, "background": "#26232a", "hover": { - "background": "#5852603d" + "background": "#332f38" }, "active": { - "background": "#5852605c" + "background": "#3f3b45" } }, "unshared_project_row": { @@ -1421,10 +1421,10 @@ }, "background": "#26232a", "hover": { - "background": "#5852603d" + "background": "#332f38" }, "active": { - "background": "#5852605c" + "background": "#3f3b45" } } }, @@ -1452,7 +1452,7 @@ "size": 14 }, "active": { - "background": "#5852605c", + "background": "#3f3b45", "text": { "family": "Zed Sans", "color": "#e2dfe7", @@ -1460,7 +1460,7 @@ } }, "hover": { - "background": "#5852603d" + "background": "#332f38" } }, "border": { @@ -1527,17 +1527,17 @@ } }, "contact_button": { - "background": "#26232a", + "background": "#332f38", "color": "#e2dfe7", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#5852603d" + "background": "#3f3b45" } }, "disabled_contact_button": { - "background": "#26232a", + "background": "#332f38", "color": "#8b8792", "icon_width": 8, "button_width": 16, @@ -1545,14 +1545,14 @@ } }, "search": { - "match_background": "#955ae77a", + "match_background": "#3d1576", "tab_icon_spacing": 8, "tab_icon_width": 14, "option_button": { "family": "Zed Mono", "color": "#8b8792", "size": 14, - "background": "#26232a", + "background": "#332f38", "corner_radius": 6, "border": { "color": "#26232a", @@ -1571,7 +1571,7 @@ "family": "Zed Mono", "color": "#efecf4", "size": 14, - "background": "#5852607a", + "background": "#4c4653", "border": { "color": "#655f6d", "width": 1 @@ -1581,7 +1581,7 @@ "family": "Zed Mono", "color": "#efecf4", "size": 14, - "background": "#5852603d", + "background": "#3f3b45", "border": { "color": "#655f6d", "width": 1 @@ -1717,7 +1717,7 @@ "left": 6 }, "hover": { - "background": "#26232a3d" + "background": "#1c1a20" } }, "dismiss_button": { diff --git a/assets/themes/cave-light.json b/assets/themes/cave-light.json index 097d2755aa..96ceb3b1a9 100644 --- a/assets/themes/cave-light.json +++ b/assets/themes/cave-light.json @@ -23,7 +23,7 @@ "size": 14 }, "active": { - "background": "#8b87922e", + "background": "#b7b3bd", "text": { "family": "Zed Sans", "color": "#26232a", @@ -31,11 +31,11 @@ } }, "hover": { - "background": "#8b87921f" + "background": "#ccc9d2" } }, "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1 }, "empty": { @@ -69,7 +69,7 @@ "size": 14 }, "border": { - "color": "#e2dfe7", + "color": "#8b8792", "width": 1 }, "padding": { @@ -107,7 +107,7 @@ "size": 14 }, "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "left": true, "bottom": true, @@ -133,7 +133,7 @@ "size": 14 }, "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "left": true, "bottom": false, @@ -152,13 +152,13 @@ "cursor": "Arrow" }, "sidebar_resize_handle": { - "background": "#efecf4", + "background": "#8b8792", "padding": { "left": 1 } }, "pane_divider": { - "color": "#e2dfe7", + "color": "#8b8792", "width": 1 }, "status_bar": { @@ -171,7 +171,7 @@ "right": 6 }, "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "top": true, "overlay": true @@ -215,7 +215,7 @@ "size": 14 }, "icon_color": "#26232a", - "background": "#8b87921f" + "background": "#ccc9d2" } }, "diagnostic_message": { @@ -288,7 +288,7 @@ "left": 7, "right": 7 }, - "background": "#8b87921f" + "background": "#ccc9d2" }, "container_warning": { "corner_radius": 6, @@ -335,11 +335,11 @@ "icon_color": "#585260", "hover": { "icon_color": "#26232a", - "background": "#8b87921f" + "background": "#ccc9d2" }, "active": { "icon_color": "#19171c", - "background": "#8b87922e" + "background": "#b7b3bd" } }, "badge": { @@ -361,7 +361,7 @@ "avatar_width": 18, "avatar_margin": 8, "height": 33, - "background": "#e2dfe7", + "background": "#ccc9d2", "padding": { "left": 80, "right": 6 @@ -383,14 +383,14 @@ "width": 12 }, "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "bottom": true, "overlay": true }, "sign_in_prompt": { "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1 }, "corner_radius": 6, @@ -426,15 +426,15 @@ }, "color": "#585260", "hover": { - "background": "#8b87921f", + "background": "#b7b3bd", "color": "#585260" }, "active": { - "background": "#8b87922e", + "background": "#a19da7", "color": "#19171c" }, "active_hover": { - "background": "#8b87921f", + "background": "#b7b3bd", "color": "#19171c" } }, @@ -458,7 +458,7 @@ "height": 34, "background": "#efecf4", "border": { - "color": "#e2dfe7", + "color": "#8b8792", "width": 1, "bottom": true }, @@ -492,7 +492,7 @@ "corner_radius": 6, "padding": 12, "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1 }, "shadow": { @@ -515,16 +515,16 @@ "editor": { "text_color": "#19171c", "background": "#efecf4", - "active_line_background": "#19171c12", + "active_line_background": "#e2dfe7", "code_actions_indicator": "#585260", "diff_background_deleted": "#be467826", "diff_background_inserted": "#2a929226", - "document_highlight_read_background": "#19171c0f", - "document_highlight_write_background": "#19171c1f", + "document_highlight_read_background": "#8b87921f", + "document_highlight_write_background": "#8b87923d", "error_color": "#be4678", "gutter_background": "#efecf4", "gutter_padding_factor": 3.5, - "highlighted_line_background": "#19171c1f", + "highlighted_line_background": "#ccc9d2", "line_number": "#655f6d", "line_number_active": "#19171c", "rename_fade": 0.6, @@ -568,7 +568,7 @@ "corner_radius": 8, "padding": 4, "border": { - "color": "#e2dfe7", + "color": "#8b8792", "width": 1 }, "item": { @@ -588,7 +588,7 @@ "right": 6, "top": 2 }, - "background": "#e2dfe71f" + "background": "#ece9f1" }, "margin": { "left": -14 @@ -606,7 +606,7 @@ "right": 6, "top": 2 }, - "background": "#e2dfe72e" + "background": "#e9e6ee" } }, "diagnostic_header": { @@ -614,7 +614,7 @@ "icon_width_factor": 1.5, "text_scale_factor": 0.857, "border": { - "color": "#e2dfe7", + "color": "#8b8792", "width": 1, "bottom": true, "top": true @@ -642,7 +642,7 @@ } }, "diagnostic_path_header": { - "background": "#19171c12", + "background": "#e2dfe7", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", @@ -662,7 +662,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "top": true } @@ -685,7 +685,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "top": true } @@ -708,7 +708,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "top": true } @@ -731,7 +731,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "top": true } @@ -754,7 +754,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "top": true } @@ -777,7 +777,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "top": true } @@ -800,7 +800,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "top": true } @@ -823,7 +823,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1, "top": true } @@ -852,7 +852,7 @@ "weight": "normal" }, "punctuation": { - "color": "#585260", + "color": "#26232a", "weight": "normal" }, "constant": { @@ -949,7 +949,7 @@ "corner_radius": 4, "background": "#efecf4", "border": { - "color": "#e2dfe7", + "color": "#8b8792", "width": 1 }, "padding": { @@ -989,7 +989,7 @@ "size": 14 }, "hover": { - "background": "#8b87921f", + "background": "#ccc9d2", "text": { "family": "Zed Mono", "color": "#26232a", @@ -997,7 +997,7 @@ } }, "active": { - "background": "#8b87922e", + "background": "#b7b3bd", "text": { "family": "Zed Mono", "color": "#26232a", @@ -1005,7 +1005,7 @@ } }, "active_hover": { - "background": "#8b87921f", + "background": "#ccc9d2", "text": { "family": "Zed Mono", "color": "#19171c", @@ -1014,7 +1014,7 @@ } }, "filename_editor": { - "background": "#e2dfe72e", + "background": "#e9e6ee", "text": { "family": "Zed Mono", "color": "#26232a", @@ -1098,7 +1098,7 @@ "right": 8 } }, - "background": "#8b87921f", + "background": "#ccc9d2", "corner_radius": 6 }, "active_item": { @@ -1133,7 +1133,7 @@ "right": 8 } }, - "background": "#8b87921f", + "background": "#ccc9d2", "corner_radius": 6 }, "menu": { @@ -1141,7 +1141,7 @@ "corner_radius": 6, "padding": 4, "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1 }, "shadow": { @@ -1232,7 +1232,7 @@ "selection": "#576ddb3d" }, "border": { - "color": "#e2dfe7", + "color": "#8b8792", "width": 1 }, "padding": { @@ -1266,7 +1266,7 @@ "selection": "#576ddb3d" }, "border": { - "color": "#e2dfe7", + "color": "#8b8792", "width": 1 }, "padding": { @@ -1307,7 +1307,7 @@ "family": "Zed Mono", "color": "#26232a", "size": 14, - "background": "#8b87922e" + "background": "#a19da7" } }, "contact_row": { @@ -1316,17 +1316,17 @@ "right": 12 }, "active": { - "background": "#8b87922e" + "background": "#a19da7" } }, "tree_branch": { - "color": "#7e7887", + "color": "#655f6d", "width": 1, "hover": { - "color": "#7e7887" + "color": "#655f6d" }, "active": { - "color": "#7e7887" + "color": "#655f6d" } }, "contact_avatar": { @@ -1343,17 +1343,17 @@ }, "contact_button_spacing": 8, "contact_button": { - "background": "#e2dfe7", + "background": "#ccc9d2", "color": "#26232a", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#8b87921f" + "background": "#b7b3bd" } }, "disabled_contact_button": { - "background": "#e2dfe7", + "background": "#ccc9d2", "color": "#585260", "icon_width": 8, "button_width": 16, @@ -1387,10 +1387,10 @@ }, "background": "#e2dfe7", "hover": { - "background": "#8b87921f" + "background": "#ccc9d2" }, "active": { - "background": "#8b87922e" + "background": "#b7b3bd" } }, "unshared_project_row": { @@ -1421,10 +1421,10 @@ }, "background": "#e2dfe7", "hover": { - "background": "#8b87921f" + "background": "#ccc9d2" }, "active": { - "background": "#8b87922e" + "background": "#b7b3bd" } } }, @@ -1452,7 +1452,7 @@ "size": 14 }, "active": { - "background": "#8b87922e", + "background": "#b7b3bd", "text": { "family": "Zed Sans", "color": "#26232a", @@ -1460,11 +1460,11 @@ } }, "hover": { - "background": "#8b87921f" + "background": "#ccc9d2" } }, "border": { - "color": "#efecf4", + "color": "#8b8792", "width": 1 }, "empty": { @@ -1498,7 +1498,7 @@ "size": 14 }, "border": { - "color": "#e2dfe7", + "color": "#8b8792", "width": 1 }, "padding": { @@ -1527,17 +1527,17 @@ } }, "contact_button": { - "background": "#e2dfe7", + "background": "#ccc9d2", "color": "#26232a", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#8b87921f" + "background": "#b7b3bd" } }, "disabled_contact_button": { - "background": "#e2dfe7", + "background": "#ccc9d2", "color": "#585260", "icon_width": 8, "button_width": 16, @@ -1545,17 +1545,17 @@ } }, "search": { - "match_background": "#955ae73d", + "match_background": "#d5bdfa", "tab_icon_spacing": 8, "tab_icon_width": 14, "option_button": { "family": "Zed Mono", "color": "#585260", "size": 14, - "background": "#e2dfe7", + "background": "#ccc9d2", "corner_radius": 6, "border": { - "color": "#e2dfe7", + "color": "#8b8792", "width": 1 }, "margin": { @@ -1571,9 +1571,9 @@ "family": "Zed Mono", "color": "#19171c", "size": 14, - "background": "#8b87923d", + "background": "#a19da7", "border": { - "color": "#7e7887", + "color": "#655f6d", "width": 1 } }, @@ -1581,9 +1581,9 @@ "family": "Zed Mono", "color": "#19171c", "size": 14, - "background": "#8b87921f", + "background": "#b7b3bd", "border": { - "color": "#7e7887", + "color": "#655f6d", "width": 1 } } @@ -1608,7 +1608,7 @@ "size": 14 }, "border": { - "color": "#e2dfe7", + "color": "#8b8792", "width": 1 }, "margin": { @@ -1717,7 +1717,7 @@ "left": 6 }, "hover": { - "background": "#e2dfe71f" + "background": "#ece9f1" } }, "dismiss_button": { diff --git a/assets/themes/dark.json b/assets/themes/dark.json deleted file mode 100644 index c4e33765ce..0000000000 --- a/assets/themes/dark.json +++ /dev/null @@ -1,1734 +0,0 @@ -{ - "picker": { - "background": "#1c1c1c", - "corner_radius": 8, - "padding": 8, - "item": { - "padding": { - "bottom": 4, - "left": 12, - "right": 12, - "top": 4 - }, - "corner_radius": 8, - "text": { - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#4f8ff7", - "weight": "bold", - "size": 14 - }, - "active": { - "background": "#2b2b2b", - "text": { - "family": "Zed Sans", - "color": "#f1f1f1", - "size": 14 - } - }, - "hover": { - "background": "#232323" - } - }, - "border": { - "color": "#070707", - "width": 1 - }, - "empty": { - "text": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - }, - "padding": { - "bottom": 4, - "left": 12, - "right": 12, - "top": 8 - } - }, - "input_editor": { - "background": "#000000", - "corner_radius": 8, - "placeholder_text": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "text": { - "family": "Zed Mono", - "color": "#f1f1f1", - "size": 14 - }, - "border": { - "color": "#232323", - "width": 1 - }, - "padding": { - "bottom": 7, - "left": 16, - "right": 16, - "top": 7 - } - }, - "shadow": { - "blur": 16, - "color": "#00000052", - "offset": [ - 0, - 2 - ] - } - }, - "workspace": { - "background": "#1c1c1c", - "leader_border_opacity": 0.7, - "leader_border_width": 2, - "tab": { - "height": 32, - "background": "#1c1c1c", - "icon_close": "#555555", - "icon_close_active": "#ffffff", - "icon_conflict": "#f6a724", - "icon_dirty": "#135acd", - "icon_width": 8, - "spacing": 8, - "text": { - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 14 - }, - "border": { - "color": "#070707", - "width": 1, - "left": true, - "bottom": true, - "overlay": true - }, - "padding": { - "left": 8, - "right": 8 - } - }, - "active_tab": { - "height": 32, - "background": "#000000", - "icon_close": "#555555", - "icon_close_active": "#ffffff", - "icon_conflict": "#f6a724", - "icon_dirty": "#135acd", - "icon_width": 8, - "spacing": 8, - "text": { - "family": "Zed Sans", - "color": "#ffffff", - "size": 14 - }, - "border": { - "color": "#070707", - "width": 1, - "left": true, - "bottom": false, - "overlay": true - }, - "padding": { - "left": 8, - "right": 8 - } - }, - "modal": { - "margin": { - "bottom": 52, - "top": 52 - }, - "cursor": "Arrow" - }, - "sidebar_resize_handle": { - "background": "#070707", - "padding": { - "left": 1 - } - }, - "pane_divider": { - "color": "#232323", - "width": 1 - }, - "status_bar": { - "height": 30, - "item_spacing": 8, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "border": { - "color": "#070707", - "width": 1, - "top": true, - "overlay": true - }, - "cursor_position": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "auto_update_progress_message": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "auto_update_done_message": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "lsp_status": { - "corner_radius": 6, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "icon_spacing": 4, - "icon_width": 14, - "height": 18, - "message": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "icon_color": "#555555", - "hover": { - "message": { - "family": "Zed Sans", - "color": "#f1f1f1", - "size": 14 - }, - "icon_color": "#c6c6c6", - "background": "#232323" - } - }, - "diagnostic_message": { - "family": "Zed Sans", - "color": "#808080", - "size": 14, - "hover": { - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 14 - } - }, - "diagnostic_summary": { - "height": 16, - "icon_width": 14, - "icon_spacing": 2, - "summary_spacing": 6, - "text": { - "family": "Zed Sans", - "color": "#f1f1f1", - "size": 14 - }, - "icon_color_ok": "#9c9c9c", - "icon_color_warning": "#f6a724", - "icon_color_error": "#eb2d2d", - "container_ok": { - "corner_radius": 6, - "padding": { - "top": 3, - "bottom": 3, - "left": 7, - "right": 7 - } - }, - "container_warning": { - "corner_radius": 6, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "background": "#f6a72426", - "border": { - "color": "#f6a72426", - "width": 1 - } - }, - "container_error": { - "corner_radius": 6, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "background": "#c9181826", - "border": { - "color": "#eb2d2d26", - "width": 1 - } - }, - "hover": { - "icon_color_ok": "#c6c6c6", - "container_ok": { - "corner_radius": 6, - "padding": { - "top": 3, - "bottom": 3, - "left": 7, - "right": 7 - }, - "background": "#232323" - }, - "container_warning": { - "corner_radius": 6, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "background": "#f6a72433", - "border": { - "color": "#f6a72426", - "width": 1 - } - }, - "container_error": { - "corner_radius": 6, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "background": "#c9181833", - "border": { - "color": "#eb2d2d26", - "width": 1 - } - } - } - }, - "sidebar_buttons": { - "group_left": {}, - "group_right": {}, - "item": { - "corner_radius": 6, - "padding": { - "top": 3, - "bottom": 3, - "left": 6, - "right": 6 - }, - "icon_size": 14, - "icon_color": "#9c9c9c", - "hover": { - "icon_color": "#c6c6c6", - "background": "#232323" - }, - "active": { - "icon_color": "#ffffff", - "background": "#2b2b2b" - } - }, - "badge": { - "corner_radius": 3, - "padding": 2, - "margin": { - "bottom": -1, - "right": -1 - }, - "border": { - "width": 1, - "color": "#1c1c1c" - }, - "background": "#2472f2" - } - } - }, - "titlebar": { - "avatar_width": 18, - "avatar_margin": 8, - "height": 33, - "background": "#2b2b2b", - "padding": { - "left": 80, - "right": 6 - }, - "title": { - "family": "Zed Sans", - "color": "#f1f1f1", - "size": 14 - }, - "avatar": { - "corner_radius": 10, - "border": { - "color": "#00000088", - "width": 1 - } - }, - "avatar_ribbon": { - "height": 3, - "width": 12 - }, - "border": { - "color": "#070707", - "width": 1, - "bottom": true, - "overlay": true - }, - "sign_in_prompt": { - "border": { - "color": "#070707", - "width": 1 - }, - "corner_radius": 6, - "margin": { - "top": 1 - }, - "padding": { - "left": 6, - "right": 6 - }, - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 12, - "hover": { - "family": "Zed Sans", - "color": "#ffffff", - "size": 12 - } - }, - "offline_icon": { - "color": "#9c9c9c", - "width": 16, - "padding": { - "right": 4 - } - }, - "share_icon": { - "corner_radius": 6, - "margin": { - "top": 3, - "bottom": 2, - "left": 6 - }, - "color": "#9c9c9c", - "hover": { - "background": "#323232", - "color": "#9c9c9c" - }, - "active": { - "background": "#1c1c1c", - "color": "#ffffff" - }, - "active_hover": { - "background": "#323232", - "color": "#ffffff" - } - }, - "outdated_warning": { - "family": "Zed Sans", - "color": "#f7bb57", - "size": 12, - "background": "#f6a72426", - "border": { - "color": "#f6a72426", - "width": 1 - }, - "padding": { - "left": 6, - "right": 6 - }, - "corner_radius": 6 - } - }, - "toolbar": { - "height": 34, - "background": "#000000", - "border": { - "color": "#232323", - "width": 1, - "bottom": true - }, - "item_spacing": 8, - "padding": { - "left": 16, - "right": 8, - "top": 4, - "bottom": 4 - } - }, - "breadcrumbs": { - "family": "Zed Mono", - "color": "#9c9c9c", - "size": 14, - "padding": { - "left": 6 - } - }, - "disconnected_overlay": { - "family": "Zed Sans", - "color": "#ffffff", - "size": 14, - "background": "#000000aa" - }, - "notification": { - "margin": { - "top": 10 - }, - "background": "#1c1c1c", - "corner_radius": 6, - "padding": 12, - "border": { - "color": "#070707", - "width": 1 - }, - "shadow": { - "blur": 16, - "color": "#00000052", - "offset": [ - 0, - 2 - ] - } - }, - "notifications": { - "width": 380, - "margin": { - "right": 10, - "bottom": 10 - } - } - }, - "editor": { - "text_color": "#d5d5d5", - "background": "#000000", - "active_line_background": "#ffffff12", - "code_actions_indicator": "#555555", - "diff_background_deleted": "#c9181826", - "diff_background_inserted": "#1b944726", - "document_highlight_read_background": "#ffffff1f", - "document_highlight_write_background": "#ffffff29", - "error_color": "#f15656", - "gutter_background": "#000000", - "gutter_padding_factor": 3.5, - "highlighted_line_background": "#ffffff1f", - "line_number": "#474747", - "line_number_active": "#ffffff", - "rename_fade": 0.6, - "unnecessary_code_fade": 0.5, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "guest_selections": [ - { - "cursor": "#79ba16", - "selection": "#79ba163d" - }, - { - "cursor": "#d430e0", - "selection": "#d430e03d" - }, - { - "cursor": "#ee670a", - "selection": "#ee670a3d" - }, - { - "cursor": "#993bf3", - "selection": "#993bf33d" - }, - { - "cursor": "#16d6c1", - "selection": "#16d6c13d" - }, - { - "cursor": "#ef59a3", - "selection": "#ef59a33d" - }, - { - "cursor": "#f7bf17", - "selection": "#f7bf173d" - } - ], - "autocomplete": { - "background": "#000000", - "corner_radius": 8, - "padding": 4, - "border": { - "color": "#232323", - "width": 1 - }, - "item": { - "corner_radius": 6, - "padding": { - "bottom": 2, - "left": 6, - "right": 6, - "top": 2 - } - }, - "hovered_item": { - "corner_radius": 6, - "padding": { - "bottom": 2, - "left": 6, - "right": 6, - "top": 2 - }, - "background": "#ffffff14" - }, - "margin": { - "left": -14 - }, - "match_highlight": { - "family": "Zed Mono", - "color": "#4f8ff7", - "size": 14 - }, - "selected_item": { - "corner_radius": 6, - "padding": { - "bottom": 2, - "left": 6, - "right": 6, - "top": 2 - }, - "background": "#ffffff1f" - } - }, - "diagnostic_header": { - "background": "#1c1c1c", - "icon_width_factor": 1.5, - "text_scale_factor": 0.857, - "border": { - "color": "#232323", - "width": 1, - "bottom": true, - "top": true - }, - "code": { - "family": "Zed Mono", - "color": "#808080", - "size": 14, - "margin": { - "left": 10 - } - }, - "message": { - "highlight_text": { - "family": "Zed Sans", - "color": "#f1f1f1", - "size": 14, - "weight": "bold" - }, - "text": { - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 14 - } - } - }, - "diagnostic_path_header": { - "background": "#ffffff12", - "text_scale_factor": 0.857, - "filename": { - "family": "Zed Mono", - "color": "#f1f1f1", - "size": 14 - }, - "path": { - "family": "Zed Mono", - "color": "#808080", - "size": 14, - "margin": { - "left": 12 - } - } - }, - "error_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#070707", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#f15656", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#f15656", - "size": 14, - "weight": "bold" - } - } - }, - "warning_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#070707", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#f7bb57", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#f7bb57", - "size": 14, - "weight": "bold" - } - } - }, - "information_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#070707", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#2472f2", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#2472f2", - "size": 14, - "weight": "bold" - } - } - }, - "hint_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#070707", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#2472f2", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#2472f2", - "size": 14, - "weight": "bold" - } - } - }, - "invalid_error_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#070707", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14, - "weight": "bold" - } - } - }, - "invalid_hint_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#070707", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14, - "weight": "bold" - } - } - }, - "invalid_information_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#070707", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14, - "weight": "bold" - } - } - }, - "invalid_warning_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#070707", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14, - "weight": "bold" - } - } - }, - "syntax": { - "primary": { - "color": "#d5d5d5", - "weight": "normal" - }, - "comment": { - "color": "#aaaaaa", - "weight": "normal" - }, - "punctuation": { - "color": "#c6c6c6", - "weight": "normal" - }, - "constant": { - "color": "#d5d5d5", - "weight": "normal" - }, - "keyword": { - "color": "#4f8ff7", - "weight": "normal" - }, - "function": { - "color": "#f9da82", - "weight": "normal" - }, - "type": { - "color": "#3eeeda", - "weight": "normal" - }, - "variant": { - "color": "#53c1f5", - "weight": "normal" - }, - "property": { - "color": "#4f8ff7", - "weight": "normal" - }, - "enum": { - "color": "#ee670a", - "weight": "normal" - }, - "operator": { - "color": "#ee670a", - "weight": "normal" - }, - "string": { - "color": "#f99d5f", - "weight": "normal" - }, - "number": { - "color": "#aeef4b", - "weight": "normal" - }, - "boolean": { - "color": "#aeef4b", - "weight": "normal" - }, - "predictive": { - "color": "#808080", - "weight": "normal" - }, - "title": { - "color": "#de900c", - "weight": "bold" - }, - "emphasis": { - "color": "#4f8ff7", - "weight": "normal" - }, - "emphasis.strong": { - "color": "#4f8ff7", - "weight": "bold" - }, - "link_uri": { - "color": "#79ba16", - "weight": "normal", - "underline": true - }, - "link_text": { - "color": "#ee670a", - "weight": "normal", - "italic": true - } - } - }, - "project_diagnostics": { - "background": "#000000", - "tab_icon_spacing": 4, - "tab_icon_width": 13, - "tab_summary_spacing": 10, - "empty_message": { - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 16 - } - }, - "command_palette": { - "keystroke_spacing": 8, - "key": { - "text": { - "family": "Zed Mono", - "color": "#9c9c9c", - "size": 12 - }, - "corner_radius": 4, - "background": "#0e0e0e80", - "border": { - "color": "#232323", - "width": 1 - }, - "padding": { - "top": 2, - "bottom": 2, - "left": 8, - "right": 8 - }, - "margin": { - "left": 2 - }, - "active": { - "text": { - "family": "Zed Mono", - "color": "#ffffff", - "size": 12 - } - } - } - }, - "project_panel": { - "padding": { - "left": 12, - "right": 12, - "top": 6, - "bottom": 6 - }, - "indent_width": 20, - "entry": { - "height": 24, - "icon_color": "#555555", - "icon_size": 8, - "icon_spacing": 8, - "text": { - "family": "Zed Mono", - "color": "#808080", - "size": 14 - }, - "hover": { - "background": "#232323", - "text": { - "family": "Zed Mono", - "color": "#f1f1f1", - "size": 14 - } - }, - "active": { - "background": "#2b2b2b", - "text": { - "family": "Zed Mono", - "color": "#f1f1f1", - "size": 14 - } - }, - "active_hover": { - "background": "#232323", - "text": { - "family": "Zed Mono", - "color": "#ffffff", - "size": 14 - } - } - }, - "filename_editor": { - "background": "#ffffff1f", - "text": { - "family": "Zed Mono", - "color": "#f1f1f1", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - } - } - }, - "chat_panel": { - "padding": { - "top": 12, - "bottom": 12 - }, - "channel_name": { - "family": "Zed Sans", - "color": "#f1f1f1", - "weight": "bold", - "size": 14 - }, - "channel_name_hash": { - "family": "Zed Sans", - "color": "#808080", - "size": 14, - "padding": { - "right": 8 - } - }, - "channel_select": { - "header": { - "name": { - "family": "Zed Sans", - "color": "#f1f1f1", - "size": 14 - }, - "padding": { - "bottom": 4, - "left": 0 - }, - "hash": { - "family": "Zed Sans", - "color": "#808080", - "size": 14, - "margin": { - "right": 8 - } - }, - "corner_radius": 0 - }, - "item": { - "name": { - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 14 - }, - "padding": 4, - "hash": { - "family": "Zed Sans", - "color": "#808080", - "size": 14, - "margin": { - "right": 8 - } - }, - "corner_radius": 0 - }, - "hovered_item": { - "name": { - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 14 - }, - "padding": 4, - "hash": { - "family": "Zed Sans", - "color": "#808080", - "size": 14, - "margin": { - "right": 8 - } - }, - "background": "#232323", - "corner_radius": 6 - }, - "active_item": { - "name": { - "family": "Zed Sans", - "color": "#f1f1f1", - "size": 14 - }, - "padding": 4, - "hash": { - "family": "Zed Sans", - "color": "#808080", - "size": 14, - "margin": { - "right": 8 - } - }, - "corner_radius": 0 - }, - "hovered_active_item": { - "name": { - "family": "Zed Sans", - "color": "#f1f1f1", - "size": 14 - }, - "padding": 4, - "hash": { - "family": "Zed Sans", - "color": "#808080", - "size": 14, - "margin": { - "right": 8 - } - }, - "background": "#232323", - "corner_radius": 6 - }, - "menu": { - "background": "#000000", - "corner_radius": 6, - "padding": 4, - "border": { - "color": "#070707", - "width": 1 - }, - "shadow": { - "blur": 16, - "color": "#00000052", - "offset": [ - 0, - 2 - ] - } - } - }, - "sign_in_prompt": { - "family": "Zed Sans", - "color": "#9c9c9c", - "underline": true, - "size": 14 - }, - "hovered_sign_in_prompt": { - "family": "Zed Sans", - "color": "#f1f1f1", - "underline": true, - "size": 14 - }, - "message": { - "body": { - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 14 - }, - "timestamp": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "padding": { - "bottom": 6 - }, - "sender": { - "family": "Zed Sans", - "color": "#f1f1f1", - "weight": "bold", - "size": 14, - "margin": { - "right": 8 - } - } - }, - "pending_message": { - "body": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "timestamp": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "padding": { - "bottom": 6 - }, - "sender": { - "family": "Zed Sans", - "color": "#808080", - "weight": "bold", - "size": 14, - "margin": { - "right": 8 - } - } - }, - "input_editor": { - "background": "#000000", - "corner_radius": 6, - "text": { - "family": "Zed Mono", - "color": "#f1f1f1", - "size": 14 - }, - "placeholder_text": { - "family": "Zed Mono", - "color": "#474747", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "border": { - "color": "#232323", - "width": 1 - }, - "padding": { - "bottom": 7, - "left": 8, - "right": 8, - "top": 7 - } - } - }, - "contacts_panel": { - "padding": { - "top": 12, - "bottom": 12 - }, - "user_query_editor": { - "background": "#000000", - "corner_radius": 6, - "text": { - "family": "Zed Mono", - "color": "#f1f1f1", - "size": 14 - }, - "placeholder_text": { - "family": "Zed Mono", - "color": "#474747", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "border": { - "color": "#232323", - "width": 1 - }, - "padding": { - "bottom": 4, - "left": 8, - "right": 8, - "top": 4 - }, - "margin": { - "left": 12, - "right": 12 - } - }, - "user_query_editor_height": 32, - "add_contact_button": { - "margin": { - "left": 6, - "right": 12 - }, - "color": "#c6c6c6", - "button_width": 8, - "icon_width": 8 - }, - "row_height": 28, - "section_icon_size": 8, - "header_row": { - "family": "Zed Mono", - "color": "#9c9c9c", - "size": 14, - "margin": { - "top": 14 - }, - "padding": { - "left": 12, - "right": 12 - }, - "active": { - "family": "Zed Mono", - "color": "#f1f1f1", - "size": 14, - "background": "#1c1c1c" - } - }, - "contact_row": { - "padding": { - "left": 12, - "right": 12 - }, - "active": { - "background": "#1c1c1c" - } - }, - "tree_branch": { - "color": "#000000", - "width": 1, - "hover": { - "color": "#000000" - }, - "active": { - "color": "#000000" - } - }, - "contact_avatar": { - "corner_radius": 10, - "width": 18 - }, - "contact_username": { - "family": "Zed Mono", - "color": "#f1f1f1", - "size": 14, - "margin": { - "left": 8 - } - }, - "contact_button_spacing": 8, - "contact_button": { - "background": "#2b2b2b", - "color": "#c6c6c6", - "icon_width": 8, - "button_width": 16, - "corner_radius": 8, - "hover": { - "background": "#323232" - } - }, - "disabled_contact_button": { - "background": "#2b2b2b", - "color": "#555555", - "icon_width": 8, - "button_width": 16, - "corner_radius": 8 - }, - "shared_project_row": { - "guest_avatar_spacing": 4, - "height": 24, - "guest_avatar": { - "corner_radius": 8, - "width": 14 - }, - "name": { - "family": "Zed Mono", - "color": "#9c9c9c", - "size": 14, - "margin": { - "left": 8, - "right": 6 - } - }, - "guests": { - "margin": { - "left": 8, - "right": 8 - } - }, - "padding": { - "left": 12, - "right": 12 - }, - "background": "#1c1c1c", - "hover": { - "background": "#232323" - }, - "active": { - "background": "#2b2b2b" - } - }, - "unshared_project_row": { - "guest_avatar_spacing": 4, - "height": 24, - "guest_avatar": { - "corner_radius": 8, - "width": 14 - }, - "name": { - "family": "Zed Mono", - "color": "#9c9c9c", - "size": 14, - "margin": { - "left": 8, - "right": 6 - } - }, - "guests": { - "margin": { - "left": 8, - "right": 8 - } - }, - "padding": { - "left": 12, - "right": 12 - }, - "background": "#1c1c1c", - "hover": { - "background": "#232323" - }, - "active": { - "background": "#2b2b2b" - } - } - }, - "contact_finder": { - "background": "#1c1c1c", - "corner_radius": 8, - "padding": 8, - "item": { - "padding": { - "bottom": 4, - "left": 12, - "right": 12, - "top": 4 - }, - "corner_radius": 8, - "text": { - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#4f8ff7", - "weight": "bold", - "size": 14 - }, - "active": { - "background": "#2b2b2b", - "text": { - "family": "Zed Sans", - "color": "#f1f1f1", - "size": 14 - } - }, - "hover": { - "background": "#232323" - } - }, - "border": { - "color": "#070707", - "width": 1 - }, - "empty": { - "text": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - }, - "padding": { - "bottom": 4, - "left": 12, - "right": 12, - "top": 8 - } - }, - "input_editor": { - "background": "#000000", - "corner_radius": 8, - "placeholder_text": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "text": { - "family": "Zed Mono", - "color": "#f1f1f1", - "size": 14 - }, - "border": { - "color": "#232323", - "width": 1 - }, - "padding": { - "bottom": 7, - "left": 16, - "right": 16, - "top": 7 - } - }, - "shadow": { - "blur": 16, - "color": "#00000052", - "offset": [ - 0, - 2 - ] - }, - "row_height": 28, - "contact_avatar": { - "corner_radius": 10, - "width": 18 - }, - "contact_username": { - "padding": { - "left": 8 - } - }, - "contact_button": { - "background": "#2b2b2b", - "color": "#c6c6c6", - "icon_width": 8, - "button_width": 16, - "corner_radius": 8, - "hover": { - "background": "#323232" - } - }, - "disabled_contact_button": { - "background": "#2b2b2b", - "color": "#555555", - "icon_width": 8, - "button_width": 16, - "corner_radius": 8 - } - }, - "search": { - "match_background": "#3f15a380", - "tab_icon_spacing": 8, - "tab_icon_width": 14, - "option_button": { - "family": "Zed Mono", - "color": "#9c9c9c", - "size": 14, - "background": "#0e0e0e", - "corner_radius": 6, - "border": { - "color": "#232323", - "width": 1 - }, - "margin": { - "right": 4 - }, - "padding": { - "bottom": 2, - "left": 10, - "right": 10, - "top": 2 - }, - "active": { - "family": "Zed Mono", - "color": "#ffffff", - "size": 14, - "background": "#232323", - "border": { - "color": "#404040", - "width": 1 - } - }, - "hover": { - "family": "Zed Mono", - "color": "#ffffff", - "size": 14, - "background": "#1c1c1c", - "border": { - "color": "#404040", - "width": 1 - } - } - }, - "editor": { - "background": "#000000", - "corner_radius": 8, - "min_width": 200, - "max_width": 500, - "placeholder_text": { - "family": "Zed Mono", - "color": "#474747", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "text": { - "family": "Zed Mono", - "color": "#ffffff", - "size": 14 - }, - "border": { - "color": "#232323", - "width": 1 - }, - "margin": { - "right": 12 - }, - "padding": { - "top": 3, - "bottom": 3, - "left": 12, - "right": 8 - } - }, - "invalid_editor": { - "background": "#000000", - "corner_radius": 8, - "min_width": 200, - "max_width": 500, - "placeholder_text": { - "family": "Zed Mono", - "color": "#474747", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "text": { - "family": "Zed Mono", - "color": "#ffffff", - "size": 14 - }, - "border": { - "color": "#eb2d2d26", - "width": 1 - }, - "margin": { - "right": 12 - }, - "padding": { - "top": 3, - "bottom": 3, - "left": 12, - "right": 8 - } - }, - "match_index": { - "family": "Zed Mono", - "color": "#808080", - "size": 14, - "padding": 6 - }, - "option_button_group": { - "padding": { - "left": 12, - "right": 12 - } - }, - "results_status": { - "family": "Zed Mono", - "color": "#f1f1f1", - "size": 18 - } - }, - "breadcrumbs": { - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 14, - "padding": { - "left": 6 - } - }, - "contact_notification": { - "header_avatar": { - "height": 12, - "width": 12, - "corner_radius": 6 - }, - "header_message": { - "family": "Zed Sans", - "color": "#f1f1f1", - "size": 12, - "margin": { - "left": 8, - "right": 8 - } - }, - "header_height": 18, - "body_message": { - "family": "Zed Sans", - "color": "#9c9c9c", - "size": 12, - "margin": { - "left": 20, - "top": 6, - "bottom": 6 - } - }, - "button": { - "family": "Zed Sans", - "color": "#f1f1f1", - "size": 12, - "background": "#0e0e0e80", - "padding": 4, - "corner_radius": 6, - "margin": { - "left": 6 - }, - "hover": { - "background": "#070707" - } - }, - "dismiss_button": { - "color": "#9c9c9c", - "icon_width": 8, - "icon_height": 8, - "button_width": 8, - "button_height": 8, - "hover": { - "color": "#c6c6c6" - } - } - } -} \ No newline at end of file diff --git a/assets/themes/light.json b/assets/themes/light.json deleted file mode 100644 index 1cff4df3ad..0000000000 --- a/assets/themes/light.json +++ /dev/null @@ -1,1734 +0,0 @@ -{ - "picker": { - "background": "#f8f8f8", - "corner_radius": 8, - "padding": 8, - "item": { - "padding": { - "bottom": 4, - "left": 12, - "right": 12, - "top": 4 - }, - "corner_radius": 8, - "text": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#484bed", - "weight": "bold", - "size": 14 - }, - "active": { - "background": "#e3e3e3", - "text": { - "family": "Zed Sans", - "color": "#2b2b2b", - "size": 14 - } - }, - "hover": { - "background": "#eaeaea" - } - }, - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "empty": { - "text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "padding": { - "bottom": 4, - "left": 12, - "right": 12, - "top": 8 - } - }, - "input_editor": { - "background": "#ffffff", - "corner_radius": 8, - "placeholder_text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "text": { - "family": "Zed Mono", - "color": "#2b2b2b", - "size": 14 - }, - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "padding": { - "bottom": 7, - "left": 16, - "right": 16, - "top": 7 - } - }, - "shadow": { - "blur": 16, - "color": "#0000001f", - "offset": [ - 0, - 2 - ] - } - }, - "workspace": { - "background": "#f8f8f8", - "leader_border_opacity": 0.7, - "leader_border_width": 2, - "tab": { - "height": 32, - "background": "#f8f8f8", - "icon_close": "#9c9c9c", - "icon_close_active": "#000000", - "icon_conflict": "#f7bf17", - "icon_dirty": "#135acd", - "icon_width": 8, - "spacing": 8, - "text": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - }, - "border": { - "color": "#d5d5d5", - "width": 1, - "left": true, - "bottom": true, - "overlay": true - }, - "padding": { - "left": 8, - "right": 8 - } - }, - "active_tab": { - "height": 32, - "background": "#ffffff", - "icon_close": "#9c9c9c", - "icon_close_active": "#000000", - "icon_conflict": "#f7bf17", - "icon_dirty": "#135acd", - "icon_width": 8, - "spacing": 8, - "text": { - "family": "Zed Sans", - "color": "#000000", - "size": 14 - }, - "border": { - "color": "#d5d5d5", - "width": 1, - "left": true, - "bottom": false, - "overlay": true - }, - "padding": { - "left": 8, - "right": 8 - } - }, - "modal": { - "margin": { - "bottom": 52, - "top": 52 - }, - "cursor": "Arrow" - }, - "sidebar_resize_handle": { - "background": "#d5d5d5", - "padding": { - "left": 1 - } - }, - "pane_divider": { - "color": "#d5d5d5", - "width": 1 - }, - "status_bar": { - "height": 30, - "item_spacing": 8, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "border": { - "color": "#d5d5d5", - "width": 1, - "top": true, - "overlay": true - }, - "cursor_position": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, - "auto_update_progress_message": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, - "auto_update_done_message": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, - "lsp_status": { - "corner_radius": 6, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "icon_spacing": 4, - "icon_width": 14, - "height": 18, - "message": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, - "icon_color": "#9c9c9c", - "hover": { - "message": { - "family": "Zed Sans", - "color": "#2b2b2b", - "size": 14 - }, - "icon_color": "#393939", - "background": "#eaeaea" - } - }, - "diagnostic_message": { - "family": "Zed Sans", - "color": "#636363", - "size": 14, - "hover": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - } - }, - "diagnostic_summary": { - "height": 16, - "icon_width": 14, - "icon_spacing": 2, - "summary_spacing": 6, - "text": { - "family": "Zed Sans", - "color": "#2b2b2b", - "size": 14 - }, - "icon_color_ok": "#717171", - "icon_color_warning": "#f7bf17", - "icon_color_error": "#c91818", - "container_ok": { - "corner_radius": 6, - "padding": { - "top": 3, - "bottom": 3, - "left": 7, - "right": 7 - } - }, - "container_warning": { - "corner_radius": 6, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "background": "#f6a72426", - "border": { - "color": "#f6a72426", - "width": 1 - } - }, - "container_error": { - "corner_radius": 6, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "background": "#c9181826", - "border": { - "color": "#eb2d2d26", - "width": 1 - } - }, - "hover": { - "icon_color_ok": "#393939", - "container_ok": { - "corner_radius": 6, - "padding": { - "top": 3, - "bottom": 3, - "left": 7, - "right": 7 - }, - "background": "#eaeaea" - }, - "container_warning": { - "corner_radius": 6, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "background": "#f6a72433", - "border": { - "color": "#f6a72426", - "width": 1 - } - }, - "container_error": { - "corner_radius": 6, - "padding": { - "top": 1, - "bottom": 1, - "left": 6, - "right": 6 - }, - "background": "#c9181833", - "border": { - "color": "#eb2d2d26", - "width": 1 - } - } - } - }, - "sidebar_buttons": { - "group_left": {}, - "group_right": {}, - "item": { - "corner_radius": 6, - "padding": { - "top": 3, - "bottom": 3, - "left": 6, - "right": 6 - }, - "icon_size": 14, - "icon_color": "#717171", - "hover": { - "icon_color": "#393939", - "background": "#eaeaea" - }, - "active": { - "icon_color": "#000000", - "background": "#e3e3e3" - } - }, - "badge": { - "corner_radius": 3, - "padding": 2, - "margin": { - "bottom": -1, - "right": -1 - }, - "border": { - "width": 1, - "color": "#f8f8f8" - }, - "background": "#484bed" - } - } - }, - "titlebar": { - "avatar_width": 18, - "avatar_margin": 8, - "height": 33, - "background": "#eaeaea", - "padding": { - "left": 80, - "right": 6 - }, - "title": { - "family": "Zed Sans", - "color": "#2b2b2b", - "size": 14 - }, - "avatar": { - "corner_radius": 10, - "border": { - "color": "#00000088", - "width": 1 - } - }, - "avatar_ribbon": { - "height": 3, - "width": 12 - }, - "border": { - "color": "#d5d5d5", - "width": 1, - "bottom": true, - "overlay": true - }, - "sign_in_prompt": { - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "corner_radius": 6, - "margin": { - "top": 1 - }, - "padding": { - "left": 6, - "right": 6 - }, - "family": "Zed Sans", - "color": "#474747", - "size": 12, - "hover": { - "family": "Zed Sans", - "color": "#000000", - "size": 12 - } - }, - "offline_icon": { - "color": "#717171", - "width": 16, - "padding": { - "right": 4 - } - }, - "share_icon": { - "corner_radius": 6, - "margin": { - "top": 3, - "bottom": 2, - "left": 6 - }, - "color": "#717171", - "hover": { - "background": "#e3e3e3", - "color": "#717171" - }, - "active": { - "background": "#d5d5d5", - "color": "#000000" - }, - "active_hover": { - "background": "#e3e3e3", - "color": "#000000" - } - }, - "outdated_warning": { - "family": "Zed Sans", - "color": "#d3a20b", - "size": 12, - "background": "#f6a72426", - "border": { - "color": "#f6a72426", - "width": 1 - }, - "padding": { - "left": 6, - "right": 6 - }, - "corner_radius": 6 - } - }, - "toolbar": { - "height": 34, - "background": "#ffffff", - "border": { - "color": "#d5d5d5", - "width": 1, - "bottom": true - }, - "item_spacing": 8, - "padding": { - "left": 16, - "right": 8, - "top": 4, - "bottom": 4 - } - }, - "breadcrumbs": { - "family": "Zed Mono", - "color": "#474747", - "size": 14, - "padding": { - "left": 6 - } - }, - "disconnected_overlay": { - "family": "Zed Sans", - "color": "#000000", - "size": 14, - "background": "#000000aa" - }, - "notification": { - "margin": { - "top": 10 - }, - "background": "#f8f8f8", - "corner_radius": 6, - "padding": 12, - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "shadow": { - "blur": 16, - "color": "#0000001f", - "offset": [ - 0, - 2 - ] - } - }, - "notifications": { - "width": 380, - "margin": { - "right": 10, - "bottom": 10 - } - } - }, - "editor": { - "text_color": "#1c1c1c", - "background": "#ffffff", - "active_line_background": "#0000000f", - "code_actions_indicator": "#9c9c9c", - "diff_background_deleted": "#c9181826", - "diff_background_inserted": "#1b944726", - "document_highlight_read_background": "#0000000f", - "document_highlight_write_background": "#00000029", - "error_color": "#eb2d2d", - "gutter_background": "#ffffff", - "gutter_padding_factor": 3.5, - "highlighted_line_background": "#0000001f", - "line_number": "#aaaaaa", - "line_number_active": "#000000", - "rename_fade": 0.6, - "unnecessary_code_fade": 0.5, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "guest_selections": [ - { - "cursor": "#12d796", - "selection": "#12d7963d" - }, - { - "cursor": "#de57e8", - "selection": "#de57e83d" - }, - { - "cursor": "#f9812e", - "selection": "#f9812e3d" - }, - { - "cursor": "#b066f8", - "selection": "#b066f83d" - }, - { - "cursor": "#16d6c1", - "selection": "#16d6c13d" - }, - { - "cursor": "#ef59a3", - "selection": "#ef59a33d" - }, - { - "cursor": "#f7bf17", - "selection": "#f7bf173d" - } - ], - "autocomplete": { - "background": "#ffffff", - "corner_radius": 8, - "padding": 4, - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "item": { - "corner_radius": 6, - "padding": { - "bottom": 2, - "left": 6, - "right": 6, - "top": 2 - } - }, - "hovered_item": { - "corner_radius": 6, - "padding": { - "bottom": 2, - "left": 6, - "right": 6, - "top": 2 - }, - "background": "#00000008" - }, - "margin": { - "left": -14 - }, - "match_highlight": { - "family": "Zed Mono", - "color": "#484bed", - "size": 14 - }, - "selected_item": { - "corner_radius": 6, - "padding": { - "bottom": 2, - "left": 6, - "right": 6, - "top": 2 - }, - "background": "#0000000f" - } - }, - "diagnostic_header": { - "background": "#f8f8f8", - "icon_width_factor": 1.5, - "text_scale_factor": 0.857, - "border": { - "color": "#d5d5d5", - "width": 1, - "bottom": true, - "top": true - }, - "code": { - "family": "Zed Mono", - "color": "#636363", - "size": 14, - "margin": { - "left": 10 - } - }, - "message": { - "highlight_text": { - "family": "Zed Sans", - "color": "#2b2b2b", - "size": 14, - "weight": "bold" - }, - "text": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - } - } - }, - "diagnostic_path_header": { - "background": "#0000000f", - "text_scale_factor": 0.857, - "filename": { - "family": "Zed Mono", - "color": "#2b2b2b", - "size": 14 - }, - "path": { - "family": "Zed Mono", - "color": "#636363", - "size": 14, - "margin": { - "left": 12 - } - } - }, - "error_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#d5d5d5", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#eb2d2d", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#eb2d2d", - "size": 14, - "weight": "bold" - } - } - }, - "warning_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#d5d5d5", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#d3a20b", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#d3a20b", - "size": 14, - "weight": "bold" - } - } - }, - "information_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#d5d5d5", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#2472f2", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#2472f2", - "size": 14, - "weight": "bold" - } - } - }, - "hint_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#d5d5d5", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#2472f2", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#2472f2", - "size": 14, - "weight": "bold" - } - } - }, - "invalid_error_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#d5d5d5", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#636363", - "size": 14, - "weight": "bold" - } - } - }, - "invalid_hint_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#d5d5d5", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#636363", - "size": 14, - "weight": "bold" - } - } - }, - "invalid_information_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#d5d5d5", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#636363", - "size": 14, - "weight": "bold" - } - } - }, - "invalid_warning_diagnostic": { - "text_scale_factor": 0.857, - "header": { - "border": { - "color": "#d5d5d5", - "width": 1, - "top": true - } - }, - "message": { - "text": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#636363", - "size": 14, - "weight": "bold" - } - } - }, - "syntax": { - "primary": { - "color": "#1c1c1c", - "weight": "normal" - }, - "comment": { - "color": "#717171", - "weight": "normal" - }, - "punctuation": { - "color": "#555555", - "weight": "normal" - }, - "constant": { - "color": "#1c1c1c", - "weight": "normal" - }, - "keyword": { - "color": "#1819a1", - "weight": "normal" - }, - "function": { - "color": "#bb550e", - "weight": "normal" - }, - "type": { - "color": "#a8820e", - "weight": "normal" - }, - "variant": { - "color": "#97142a", - "weight": "normal" - }, - "property": { - "color": "#106c4e", - "weight": "normal" - }, - "enum": { - "color": "#eb2d2d", - "weight": "normal" - }, - "operator": { - "color": "#eb2d2d", - "weight": "normal" - }, - "string": { - "color": "#eb2d2d", - "weight": "normal" - }, - "number": { - "color": "#484bed", - "weight": "normal" - }, - "boolean": { - "color": "#eb2d2d", - "weight": "normal" - }, - "predictive": { - "color": "#808080", - "weight": "normal" - }, - "title": { - "color": "#1096d3", - "weight": "bold" - }, - "emphasis": { - "color": "#484bed", - "weight": "normal" - }, - "emphasis.strong": { - "color": "#484bed", - "weight": "bold" - }, - "link_uri": { - "color": "#79ba16", - "weight": "normal", - "underline": true - }, - "link_text": { - "color": "#eb2d2d", - "weight": "normal", - "italic": true - } - } - }, - "project_diagnostics": { - "background": "#ffffff", - "tab_icon_spacing": 4, - "tab_icon_width": 13, - "tab_summary_spacing": 10, - "empty_message": { - "family": "Zed Sans", - "color": "#474747", - "size": 16 - } - }, - "command_palette": { - "keystroke_spacing": 8, - "key": { - "text": { - "family": "Zed Mono", - "color": "#474747", - "size": 12 - }, - "corner_radius": 4, - "background": "#f1f1f1", - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "padding": { - "top": 2, - "bottom": 2, - "left": 8, - "right": 8 - }, - "margin": { - "left": 2 - }, - "active": { - "text": { - "family": "Zed Mono", - "color": "#000000", - "size": 12 - } - } - } - }, - "project_panel": { - "padding": { - "left": 12, - "right": 12, - "top": 6, - "bottom": 6 - }, - "indent_width": 20, - "entry": { - "height": 24, - "icon_color": "#9c9c9c", - "icon_size": 8, - "icon_spacing": 8, - "text": { - "family": "Zed Mono", - "color": "#636363", - "size": 14 - }, - "hover": { - "background": "#eaeaea", - "text": { - "family": "Zed Mono", - "color": "#2b2b2b", - "size": 14 - } - }, - "active": { - "background": "#e3e3e3", - "text": { - "family": "Zed Mono", - "color": "#2b2b2b", - "size": 14 - } - }, - "active_hover": { - "background": "#eaeaea", - "text": { - "family": "Zed Mono", - "color": "#000000", - "size": 14 - } - } - }, - "filename_editor": { - "background": "#0000000f", - "text": { - "family": "Zed Mono", - "color": "#2b2b2b", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - } - } - }, - "chat_panel": { - "padding": { - "top": 12, - "bottom": 12 - }, - "channel_name": { - "family": "Zed Sans", - "color": "#2b2b2b", - "weight": "bold", - "size": 14 - }, - "channel_name_hash": { - "family": "Zed Sans", - "color": "#636363", - "size": 14, - "padding": { - "right": 8 - } - }, - "channel_select": { - "header": { - "name": { - "family": "Zed Sans", - "color": "#2b2b2b", - "size": 14 - }, - "padding": { - "bottom": 4, - "left": 0 - }, - "hash": { - "family": "Zed Sans", - "color": "#636363", - "size": 14, - "margin": { - "right": 8 - } - }, - "corner_radius": 0 - }, - "item": { - "name": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - }, - "padding": 4, - "hash": { - "family": "Zed Sans", - "color": "#636363", - "size": 14, - "margin": { - "right": 8 - } - }, - "corner_radius": 0 - }, - "hovered_item": { - "name": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - }, - "padding": 4, - "hash": { - "family": "Zed Sans", - "color": "#636363", - "size": 14, - "margin": { - "right": 8 - } - }, - "background": "#eaeaea", - "corner_radius": 6 - }, - "active_item": { - "name": { - "family": "Zed Sans", - "color": "#2b2b2b", - "size": 14 - }, - "padding": 4, - "hash": { - "family": "Zed Sans", - "color": "#636363", - "size": 14, - "margin": { - "right": 8 - } - }, - "corner_radius": 0 - }, - "hovered_active_item": { - "name": { - "family": "Zed Sans", - "color": "#2b2b2b", - "size": 14 - }, - "padding": 4, - "hash": { - "family": "Zed Sans", - "color": "#636363", - "size": 14, - "margin": { - "right": 8 - } - }, - "background": "#eaeaea", - "corner_radius": 6 - }, - "menu": { - "background": "#ffffff", - "corner_radius": 6, - "padding": 4, - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "shadow": { - "blur": 16, - "color": "#0000001f", - "offset": [ - 0, - 2 - ] - } - } - }, - "sign_in_prompt": { - "family": "Zed Sans", - "color": "#474747", - "underline": true, - "size": 14 - }, - "hovered_sign_in_prompt": { - "family": "Zed Sans", - "color": "#2b2b2b", - "underline": true, - "size": 14 - }, - "message": { - "body": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - }, - "timestamp": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, - "padding": { - "bottom": 6 - }, - "sender": { - "family": "Zed Sans", - "color": "#2b2b2b", - "weight": "bold", - "size": 14, - "margin": { - "right": 8 - } - } - }, - "pending_message": { - "body": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, - "timestamp": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, - "padding": { - "bottom": 6 - }, - "sender": { - "family": "Zed Sans", - "color": "#636363", - "weight": "bold", - "size": 14, - "margin": { - "right": 8 - } - } - }, - "input_editor": { - "background": "#ffffff", - "corner_radius": 6, - "text": { - "family": "Zed Mono", - "color": "#2b2b2b", - "size": 14 - }, - "placeholder_text": { - "family": "Zed Mono", - "color": "#808080", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "padding": { - "bottom": 7, - "left": 8, - "right": 8, - "top": 7 - } - } - }, - "contacts_panel": { - "padding": { - "top": 12, - "bottom": 12 - }, - "user_query_editor": { - "background": "#ffffff", - "corner_radius": 6, - "text": { - "family": "Zed Mono", - "color": "#2b2b2b", - "size": 14 - }, - "placeholder_text": { - "family": "Zed Mono", - "color": "#808080", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "padding": { - "bottom": 4, - "left": 8, - "right": 8, - "top": 4 - }, - "margin": { - "left": 12, - "right": 12 - } - }, - "user_query_editor_height": 32, - "add_contact_button": { - "margin": { - "left": 6, - "right": 12 - }, - "color": "#393939", - "button_width": 8, - "icon_width": 8 - }, - "row_height": 28, - "section_icon_size": 8, - "header_row": { - "family": "Zed Mono", - "color": "#474747", - "size": 14, - "margin": { - "top": 14 - }, - "padding": { - "left": 12, - "right": 12 - }, - "active": { - "family": "Zed Mono", - "color": "#2b2b2b", - "size": 14, - "background": "#d5d5d5" - } - }, - "contact_row": { - "padding": { - "left": 12, - "right": 12 - }, - "active": { - "background": "#d5d5d5" - } - }, - "tree_branch": { - "color": "#b8b8b8", - "width": 1, - "hover": { - "color": "#b8b8b8" - }, - "active": { - "color": "#b8b8b8" - } - }, - "contact_avatar": { - "corner_radius": 10, - "width": 18 - }, - "contact_username": { - "family": "Zed Mono", - "color": "#2b2b2b", - "size": 14, - "margin": { - "left": 8 - } - }, - "contact_button_spacing": 8, - "contact_button": { - "background": "#eaeaea", - "color": "#393939", - "icon_width": 8, - "button_width": 16, - "corner_radius": 8, - "hover": { - "background": "#e3e3e3" - } - }, - "disabled_contact_button": { - "background": "#eaeaea", - "color": "#9c9c9c", - "icon_width": 8, - "button_width": 16, - "corner_radius": 8 - }, - "shared_project_row": { - "guest_avatar_spacing": 4, - "height": 24, - "guest_avatar": { - "corner_radius": 8, - "width": 14 - }, - "name": { - "family": "Zed Mono", - "color": "#474747", - "size": 14, - "margin": { - "left": 8, - "right": 6 - } - }, - "guests": { - "margin": { - "left": 8, - "right": 8 - } - }, - "padding": { - "left": 12, - "right": 12 - }, - "background": "#f8f8f8", - "hover": { - "background": "#eaeaea" - }, - "active": { - "background": "#e3e3e3" - } - }, - "unshared_project_row": { - "guest_avatar_spacing": 4, - "height": 24, - "guest_avatar": { - "corner_radius": 8, - "width": 14 - }, - "name": { - "family": "Zed Mono", - "color": "#474747", - "size": 14, - "margin": { - "left": 8, - "right": 6 - } - }, - "guests": { - "margin": { - "left": 8, - "right": 8 - } - }, - "padding": { - "left": 12, - "right": 12 - }, - "background": "#f8f8f8", - "hover": { - "background": "#eaeaea" - }, - "active": { - "background": "#e3e3e3" - } - } - }, - "contact_finder": { - "background": "#f8f8f8", - "corner_radius": 8, - "padding": 8, - "item": { - "padding": { - "bottom": 4, - "left": 12, - "right": 12, - "top": 4 - }, - "corner_radius": 8, - "text": { - "family": "Zed Sans", - "color": "#474747", - "size": 14 - }, - "highlight_text": { - "family": "Zed Sans", - "color": "#484bed", - "weight": "bold", - "size": 14 - }, - "active": { - "background": "#e3e3e3", - "text": { - "family": "Zed Sans", - "color": "#2b2b2b", - "size": 14 - } - }, - "hover": { - "background": "#eaeaea" - } - }, - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "empty": { - "text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "padding": { - "bottom": 4, - "left": 12, - "right": 12, - "top": 8 - } - }, - "input_editor": { - "background": "#ffffff", - "corner_radius": 8, - "placeholder_text": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "text": { - "family": "Zed Mono", - "color": "#2b2b2b", - "size": 14 - }, - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "padding": { - "bottom": 7, - "left": 16, - "right": 16, - "top": 7 - } - }, - "shadow": { - "blur": 16, - "color": "#0000001f", - "offset": [ - 0, - 2 - ] - }, - "row_height": 28, - "contact_avatar": { - "corner_radius": 10, - "width": 18 - }, - "contact_username": { - "padding": { - "left": 8 - } - }, - "contact_button": { - "background": "#eaeaea", - "color": "#393939", - "icon_width": 8, - "button_width": 16, - "corner_radius": 8, - "hover": { - "background": "#e3e3e3" - } - }, - "disabled_contact_button": { - "background": "#eaeaea", - "color": "#9c9c9c", - "icon_width": 8, - "button_width": 16, - "corner_radius": 8 - } - }, - "search": { - "match_background": "#fce9b7", - "tab_icon_spacing": 8, - "tab_icon_width": 14, - "option_button": { - "family": "Zed Mono", - "color": "#474747", - "size": 14, - "background": "#f1f1f1", - "corner_radius": 6, - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "margin": { - "right": 4 - }, - "padding": { - "bottom": 2, - "left": 10, - "right": 10, - "top": 2 - }, - "active": { - "family": "Zed Mono", - "color": "#000000", - "size": 14, - "background": "#ffffff", - "border": { - "color": "#e3e3e3", - "width": 1 - } - }, - "hover": { - "family": "Zed Mono", - "color": "#000000", - "size": 14, - "background": "#f8f8f8", - "border": { - "color": "#e3e3e3", - "width": 1 - } - } - }, - "editor": { - "background": "#ffffff", - "corner_radius": 8, - "min_width": 200, - "max_width": 500, - "placeholder_text": { - "family": "Zed Mono", - "color": "#808080", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "text": { - "family": "Zed Mono", - "color": "#000000", - "size": 14 - }, - "border": { - "color": "#d5d5d5", - "width": 1 - }, - "margin": { - "right": 12 - }, - "padding": { - "top": 3, - "bottom": 3, - "left": 12, - "right": 8 - } - }, - "invalid_editor": { - "background": "#ffffff", - "corner_radius": 8, - "min_width": 200, - "max_width": 500, - "placeholder_text": { - "family": "Zed Mono", - "color": "#808080", - "size": 14 - }, - "selection": { - "cursor": "#2472f2", - "selection": "#2472f23d" - }, - "text": { - "family": "Zed Mono", - "color": "#000000", - "size": 14 - }, - "border": { - "color": "#eb2d2d26", - "width": 1 - }, - "margin": { - "right": 12 - }, - "padding": { - "top": 3, - "bottom": 3, - "left": 12, - "right": 8 - } - }, - "match_index": { - "family": "Zed Mono", - "color": "#636363", - "size": 14, - "padding": 6 - }, - "option_button_group": { - "padding": { - "left": 12, - "right": 12 - } - }, - "results_status": { - "family": "Zed Mono", - "color": "#2b2b2b", - "size": 18 - } - }, - "breadcrumbs": { - "family": "Zed Sans", - "color": "#474747", - "size": 14, - "padding": { - "left": 6 - } - }, - "contact_notification": { - "header_avatar": { - "height": 12, - "width": 12, - "corner_radius": 6 - }, - "header_message": { - "family": "Zed Sans", - "color": "#2b2b2b", - "size": 12, - "margin": { - "left": 8, - "right": 8 - } - }, - "header_height": 18, - "body_message": { - "family": "Zed Sans", - "color": "#474747", - "size": 12, - "margin": { - "left": 20, - "top": 6, - "bottom": 6 - } - }, - "button": { - "family": "Zed Sans", - "color": "#2b2b2b", - "size": 12, - "background": "#f1f1f1", - "padding": 4, - "corner_radius": 6, - "margin": { - "left": 6 - }, - "hover": { - "background": "#e3e3e3" - } - }, - "dismiss_button": { - "color": "#717171", - "icon_width": 8, - "icon_height": 8, - "button_width": 8, - "button_height": 8, - "hover": { - "color": "#393939" - } - } - } -} \ No newline at end of file diff --git a/assets/themes/solarized-dark.json b/assets/themes/solarized-dark.json index 8606c78ca0..87f4df2ccb 100644 --- a/assets/themes/solarized-dark.json +++ b/assets/themes/solarized-dark.json @@ -23,7 +23,7 @@ "size": 14 }, "active": { - "background": "#586e755c", + "background": "#30525c", "text": { "family": "Zed Sans", "color": "#eee8d5", @@ -31,7 +31,7 @@ } }, "hover": { - "background": "#586e753d" + "background": "#1b444f" } }, "border": { @@ -215,7 +215,7 @@ "size": 14 }, "icon_color": "#eee8d5", - "background": "#586e753d" + "background": "#1b444f" } }, "diagnostic_message": { @@ -288,7 +288,7 @@ "left": 7, "right": 7 }, - "background": "#586e753d" + "background": "#1b444f" }, "container_warning": { "corner_radius": 6, @@ -335,11 +335,11 @@ "icon_color": "#93a1a1", "hover": { "icon_color": "#eee8d5", - "background": "#586e753d" + "background": "#1b444f" }, "active": { "icon_color": "#fdf6e3", - "background": "#586e755c" + "background": "#30525c" } }, "badge": { @@ -361,7 +361,7 @@ "avatar_width": 18, "avatar_margin": 8, "height": 33, - "background": "#073642", + "background": "#1b444f", "padding": { "left": 80, "right": 6 @@ -426,15 +426,15 @@ }, "color": "#93a1a1", "hover": { - "background": "#586e753d", + "background": "#30525c", "color": "#93a1a1" }, "active": { - "background": "#586e755c", + "background": "#446068", "color": "#fdf6e3" }, "active_hover": { - "background": "#586e753d", + "background": "#30525c", "color": "#fdf6e3" } }, @@ -515,16 +515,16 @@ "editor": { "text_color": "#fdf6e3", "background": "#002b36", - "active_line_background": "#fdf6e312", + "active_line_background": "#073642", "code_actions_indicator": "#93a1a1", "diff_background_deleted": "#dc322f26", "diff_background_inserted": "#85990026", - "document_highlight_read_background": "#fdf6e31f", - "document_highlight_write_background": "#fdf6e33d", + "document_highlight_read_background": "#586e753d", + "document_highlight_write_background": "#586e757a", "error_color": "#dc322f", "gutter_background": "#002b36", "gutter_padding_factor": 3.5, - "highlighted_line_background": "#fdf6e31f", + "highlighted_line_background": "#1b444f", "line_number": "#839496", "line_number_active": "#fdf6e3", "rename_fade": 0.6, @@ -588,7 +588,7 @@ "right": 6, "top": 2 }, - "background": "#0736423d" + "background": "#022e39" }, "margin": { "left": -14 @@ -606,7 +606,7 @@ "right": 6, "top": 2 }, - "background": "#0736425c" + "background": "#04313c" } }, "diagnostic_header": { @@ -642,7 +642,7 @@ } }, "diagnostic_path_header": { - "background": "#fdf6e312", + "background": "#073642", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", @@ -852,7 +852,7 @@ "weight": "normal" }, "punctuation": { - "color": "#93a1a1", + "color": "#eee8d5", "weight": "normal" }, "constant": { @@ -989,7 +989,7 @@ "size": 14 }, "hover": { - "background": "#586e753d", + "background": "#1b444f", "text": { "family": "Zed Mono", "color": "#eee8d5", @@ -997,7 +997,7 @@ } }, "active": { - "background": "#586e755c", + "background": "#30525c", "text": { "family": "Zed Mono", "color": "#eee8d5", @@ -1005,7 +1005,7 @@ } }, "active_hover": { - "background": "#586e753d", + "background": "#1b444f", "text": { "family": "Zed Mono", "color": "#fdf6e3", @@ -1014,7 +1014,7 @@ } }, "filename_editor": { - "background": "#0736425c", + "background": "#04313c", "text": { "family": "Zed Mono", "color": "#eee8d5", @@ -1098,7 +1098,7 @@ "right": 8 } }, - "background": "#586e753d", + "background": "#1b444f", "corner_radius": 6 }, "active_item": { @@ -1133,7 +1133,7 @@ "right": 8 } }, - "background": "#586e753d", + "background": "#1b444f", "corner_radius": 6 }, "menu": { @@ -1307,7 +1307,7 @@ "family": "Zed Mono", "color": "#eee8d5", "size": 14, - "background": "#586e755c" + "background": "#446068" } }, "contact_row": { @@ -1316,7 +1316,7 @@ "right": 12 }, "active": { - "background": "#586e755c" + "background": "#446068" } }, "tree_branch": { @@ -1343,17 +1343,17 @@ }, "contact_button_spacing": 8, "contact_button": { - "background": "#073642", + "background": "#1b444f", "color": "#eee8d5", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#586e753d" + "background": "#30525c" } }, "disabled_contact_button": { - "background": "#073642", + "background": "#1b444f", "color": "#93a1a1", "icon_width": 8, "button_width": 16, @@ -1387,10 +1387,10 @@ }, "background": "#073642", "hover": { - "background": "#586e753d" + "background": "#1b444f" }, "active": { - "background": "#586e755c" + "background": "#30525c" } }, "unshared_project_row": { @@ -1421,10 +1421,10 @@ }, "background": "#073642", "hover": { - "background": "#586e753d" + "background": "#1b444f" }, "active": { - "background": "#586e755c" + "background": "#30525c" } } }, @@ -1452,7 +1452,7 @@ "size": 14 }, "active": { - "background": "#586e755c", + "background": "#30525c", "text": { "family": "Zed Sans", "color": "#eee8d5", @@ -1460,7 +1460,7 @@ } }, "hover": { - "background": "#586e753d" + "background": "#1b444f" } }, "border": { @@ -1527,17 +1527,17 @@ } }, "contact_button": { - "background": "#073642", + "background": "#1b444f", "color": "#eee8d5", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#586e753d" + "background": "#30525c" } }, "disabled_contact_button": { - "background": "#073642", + "background": "#1b444f", "color": "#93a1a1", "icon_width": 8, "button_width": 16, @@ -1545,14 +1545,14 @@ } }, "search": { - "match_background": "#6c71c47a", + "match_background": "#1b1f6b", "tab_icon_spacing": 8, "tab_icon_width": 14, "option_button": { "family": "Zed Mono", "color": "#93a1a1", "size": 14, - "background": "#073642", + "background": "#1b444f", "corner_radius": 6, "border": { "color": "#073642", @@ -1571,7 +1571,7 @@ "family": "Zed Mono", "color": "#fdf6e3", "size": 14, - "background": "#586e757a", + "background": "#446068", "border": { "color": "#657b83", "width": 1 @@ -1581,7 +1581,7 @@ "family": "Zed Mono", "color": "#fdf6e3", "size": 14, - "background": "#586e753d", + "background": "#30525c", "border": { "color": "#657b83", "width": 1 @@ -1717,7 +1717,7 @@ "left": 6 }, "hover": { - "background": "#0736423d" + "background": "#022e39" } }, "dismiss_button": { diff --git a/assets/themes/solarized-light.json b/assets/themes/solarized-light.json index fb8e781ea0..6d74234a6a 100644 --- a/assets/themes/solarized-light.json +++ b/assets/themes/solarized-light.json @@ -23,7 +23,7 @@ "size": 14 }, "active": { - "background": "#93a1a12e", + "background": "#c1c5bb", "text": { "family": "Zed Sans", "color": "#073642", @@ -31,11 +31,11 @@ } }, "hover": { - "background": "#93a1a11f" + "background": "#d7d6c8" } }, "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1 }, "empty": { @@ -69,7 +69,7 @@ "size": 14 }, "border": { - "color": "#eee8d5", + "color": "#93a1a1", "width": 1 }, "padding": { @@ -107,7 +107,7 @@ "size": 14 }, "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "left": true, "bottom": true, @@ -133,7 +133,7 @@ "size": 14 }, "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "left": true, "bottom": false, @@ -152,13 +152,13 @@ "cursor": "Arrow" }, "sidebar_resize_handle": { - "background": "#fdf6e3", + "background": "#93a1a1", "padding": { "left": 1 } }, "pane_divider": { - "color": "#eee8d5", + "color": "#93a1a1", "width": 1 }, "status_bar": { @@ -171,7 +171,7 @@ "right": 6 }, "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "top": true, "overlay": true @@ -215,7 +215,7 @@ "size": 14 }, "icon_color": "#073642", - "background": "#93a1a11f" + "background": "#d7d6c8" } }, "diagnostic_message": { @@ -288,7 +288,7 @@ "left": 7, "right": 7 }, - "background": "#93a1a11f" + "background": "#d7d6c8" }, "container_warning": { "corner_radius": 6, @@ -335,11 +335,11 @@ "icon_color": "#586e75", "hover": { "icon_color": "#073642", - "background": "#93a1a11f" + "background": "#d7d6c8" }, "active": { "icon_color": "#002b36", - "background": "#93a1a12e" + "background": "#c1c5bb" } }, "badge": { @@ -361,7 +361,7 @@ "avatar_width": 18, "avatar_margin": 8, "height": 33, - "background": "#eee8d5", + "background": "#d7d6c8", "padding": { "left": 80, "right": 6 @@ -383,14 +383,14 @@ "width": 12 }, "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "bottom": true, "overlay": true }, "sign_in_prompt": { "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1 }, "corner_radius": 6, @@ -426,15 +426,15 @@ }, "color": "#586e75", "hover": { - "background": "#93a1a11f", + "background": "#c1c5bb", "color": "#586e75" }, "active": { - "background": "#93a1a12e", + "background": "#aab3ae", "color": "#002b36" }, "active_hover": { - "background": "#93a1a11f", + "background": "#c1c5bb", "color": "#002b36" } }, @@ -458,7 +458,7 @@ "height": 34, "background": "#fdf6e3", "border": { - "color": "#eee8d5", + "color": "#93a1a1", "width": 1, "bottom": true }, @@ -492,7 +492,7 @@ "corner_radius": 6, "padding": 12, "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1 }, "shadow": { @@ -515,16 +515,16 @@ "editor": { "text_color": "#002b36", "background": "#fdf6e3", - "active_line_background": "#002b3612", + "active_line_background": "#eee8d5", "code_actions_indicator": "#586e75", "diff_background_deleted": "#dc322f26", "diff_background_inserted": "#85990026", - "document_highlight_read_background": "#002b360f", - "document_highlight_write_background": "#002b361f", + "document_highlight_read_background": "#93a1a11f", + "document_highlight_write_background": "#93a1a13d", "error_color": "#dc322f", "gutter_background": "#fdf6e3", "gutter_padding_factor": 3.5, - "highlighted_line_background": "#002b361f", + "highlighted_line_background": "#d7d6c8", "line_number": "#657b83", "line_number_active": "#002b36", "rename_fade": 0.6, @@ -568,7 +568,7 @@ "corner_radius": 8, "padding": 4, "border": { - "color": "#eee8d5", + "color": "#93a1a1", "width": 1 }, "item": { @@ -588,7 +588,7 @@ "right": 6, "top": 2 }, - "background": "#eee8d51f" + "background": "#f9f3e0" }, "margin": { "left": -14 @@ -606,7 +606,7 @@ "right": 6, "top": 2 }, - "background": "#eee8d52e" + "background": "#f6efdc" } }, "diagnostic_header": { @@ -614,7 +614,7 @@ "icon_width_factor": 1.5, "text_scale_factor": 0.857, "border": { - "color": "#eee8d5", + "color": "#93a1a1", "width": 1, "bottom": true, "top": true @@ -642,7 +642,7 @@ } }, "diagnostic_path_header": { - "background": "#002b3612", + "background": "#eee8d5", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", @@ -662,7 +662,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "top": true } @@ -685,7 +685,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "top": true } @@ -708,7 +708,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "top": true } @@ -731,7 +731,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "top": true } @@ -754,7 +754,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "top": true } @@ -777,7 +777,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "top": true } @@ -800,7 +800,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "top": true } @@ -823,7 +823,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1, "top": true } @@ -852,7 +852,7 @@ "weight": "normal" }, "punctuation": { - "color": "#586e75", + "color": "#073642", "weight": "normal" }, "constant": { @@ -949,7 +949,7 @@ "corner_radius": 4, "background": "#fdf6e3", "border": { - "color": "#eee8d5", + "color": "#93a1a1", "width": 1 }, "padding": { @@ -989,7 +989,7 @@ "size": 14 }, "hover": { - "background": "#93a1a11f", + "background": "#d7d6c8", "text": { "family": "Zed Mono", "color": "#073642", @@ -997,7 +997,7 @@ } }, "active": { - "background": "#93a1a12e", + "background": "#c1c5bb", "text": { "family": "Zed Mono", "color": "#073642", @@ -1005,7 +1005,7 @@ } }, "active_hover": { - "background": "#93a1a11f", + "background": "#d7d6c8", "text": { "family": "Zed Mono", "color": "#002b36", @@ -1014,7 +1014,7 @@ } }, "filename_editor": { - "background": "#eee8d52e", + "background": "#f6efdc", "text": { "family": "Zed Mono", "color": "#073642", @@ -1098,7 +1098,7 @@ "right": 8 } }, - "background": "#93a1a11f", + "background": "#d7d6c8", "corner_radius": 6 }, "active_item": { @@ -1133,7 +1133,7 @@ "right": 8 } }, - "background": "#93a1a11f", + "background": "#d7d6c8", "corner_radius": 6 }, "menu": { @@ -1141,7 +1141,7 @@ "corner_radius": 6, "padding": 4, "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1 }, "shadow": { @@ -1232,7 +1232,7 @@ "selection": "#268bd23d" }, "border": { - "color": "#eee8d5", + "color": "#93a1a1", "width": 1 }, "padding": { @@ -1266,7 +1266,7 @@ "selection": "#268bd23d" }, "border": { - "color": "#eee8d5", + "color": "#93a1a1", "width": 1 }, "padding": { @@ -1307,7 +1307,7 @@ "family": "Zed Mono", "color": "#073642", "size": 14, - "background": "#93a1a12e" + "background": "#aab3ae" } }, "contact_row": { @@ -1316,17 +1316,17 @@ "right": 12 }, "active": { - "background": "#93a1a12e" + "background": "#aab3ae" } }, "tree_branch": { - "color": "#839496", + "color": "#657b83", "width": 1, "hover": { - "color": "#839496" + "color": "#657b83" }, "active": { - "color": "#839496" + "color": "#657b83" } }, "contact_avatar": { @@ -1343,17 +1343,17 @@ }, "contact_button_spacing": 8, "contact_button": { - "background": "#eee8d5", + "background": "#d7d6c8", "color": "#073642", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#93a1a11f" + "background": "#c1c5bb" } }, "disabled_contact_button": { - "background": "#eee8d5", + "background": "#d7d6c8", "color": "#586e75", "icon_width": 8, "button_width": 16, @@ -1387,10 +1387,10 @@ }, "background": "#eee8d5", "hover": { - "background": "#93a1a11f" + "background": "#d7d6c8" }, "active": { - "background": "#93a1a12e" + "background": "#c1c5bb" } }, "unshared_project_row": { @@ -1421,10 +1421,10 @@ }, "background": "#eee8d5", "hover": { - "background": "#93a1a11f" + "background": "#d7d6c8" }, "active": { - "background": "#93a1a12e" + "background": "#c1c5bb" } } }, @@ -1452,7 +1452,7 @@ "size": 14 }, "active": { - "background": "#93a1a12e", + "background": "#c1c5bb", "text": { "family": "Zed Sans", "color": "#073642", @@ -1460,11 +1460,11 @@ } }, "hover": { - "background": "#93a1a11f" + "background": "#d7d6c8" } }, "border": { - "color": "#fdf6e3", + "color": "#93a1a1", "width": 1 }, "empty": { @@ -1498,7 +1498,7 @@ "size": 14 }, "border": { - "color": "#eee8d5", + "color": "#93a1a1", "width": 1 }, "padding": { @@ -1527,17 +1527,17 @@ } }, "contact_button": { - "background": "#eee8d5", + "background": "#d7d6c8", "color": "#073642", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#93a1a11f" + "background": "#c1c5bb" } }, "disabled_contact_button": { - "background": "#eee8d5", + "background": "#d7d6c8", "color": "#586e75", "icon_width": 8, "button_width": 16, @@ -1545,17 +1545,17 @@ } }, "search": { - "match_background": "#6c71c43d", + "match_background": "#bcc0f6", "tab_icon_spacing": 8, "tab_icon_width": 14, "option_button": { "family": "Zed Mono", "color": "#586e75", "size": 14, - "background": "#eee8d5", + "background": "#d7d6c8", "corner_radius": 6, "border": { - "color": "#eee8d5", + "color": "#93a1a1", "width": 1 }, "margin": { @@ -1571,9 +1571,9 @@ "family": "Zed Mono", "color": "#002b36", "size": 14, - "background": "#93a1a13d", + "background": "#aab3ae", "border": { - "color": "#839496", + "color": "#657b83", "width": 1 } }, @@ -1581,9 +1581,9 @@ "family": "Zed Mono", "color": "#002b36", "size": 14, - "background": "#93a1a11f", + "background": "#c1c5bb", "border": { - "color": "#839496", + "color": "#657b83", "width": 1 } } @@ -1608,7 +1608,7 @@ "size": 14 }, "border": { - "color": "#eee8d5", + "color": "#93a1a1", "width": 1 }, "margin": { @@ -1717,7 +1717,7 @@ "left": 6 }, "hover": { - "background": "#eee8d51f" + "background": "#f9f3e0" } }, "dismiss_button": { diff --git a/assets/themes/sulphurpool-dark.json b/assets/themes/sulphurpool-dark.json index 607cecf990..d18e97dc55 100644 --- a/assets/themes/sulphurpool-dark.json +++ b/assets/themes/sulphurpool-dark.json @@ -23,7 +23,7 @@ "size": 14 }, "active": { - "background": "#5e66875c", + "background": "#444c6f", "text": { "family": "Zed Sans", "color": "#dfe2f1", @@ -31,7 +31,7 @@ } }, "hover": { - "background": "#5e66873d" + "background": "#363f62" } }, "border": { @@ -215,7 +215,7 @@ "size": 14 }, "icon_color": "#dfe2f1", - "background": "#5e66873d" + "background": "#363f62" } }, "diagnostic_message": { @@ -288,7 +288,7 @@ "left": 7, "right": 7 }, - "background": "#5e66873d" + "background": "#363f62" }, "container_warning": { "corner_radius": 6, @@ -335,11 +335,11 @@ "icon_color": "#979db4", "hover": { "icon_color": "#dfe2f1", - "background": "#5e66873d" + "background": "#363f62" }, "active": { "icon_color": "#f5f7ff", - "background": "#5e66875c" + "background": "#444c6f" } }, "badge": { @@ -361,7 +361,7 @@ "avatar_width": 18, "avatar_margin": 8, "height": 33, - "background": "#293256", + "background": "#363f62", "padding": { "left": 80, "right": 6 @@ -426,15 +426,15 @@ }, "color": "#979db4", "hover": { - "background": "#5e66873d", + "background": "#444c6f", "color": "#979db4" }, "active": { - "background": "#5e66875c", + "background": "#51597b", "color": "#f5f7ff" }, "active_hover": { - "background": "#5e66873d", + "background": "#444c6f", "color": "#f5f7ff" } }, @@ -515,16 +515,16 @@ "editor": { "text_color": "#f5f7ff", "background": "#202746", - "active_line_background": "#f5f7ff12", + "active_line_background": "#293256", "code_actions_indicator": "#979db4", "diff_background_deleted": "#c9492226", "diff_background_inserted": "#ac973926", - "document_highlight_read_background": "#f5f7ff1f", - "document_highlight_write_background": "#f5f7ff3d", + "document_highlight_read_background": "#5e66873d", + "document_highlight_write_background": "#5e66877a", "error_color": "#c94922", "gutter_background": "#202746", "gutter_padding_factor": 3.5, - "highlighted_line_background": "#f5f7ff1f", + "highlighted_line_background": "#363f62", "line_number": "#898ea4", "line_number_active": "#f5f7ff", "rename_fade": 0.6, @@ -588,7 +588,7 @@ "right": 6, "top": 2 }, - "background": "#2932563d" + "background": "#222a4a" }, "margin": { "left": -14 @@ -606,7 +606,7 @@ "right": 6, "top": 2 }, - "background": "#2932565c" + "background": "#252d4e" } }, "diagnostic_header": { @@ -642,7 +642,7 @@ } }, "diagnostic_path_header": { - "background": "#f5f7ff12", + "background": "#293256", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", @@ -852,7 +852,7 @@ "weight": "normal" }, "punctuation": { - "color": "#979db4", + "color": "#dfe2f1", "weight": "normal" }, "constant": { @@ -989,7 +989,7 @@ "size": 14 }, "hover": { - "background": "#5e66873d", + "background": "#363f62", "text": { "family": "Zed Mono", "color": "#dfe2f1", @@ -997,7 +997,7 @@ } }, "active": { - "background": "#5e66875c", + "background": "#444c6f", "text": { "family": "Zed Mono", "color": "#dfe2f1", @@ -1005,7 +1005,7 @@ } }, "active_hover": { - "background": "#5e66873d", + "background": "#363f62", "text": { "family": "Zed Mono", "color": "#f5f7ff", @@ -1014,7 +1014,7 @@ } }, "filename_editor": { - "background": "#2932565c", + "background": "#252d4e", "text": { "family": "Zed Mono", "color": "#dfe2f1", @@ -1098,7 +1098,7 @@ "right": 8 } }, - "background": "#5e66873d", + "background": "#363f62", "corner_radius": 6 }, "active_item": { @@ -1133,7 +1133,7 @@ "right": 8 } }, - "background": "#5e66873d", + "background": "#363f62", "corner_radius": 6 }, "menu": { @@ -1307,7 +1307,7 @@ "family": "Zed Mono", "color": "#dfe2f1", "size": 14, - "background": "#5e66875c" + "background": "#51597b" } }, "contact_row": { @@ -1316,7 +1316,7 @@ "right": 12 }, "active": { - "background": "#5e66875c" + "background": "#51597b" } }, "tree_branch": { @@ -1343,17 +1343,17 @@ }, "contact_button_spacing": 8, "contact_button": { - "background": "#293256", + "background": "#363f62", "color": "#dfe2f1", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#5e66873d" + "background": "#444c6f" } }, "disabled_contact_button": { - "background": "#293256", + "background": "#363f62", "color": "#979db4", "icon_width": 8, "button_width": 16, @@ -1387,10 +1387,10 @@ }, "background": "#293256", "hover": { - "background": "#5e66873d" + "background": "#363f62" }, "active": { - "background": "#5e66875c" + "background": "#444c6f" } }, "unshared_project_row": { @@ -1421,10 +1421,10 @@ }, "background": "#293256", "hover": { - "background": "#5e66873d" + "background": "#363f62" }, "active": { - "background": "#5e66875c" + "background": "#444c6f" } } }, @@ -1452,7 +1452,7 @@ "size": 14 }, "active": { - "background": "#5e66875c", + "background": "#444c6f", "text": { "family": "Zed Sans", "color": "#dfe2f1", @@ -1460,7 +1460,7 @@ } }, "hover": { - "background": "#5e66873d" + "background": "#363f62" } }, "border": { @@ -1527,17 +1527,17 @@ } }, "contact_button": { - "background": "#293256", + "background": "#363f62", "color": "#dfe2f1", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#5e66873d" + "background": "#444c6f" } }, "disabled_contact_button": { - "background": "#293256", + "background": "#363f62", "color": "#979db4", "icon_width": 8, "button_width": 16, @@ -1545,14 +1545,14 @@ } }, "search": { - "match_background": "#6679cc7a", + "match_background": "#1a2a6d", "tab_icon_spacing": 8, "tab_icon_width": 14, "option_button": { "family": "Zed Mono", "color": "#979db4", "size": 14, - "background": "#293256", + "background": "#363f62", "corner_radius": 6, "border": { "color": "#293256", @@ -1571,7 +1571,7 @@ "family": "Zed Mono", "color": "#f5f7ff", "size": 14, - "background": "#5e66877a", + "background": "#51597b", "border": { "color": "#6b7394", "width": 1 @@ -1581,7 +1581,7 @@ "family": "Zed Mono", "color": "#f5f7ff", "size": 14, - "background": "#5e66873d", + "background": "#444c6f", "border": { "color": "#6b7394", "width": 1 @@ -1717,7 +1717,7 @@ "left": 6 }, "hover": { - "background": "#2932563d" + "background": "#222a4a" } }, "dismiss_button": { diff --git a/assets/themes/sulphurpool-light.json b/assets/themes/sulphurpool-light.json index d66382331a..1572007012 100644 --- a/assets/themes/sulphurpool-light.json +++ b/assets/themes/sulphurpool-light.json @@ -23,7 +23,7 @@ "size": 14 }, "active": { - "background": "#979db42e", + "background": "#bbc0d3", "text": { "family": "Zed Sans", "color": "#293256", @@ -31,11 +31,11 @@ } }, "hover": { - "background": "#979db41f" + "background": "#cdd1e2" } }, "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1 }, "empty": { @@ -69,7 +69,7 @@ "size": 14 }, "border": { - "color": "#dfe2f1", + "color": "#979db4", "width": 1 }, "padding": { @@ -107,7 +107,7 @@ "size": 14 }, "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "left": true, "bottom": true, @@ -133,7 +133,7 @@ "size": 14 }, "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "left": true, "bottom": false, @@ -152,13 +152,13 @@ "cursor": "Arrow" }, "sidebar_resize_handle": { - "background": "#f5f7ff", + "background": "#979db4", "padding": { "left": 1 } }, "pane_divider": { - "color": "#dfe2f1", + "color": "#979db4", "width": 1 }, "status_bar": { @@ -171,7 +171,7 @@ "right": 6 }, "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "top": true, "overlay": true @@ -215,7 +215,7 @@ "size": 14 }, "icon_color": "#293256", - "background": "#979db41f" + "background": "#cdd1e2" } }, "diagnostic_message": { @@ -288,7 +288,7 @@ "left": 7, "right": 7 }, - "background": "#979db41f" + "background": "#cdd1e2" }, "container_warning": { "corner_radius": 6, @@ -335,11 +335,11 @@ "icon_color": "#5e6687", "hover": { "icon_color": "#293256", - "background": "#979db41f" + "background": "#cdd1e2" }, "active": { "icon_color": "#202746", - "background": "#979db42e" + "background": "#bbc0d3" } }, "badge": { @@ -361,7 +361,7 @@ "avatar_width": 18, "avatar_margin": 8, "height": 33, - "background": "#dfe2f1", + "background": "#cdd1e2", "padding": { "left": 80, "right": 6 @@ -383,14 +383,14 @@ "width": 12 }, "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "bottom": true, "overlay": true }, "sign_in_prompt": { "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1 }, "corner_radius": 6, @@ -426,15 +426,15 @@ }, "color": "#5e6687", "hover": { - "background": "#979db41f", + "background": "#bbc0d3", "color": "#5e6687" }, "active": { - "background": "#979db42e", + "background": "#a9aec3", "color": "#202746" }, "active_hover": { - "background": "#979db41f", + "background": "#bbc0d3", "color": "#202746" } }, @@ -458,7 +458,7 @@ "height": 34, "background": "#f5f7ff", "border": { - "color": "#dfe2f1", + "color": "#979db4", "width": 1, "bottom": true }, @@ -492,7 +492,7 @@ "corner_radius": 6, "padding": 12, "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1 }, "shadow": { @@ -515,16 +515,16 @@ "editor": { "text_color": "#202746", "background": "#f5f7ff", - "active_line_background": "#20274612", + "active_line_background": "#dfe2f1", "code_actions_indicator": "#5e6687", "diff_background_deleted": "#c9492226", "diff_background_inserted": "#ac973926", - "document_highlight_read_background": "#2027460f", - "document_highlight_write_background": "#2027461f", + "document_highlight_read_background": "#979db41f", + "document_highlight_write_background": "#979db43d", "error_color": "#c94922", "gutter_background": "#f5f7ff", "gutter_padding_factor": 3.5, - "highlighted_line_background": "#2027461f", + "highlighted_line_background": "#cdd1e2", "line_number": "#6b7394", "line_number_active": "#202746", "rename_fade": 0.6, @@ -568,7 +568,7 @@ "corner_radius": 8, "padding": 4, "border": { - "color": "#dfe2f1", + "color": "#979db4", "width": 1 }, "item": { @@ -588,7 +588,7 @@ "right": 6, "top": 2 }, - "background": "#dfe2f11f" + "background": "#f0f2fc" }, "margin": { "left": -14 @@ -606,7 +606,7 @@ "right": 6, "top": 2 }, - "background": "#dfe2f12e" + "background": "#eaedf8" } }, "diagnostic_header": { @@ -614,7 +614,7 @@ "icon_width_factor": 1.5, "text_scale_factor": 0.857, "border": { - "color": "#dfe2f1", + "color": "#979db4", "width": 1, "bottom": true, "top": true @@ -642,7 +642,7 @@ } }, "diagnostic_path_header": { - "background": "#20274612", + "background": "#dfe2f1", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", @@ -662,7 +662,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "top": true } @@ -685,7 +685,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "top": true } @@ -708,7 +708,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "top": true } @@ -731,7 +731,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "top": true } @@ -754,7 +754,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "top": true } @@ -777,7 +777,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "top": true } @@ -800,7 +800,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "top": true } @@ -823,7 +823,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1, "top": true } @@ -852,7 +852,7 @@ "weight": "normal" }, "punctuation": { - "color": "#5e6687", + "color": "#293256", "weight": "normal" }, "constant": { @@ -949,7 +949,7 @@ "corner_radius": 4, "background": "#f5f7ff", "border": { - "color": "#dfe2f1", + "color": "#979db4", "width": 1 }, "padding": { @@ -989,7 +989,7 @@ "size": 14 }, "hover": { - "background": "#979db41f", + "background": "#cdd1e2", "text": { "family": "Zed Mono", "color": "#293256", @@ -997,7 +997,7 @@ } }, "active": { - "background": "#979db42e", + "background": "#bbc0d3", "text": { "family": "Zed Mono", "color": "#293256", @@ -1005,7 +1005,7 @@ } }, "active_hover": { - "background": "#979db41f", + "background": "#cdd1e2", "text": { "family": "Zed Mono", "color": "#202746", @@ -1014,7 +1014,7 @@ } }, "filename_editor": { - "background": "#dfe2f12e", + "background": "#eaedf8", "text": { "family": "Zed Mono", "color": "#293256", @@ -1098,7 +1098,7 @@ "right": 8 } }, - "background": "#979db41f", + "background": "#cdd1e2", "corner_radius": 6 }, "active_item": { @@ -1133,7 +1133,7 @@ "right": 8 } }, - "background": "#979db41f", + "background": "#cdd1e2", "corner_radius": 6 }, "menu": { @@ -1141,7 +1141,7 @@ "corner_radius": 6, "padding": 4, "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1 }, "shadow": { @@ -1232,7 +1232,7 @@ "selection": "#3d8fd13d" }, "border": { - "color": "#dfe2f1", + "color": "#979db4", "width": 1 }, "padding": { @@ -1266,7 +1266,7 @@ "selection": "#3d8fd13d" }, "border": { - "color": "#dfe2f1", + "color": "#979db4", "width": 1 }, "padding": { @@ -1307,7 +1307,7 @@ "family": "Zed Mono", "color": "#293256", "size": 14, - "background": "#979db42e" + "background": "#a9aec3" } }, "contact_row": { @@ -1316,17 +1316,17 @@ "right": 12 }, "active": { - "background": "#979db42e" + "background": "#a9aec3" } }, "tree_branch": { - "color": "#898ea4", + "color": "#6b7394", "width": 1, "hover": { - "color": "#898ea4" + "color": "#6b7394" }, "active": { - "color": "#898ea4" + "color": "#6b7394" } }, "contact_avatar": { @@ -1343,17 +1343,17 @@ }, "contact_button_spacing": 8, "contact_button": { - "background": "#dfe2f1", + "background": "#cdd1e2", "color": "#293256", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#979db41f" + "background": "#bbc0d3" } }, "disabled_contact_button": { - "background": "#dfe2f1", + "background": "#cdd1e2", "color": "#5e6687", "icon_width": 8, "button_width": 16, @@ -1387,10 +1387,10 @@ }, "background": "#dfe2f1", "hover": { - "background": "#979db41f" + "background": "#cdd1e2" }, "active": { - "background": "#979db42e" + "background": "#bbc0d3" } }, "unshared_project_row": { @@ -1421,10 +1421,10 @@ }, "background": "#dfe2f1", "hover": { - "background": "#979db41f" + "background": "#cdd1e2" }, "active": { - "background": "#979db42e" + "background": "#bbc0d3" } } }, @@ -1452,7 +1452,7 @@ "size": 14 }, "active": { - "background": "#979db42e", + "background": "#bbc0d3", "text": { "family": "Zed Sans", "color": "#293256", @@ -1460,11 +1460,11 @@ } }, "hover": { - "background": "#979db41f" + "background": "#cdd1e2" } }, "border": { - "color": "#f5f7ff", + "color": "#979db4", "width": 1 }, "empty": { @@ -1498,7 +1498,7 @@ "size": 14 }, "border": { - "color": "#dfe2f1", + "color": "#979db4", "width": 1 }, "padding": { @@ -1527,17 +1527,17 @@ } }, "contact_button": { - "background": "#dfe2f1", + "background": "#cdd1e2", "color": "#293256", "icon_width": 8, "button_width": 16, "corner_radius": 8, "hover": { - "background": "#979db41f" + "background": "#bbc0d3" } }, "disabled_contact_button": { - "background": "#dfe2f1", + "background": "#cdd1e2", "color": "#5e6687", "icon_width": 8, "button_width": 16, @@ -1545,17 +1545,17 @@ } }, "search": { - "match_background": "#6679cc3d", + "match_background": "#bcc6f7", "tab_icon_spacing": 8, "tab_icon_width": 14, "option_button": { "family": "Zed Mono", "color": "#5e6687", "size": 14, - "background": "#dfe2f1", + "background": "#cdd1e2", "corner_radius": 6, "border": { - "color": "#dfe2f1", + "color": "#979db4", "width": 1 }, "margin": { @@ -1571,9 +1571,9 @@ "family": "Zed Mono", "color": "#202746", "size": 14, - "background": "#979db43d", + "background": "#a9aec3", "border": { - "color": "#898ea4", + "color": "#6b7394", "width": 1 } }, @@ -1581,9 +1581,9 @@ "family": "Zed Mono", "color": "#202746", "size": 14, - "background": "#979db41f", + "background": "#bbc0d3", "border": { - "color": "#898ea4", + "color": "#6b7394", "width": 1 } } @@ -1608,7 +1608,7 @@ "size": 14 }, "border": { - "color": "#dfe2f1", + "color": "#979db4", "width": 1 }, "margin": { @@ -1717,7 +1717,7 @@ "left": 6 }, "hover": { - "background": "#dfe2f11f" + "background": "#f0f2fc" } }, "dismiss_button": { diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index c6ad68ace6..c73035cc71 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -12,7 +12,7 @@ use std::{collections::HashMap, sync::Arc}; pub use theme_registry::*; -pub const DEFAULT_THEME_NAME: &'static str = "dark"; +pub const DEFAULT_THEME_NAME: &'static str = "cave-dark"; #[derive(Deserialize, Default)] pub struct Theme { diff --git a/styles/dist/dark.json b/styles/dist/dark.json index dac975e8f0..cf780140dd 100644 --- a/styles/dist/dark.json +++ b/styles/dist/dark.json @@ -1,698 +1,531 @@ { "meta": { - "themeName": "dark" + "themeName": "cave-dark" }, "text": { "primary": { - "value": "#f1f1f1", - "description": "Step: 50", + "value": "#e2dfe7", "type": "color" }, "secondary": { - "value": "#9c9c9c", - "description": "Step: 350", + "value": "#8b8792", "type": "color" }, "muted": { - "value": "#808080", - "description": "Step: 450", + "value": "#8b8792", "type": "color" }, "placeholder": { - "value": "#474747", - "description": "Step: 650", + "value": "#7e7887", "type": "color" }, "active": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#efecf4", "type": "color" }, "feature": { - "value": "#4f8ff7", - "description": "Step: 400", + "value": "#576ddb", "type": "color" }, "ok": { - "value": "#1b9447", - "description": "Step: 600", + "value": "#2a9292", "type": "color" }, "error": { - "value": "#f15656", - "description": "Step: 400", + "value": "#be4678", "type": "color" }, "warning": { - "value": "#f7bb57", - "description": "Step: 300", + "value": "#a06e3b", "type": "color" }, "info": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" } }, "icon": { "primary": { - "value": "#c6c6c6", - "description": "Step: 200", + "value": "#e2dfe7", "type": "color" }, "secondary": { - "value": "#9c9c9c", - "description": "Step: 350", + "value": "#8b8792", "type": "color" }, "muted": { - "value": "#555555", - "description": "Step: 600", + "value": "#8b8792", "type": "color" }, "placeholder": { - "value": "#393939", - "description": "Step: 700", + "value": "#7e7887", "type": "color" }, "active": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#efecf4", "type": "color" }, "feature": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "ok": { - "value": "#1b9447", - "description": "Step: 600", + "value": "#2a9292", "type": "color" }, "error": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#be4678", "type": "color" }, "warning": { - "value": "#f6a724", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "info": { - "value": "#135acd", - "description": "Step: 600", + "value": "#576ddb", "type": "color" } }, "background": { "100": { "base": { - "value": "#2b2b2b", - "description": "Step: 750", + "value": "#26232a", "type": "color" }, "hovered": { - "value": "#323232", - "description": "Step: 725", + "value": "#5852603d", "type": "color" }, "active": { - "value": "#1c1c1c", - "description": "Step: 800", - "type": "color" - }, - "focused": { - "value": "#404040", - "description": "Step: 675", + "value": "#5852605c", "type": "color" } }, "300": { "base": { - "value": "#1c1c1c", - "description": "Step: 800", + "value": "#26232a", "type": "color" }, "hovered": { - "value": "#232323", - "description": "Step: 775", + "value": "#5852603d", "type": "color" }, "active": { - "value": "#2b2b2b", - "description": "Step: 750", - "type": "color" - }, - "focused": { - "value": "#232323", - "description": "Step: 775", + "value": "#5852605c", "type": "color" } }, "500": { "base": { - "value": "#000000", - "description": "Step: 900", + "value": "#19171c", "type": "color" }, "hovered": { - "value": "#ffffff14", - "description": "Step: 0", + "value": "#26232a3d", "type": "color" }, "active": { - "value": "#ffffff1f", - "description": "Step: 0", - "type": "color" - }, - "focused": { - "value": "#151515", - "description": "Step: 825", + "value": "#26232a5c", "type": "color" } }, "on300": { "base": { - "value": "#0e0e0e80", - "description": "Step: 850", + "value": "#19171c", "type": "color" }, "hovered": { - "value": "#070707", - "description": "Step: 875", + "value": "#26232a3d", "type": "color" }, "active": { - "value": "#000000", - "description": "Step: 900", - "type": "color" - }, - "focused": { - "value": "#070707", - "description": "Step: 875", + "value": "#26232a7a", "type": "color" } }, "on500": { "base": { - "value": "#0e0e0e", - "description": "Step: 850", + "value": "#26232a", "type": "color" }, "hovered": { - "value": "#1c1c1c", - "description": "Step: 800", + "value": "#5852603d", "type": "color" }, "active": { - "value": "#232323", - "description": "Step: 775", - "type": "color" - }, - "focused": { - "value": "#1c1c1c", - "description": "Step: 800", + "value": "#5852607a", "type": "color" } }, "ok": { "base": { - "value": "#1b944726", - "description": "Step: 600", + "value": "#2a929226", "type": "color" }, "hovered": { - "value": "#1b944733", - "description": "Step: 600", + "value": "#2a929233", "type": "color" }, "active": { - "value": "#1b944740", - "description": "Step: 600", - "type": "color" - }, - "focused": { - "value": "#1b944733", - "description": "Step: 600", + "value": "#2a929240", "type": "color" } }, "error": { "base": { - "value": "#c9181826", - "description": "Step: 600", + "value": "#be467826", "type": "color" }, "hovered": { - "value": "#c9181833", - "description": "Step: 600", + "value": "#be467833", "type": "color" }, "active": { - "value": "#c9181840", - "description": "Step: 600", - "type": "color" - }, - "focused": { - "value": "#c9181833", - "description": "Step: 600", + "value": "#be467840", "type": "color" } }, "warning": { "base": { - "value": "#f6a72426", - "description": "Step: 400", + "value": "#a06e3b26", "type": "color" }, "hovered": { - "value": "#f6a72433", - "description": "Step: 400", + "value": "#a06e3b33", "type": "color" }, "active": { - "value": "#f6a72440", - "description": "Step: 400", - "type": "color" - }, - "focused": { - "value": "#f6a72433", - "description": "Step: 400", + "value": "#a06e3b40", "type": "color" } }, "info": { "base": { - "value": "#2472f226", - "description": "Step: 500", + "value": "#576ddb26", "type": "color" }, "hovered": { - "value": "#2472f233", - "description": "Step: 500", + "value": "#576ddb33", "type": "color" }, "active": { - "value": "#2472f240", - "description": "Step: 500", - "type": "color" - }, - "focused": { - "value": "#2472f233", - "description": "Step: 500", + "value": "#576ddb40", "type": "color" } } }, "border": { "primary": { - "value": "#070707", - "description": "Step: 875", + "value": "#19171c", "type": "color" }, "secondary": { - "value": "#232323", - "description": "Step: 775", + "value": "#26232a", "type": "color" }, "muted": { - "value": "#404040", - "description": "Step: 675", - "type": "color" - }, - "focused": { - "value": "#484bed", - "description": "Step: 500", + "value": "#655f6d", "type": "color" }, "active": { - "value": "#000000", - "description": "Step: 900", + "value": "#655f6d", "type": "color" }, "onMedia": { - "value": "#0707071a", - "description": "Step: 875", + "value": "#19171c1a", "type": "color" }, "ok": { - "value": "#1b944726", - "description": "Step: 600", + "value": "#2a929226", "type": "color" }, "error": { - "value": "#eb2d2d26", - "description": "Step: 500", + "value": "#be467826", "type": "color" }, "warning": { - "value": "#f6a72426", - "description": "Step: 400", + "value": "#a06e3b26", "type": "color" }, "info": { - "value": "#2472f226", - "description": "Step: 500", + "value": "#576ddb26", "type": "color" } }, "editor": { "background": { - "value": "#000000", - "description": "Step: 900", + "value": "#19171c", "type": "color" }, "indent_guide": { - "value": "#404040", - "description": "Step: 675", + "value": "#655f6d", "type": "color" }, "indent_guide_active": { - "value": "#232323", - "description": "Step: 775", + "value": "#26232a", "type": "color" }, "line": { "active": { - "value": "#ffffff12", - "description": "Step: 0", + "value": "#efecf412", "type": "color" }, "highlighted": { - "value": "#ffffff1f", - "description": "Step: 0", + "value": "#efecf41f", "type": "color" }, "inserted": { - "value": "#1b944740", - "description": "Step: 600", + "value": "#2a929240", "type": "color" }, "deleted": { - "value": "#c9181840", - "description": "Step: 600", + "value": "#be467840", "type": "color" }, "modified": { - "value": "#2472f240", - "description": "Step: 500", + "value": "#576ddb40", "type": "color" } }, "highlight": { "selection": { - "value": "#2472f23d", - "description": "Step: 500", + "value": "#576ddb3d", "type": "color" }, "occurrence": { - "value": "#ffffff1f", - "description": "Step: 0", + "value": "#efecf41f", "type": "color" }, "activeOccurrence": { - "value": "#ffffff29", - "description": "Step: 0", + "value": "#efecf43d", "type": "color" }, "matchingBracket": { - "value": "#ffffff1f", - "description": "Step: 0", + "value": "#26232a5c", "type": "color" }, "match": { - "value": "#3f15a380", - "description": "Step: 700", + "value": "#955ae77a", "type": "color" }, "activeMatch": { - "value": "#5316e0b3", - "description": "Step: 600", + "value": "#955ae7b8", "type": "color" }, "related": { - "value": "#151515", - "description": "Step: 825", + "value": "#26232a3d", "type": "color" } }, "gutter": { "primary": { - "value": "#474747", - "description": "Step: 650", + "value": "#7e7887", "type": "color" }, "active": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#efecf4", "type": "color" } } }, "syntax": { "primary": { - "value": "#d5d5d5", - "description": "Step: 150", + "value": "#efecf4", "type": "color" }, "comment": { - "value": "#aaaaaa", - "description": "Step: 300", + "value": "#8b8792", "type": "color" }, "keyword": { - "value": "#4f8ff7", - "description": "Step: 400", + "value": "#576ddb", "type": "color" }, "function": { - "value": "#f9da82", - "description": "Step: 200", + "value": "#a06e3b", "type": "color" }, "type": { - "value": "#3eeeda", - "description": "Step: 300", + "value": "#398bc6", "type": "color" }, "variant": { - "value": "#53c1f5", - "description": "Step: 300", + "value": "#576ddb", "type": "color" }, "property": { - "value": "#4f8ff7", - "description": "Step: 400", + "value": "#576ddb", "type": "color" }, "enum": { - "value": "#ee670a", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "operator": { - "value": "#ee670a", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "string": { - "value": "#f99d5f", - "description": "Step: 300", + "value": "#aa573c", "type": "color" }, "number": { - "value": "#aeef4b", - "description": "Step: 300", + "value": "#2a9292", "type": "color" }, "boolean": { - "value": "#aeef4b", - "description": "Step: 300", + "value": "#2a9292", "type": "color" } }, "player": { "1": { "baseColor": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "cursorColor": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "selectionColor": { - "value": "#2472f23d", - "description": "Step: 500", + "value": "#576ddb3d", "type": "color" }, "borderColor": { - "value": "#2472f2cc", - "description": "Step: 500", + "value": "#576ddbcc", "type": "color" } }, "2": { "baseColor": { - "value": "#79ba16", - "description": "Step: 500", + "value": "#2a9292", "type": "color" }, "cursorColor": { - "value": "#79ba16", - "description": "Step: 500", + "value": "#2a9292", "type": "color" }, "selectionColor": { - "value": "#79ba163d", - "description": "Step: 500", + "value": "#2a92923d", "type": "color" }, "borderColor": { - "value": "#79ba16cc", - "description": "Step: 500", + "value": "#2a9292cc", "type": "color" } }, "3": { "baseColor": { - "value": "#d430e0", - "description": "Step: 500", + "value": "#bf40bf", "type": "color" }, "cursorColor": { - "value": "#d430e0", - "description": "Step: 500", + "value": "#bf40bf", "type": "color" }, "selectionColor": { - "value": "#d430e03d", - "description": "Step: 500", + "value": "#bf40bf3d", "type": "color" }, "borderColor": { - "value": "#d430e0cc", - "description": "Step: 500", + "value": "#bf40bfcc", "type": "color" } }, "4": { "baseColor": { - "value": "#ee670a", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "cursorColor": { - "value": "#ee670a", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "selectionColor": { - "value": "#ee670a3d", - "description": "Step: 500", + "value": "#aa573c3d", "type": "color" }, "borderColor": { - "value": "#ee670acc", - "description": "Step: 500", + "value": "#aa573ccc", "type": "color" } }, "5": { "baseColor": { - "value": "#993bf3", - "description": "Step: 500", + "value": "#955ae7", "type": "color" }, "cursorColor": { - "value": "#993bf3", - "description": "Step: 500", + "value": "#955ae7", "type": "color" }, "selectionColor": { - "value": "#993bf33d", - "description": "Step: 500", + "value": "#955ae73d", "type": "color" }, "borderColor": { - "value": "#993bf3cc", - "description": "Step: 500", + "value": "#955ae7cc", "type": "color" } }, "6": { "baseColor": { - "value": "#16d6c1", - "description": "Step: 400", + "value": "#398bc6", "type": "color" }, "cursorColor": { - "value": "#16d6c1", - "description": "Step: 400", + "value": "#398bc6", "type": "color" }, "selectionColor": { - "value": "#16d6c13d", - "description": "Step: 400", + "value": "#398bc63d", "type": "color" }, "borderColor": { - "value": "#16d6c1cc", - "description": "Step: 400", + "value": "#398bc6cc", "type": "color" } }, "7": { "baseColor": { - "value": "#ef59a3", - "description": "Step: 400", + "value": "#be4678", "type": "color" }, "cursorColor": { - "value": "#ef59a3", - "description": "Step: 400", + "value": "#be4678", "type": "color" }, "selectionColor": { - "value": "#ef59a33d", - "description": "Step: 400", + "value": "#be46783d", "type": "color" }, "borderColor": { - "value": "#ef59a3cc", - "description": "Step: 400", + "value": "#be4678cc", "type": "color" } }, "8": { "baseColor": { - "value": "#f7bf17", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "cursorColor": { - "value": "#f7bf17", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "selectionColor": { - "value": "#f7bf173d", - "description": "Step: 400", + "value": "#a06e3b3d", "type": "color" }, "borderColor": { - "value": "#f7bf17cc", - "description": "Step: 400", + "value": "#a06e3bcc", "type": "color" } } }, "shadowAlpha": { - "value": 0.32, + "value": 0.24, "type": "number" } } \ No newline at end of file diff --git a/styles/dist/light.json b/styles/dist/light.json index 806c50240e..1287dea481 100644 --- a/styles/dist/light.json +++ b/styles/dist/light.json @@ -1,692 +1,525 @@ { "meta": { - "themeName": "light" + "themeName": "cave-light" }, "text": { "primary": { - "value": "#2b2b2b", - "description": "Step: 750", + "value": "#26232a", "type": "color" }, "secondary": { - "value": "#474747", - "description": "Step: 650", + "value": "#585260", "type": "color" }, "muted": { - "value": "#636363", - "description": "Step: 550", + "value": "#585260", "type": "color" }, "placeholder": { - "value": "#808080", - "description": "Step: 450", + "value": "#655f6d", "type": "color" }, "active": { - "value": "#000000", - "description": "Step: 900", + "value": "#19171c", "type": "color" }, "feature": { - "value": "#484bed", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "ok": { - "value": "#20b456", - "description": "Step: 500", + "value": "#2a9292", "type": "color" }, "error": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#be4678", "type": "color" }, "warning": { - "value": "#d3a20b", - "description": "Step: 500", + "value": "#a06e3b", "type": "color" }, "info": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" } }, "icon": { "primary": { - "value": "#393939", - "description": "Step: 700", + "value": "#26232a", "type": "color" }, "secondary": { - "value": "#717171", - "description": "Step: 500", + "value": "#585260", "type": "color" }, "muted": { - "value": "#9c9c9c", - "description": "Step: 350", + "value": "#585260", "type": "color" }, "placeholder": { - "value": "#aaaaaa", - "description": "Step: 300", + "value": "#655f6d", "type": "color" }, "active": { - "value": "#000000", - "description": "Step: 900", + "value": "#19171c", "type": "color" }, "feature": { - "value": "#484bed", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "ok": { - "value": "#1b9447", - "description": "Step: 600", + "value": "#2a9292", "type": "color" }, "error": { - "value": "#c91818", - "description": "Step: 600", + "value": "#be4678", "type": "color" }, "warning": { - "value": "#f7bf17", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "info": { - "value": "#135acd", - "description": "Step: 600", + "value": "#576ddb", "type": "color" } }, "background": { "100": { "base": { - "value": "#eaeaea", - "description": "Step: 75", + "value": "#e2dfe7", "type": "color" }, "hovered": { - "value": "#e3e3e3", - "description": "Step: 100", + "value": "#8b87921f", "type": "color" }, "active": { - "value": "#d5d5d5", - "description": "Step: 150", - "type": "color" - }, - "focused": { - "value": "#e3e3e3", - "description": "Step: 100", + "value": "#8b87922e", "type": "color" } }, "300": { "base": { - "value": "#f8f8f8", - "description": "Step: 25", + "value": "#e2dfe7", "type": "color" }, "hovered": { - "value": "#eaeaea", - "description": "Step: 75", + "value": "#8b87921f", "type": "color" }, "active": { - "value": "#e3e3e3", - "description": "Step: 100", - "type": "color" - }, - "focused": { - "value": "#eaeaea", - "description": "Step: 75", + "value": "#8b87922e", "type": "color" } }, "500": { "base": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#efecf4", "type": "color" }, "hovered": { - "value": "#00000008", - "description": "Step: 900", + "value": "#e2dfe71f", "type": "color" }, "active": { - "value": "#0000000f", - "description": "Step: 900", - "type": "color" - }, - "focused": { - "value": "#f1f1f1", - "description": "Step: 50", + "value": "#e2dfe72e", "type": "color" } }, "on300": { "base": { - "value": "#f1f1f1", - "description": "Step: 50", + "value": "#efecf4", "type": "color" }, "hovered": { - "value": "#e3e3e3", - "description": "Step: 100", + "value": "#e2dfe71f", "type": "color" }, "active": { - "value": "#d5d5d5", - "description": "Step: 150", - "type": "color" - }, - "focused": { - "value": "#e3e3e3", - "description": "Step: 100", + "value": "#e2dfe73d", "type": "color" } }, "on500": { "base": { - "value": "#f1f1f1", - "description": "Step: 50", + "value": "#e2dfe7", "type": "color" }, "hovered": { - "value": "#f8f8f8", - "description": "Step: 25", + "value": "#8b87921f", "type": "color" }, "active": { - "value": "#ffffff", - "description": "Step: 0", - "type": "color" - }, - "focused": { - "value": "#f8f8f8", - "description": "Step: 25", + "value": "#8b87923d", "type": "color" } }, "ok": { "base": { - "value": "#1b944726", - "description": "Step: 600", + "value": "#2a929226", "type": "color" }, "hovered": { - "value": "#1b944733", - "description": "Step: 600", + "value": "#2a929233", "type": "color" }, "active": { - "value": "#1b944740", - "description": "Step: 600", - "type": "color" - }, - "focused": { - "value": "#1b944733", - "description": "Step: 600", + "value": "#2a929240", "type": "color" } }, "error": { "base": { - "value": "#c9181826", - "description": "Step: 600", + "value": "#be467826", "type": "color" }, "hovered": { - "value": "#c9181833", - "description": "Step: 600", + "value": "#be467833", "type": "color" }, "active": { - "value": "#c9181840", - "description": "Step: 600", - "type": "color" - }, - "focused": { - "value": "#c9181833", - "description": "Step: 600", + "value": "#be467840", "type": "color" } }, "warning": { "base": { - "value": "#f6a72426", - "description": "Step: 400", + "value": "#a06e3b26", "type": "color" }, "hovered": { - "value": "#f6a72433", - "description": "Step: 400", + "value": "#a06e3b33", "type": "color" }, "active": { - "value": "#f6a72440", - "description": "Step: 400", - "type": "color" - }, - "focused": { - "value": "#f6a72433", - "description": "Step: 400", + "value": "#a06e3b40", "type": "color" } }, "info": { "base": { - "value": "#2472f226", - "description": "Step: 500", + "value": "#576ddb26", "type": "color" }, "hovered": { - "value": "#2472f233", - "description": "Step: 500", + "value": "#576ddb33", "type": "color" }, "active": { - "value": "#2472f240", - "description": "Step: 500", - "type": "color" - }, - "focused": { - "value": "#2472f233", - "description": "Step: 500", + "value": "#576ddb40", "type": "color" } } }, "border": { "primary": { - "value": "#d5d5d5", - "description": "Step: 150", + "value": "#efecf4", "type": "color" }, "secondary": { - "value": "#d5d5d5", - "description": "Step: 150", + "value": "#e2dfe7", "type": "color" }, "muted": { - "value": "#e3e3e3", - "description": "Step: 100", - "type": "color" - }, - "focused": { - "value": "#484bed", - "description": "Step: 500", + "value": "#7e7887", "type": "color" }, "active": { - "value": "#b8b8b8", - "description": "Step: 250", + "value": "#7e7887", "type": "color" }, "onMedia": { - "value": "#b8b8b84d", - "description": "Step: 250", + "value": "#efecf41a", "type": "color" }, "ok": { - "value": "#1b944726", - "description": "Step: 600", + "value": "#2a929226", "type": "color" }, "error": { - "value": "#eb2d2d26", - "description": "Step: 500", + "value": "#be467826", "type": "color" }, "warning": { - "value": "#f6a72426", - "description": "Step: 400", + "value": "#a06e3b26", "type": "color" }, "info": { - "value": "#2472f226", - "description": "Step: 500", + "value": "#576ddb26", "type": "color" } }, "editor": { "background": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#efecf4", "type": "color" }, "indent_guide": { - "value": "#e3e3e3", - "description": "Step: 100", + "value": "#7e7887", "type": "color" }, "indent_guide_active": { - "value": "#d5d5d5", - "description": "Step: 150", + "value": "#e2dfe7", "type": "color" }, "line": { "active": { - "value": "#0000000f", - "description": "Step: 900", + "value": "#19171c12", "type": "color" }, "highlighted": { - "value": "#0000001f", - "description": "Step: 900", + "value": "#19171c1f", "type": "color" }, "inserted": { - "value": "#1b944740", - "description": "Step: 600", + "value": "#2a929240", "type": "color" }, "deleted": { - "value": "#c9181840", - "description": "Step: 600", + "value": "#be467840", "type": "color" }, "modified": { - "value": "#2472f240", - "description": "Step: 500", + "value": "#576ddb40", "type": "color" } }, "highlight": { "selection": { - "value": "#2472f23d", - "description": "Step: 500", + "value": "#576ddb3d", "type": "color" }, "occurrence": { - "value": "#0000000f", - "description": "Step: 900", + "value": "#19171c0f", "type": "color" }, "activeOccurrence": { - "value": "#00000029", - "description": "Step: 900", + "value": "#19171c1f", "type": "color" }, "matchingBracket": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#e2dfe72e", "type": "color" }, "match": { - "value": "#fce9b7", - "description": "Step: 100", + "value": "#955ae73d", "type": "color" }, "activeMatch": { - "value": "#f9da82", - "description": "Step: 200", + "value": "#955ae75c", "type": "color" }, "related": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#e2dfe71f", "type": "color" } }, "gutter": { "primary": { - "value": "#aaaaaa", - "description": "Step: 300", + "value": "#655f6d", "type": "color" }, "active": { - "value": "#000000", - "description": "Step: 900", + "value": "#19171c", "type": "color" } } }, "syntax": { "primary": { - "value": "#1c1c1c", - "description": "Step: 800", + "value": "#19171c", "type": "color" }, "comment": { - "value": "#717171", - "description": "Step: 500", + "value": "#585260", "type": "color" }, "keyword": { - "value": "#1819a1", - "description": "Step: 700", + "value": "#576ddb", "type": "color" }, "function": { - "value": "#bb550e", - "description": "Step: 600", + "value": "#a06e3b", "type": "color" }, "type": { - "value": "#a8820e", - "description": "Step: 600", + "value": "#398bc6", "type": "color" }, "variant": { - "value": "#97142a", - "description": "Step: 700", + "value": "#576ddb", "type": "color" }, "property": { - "value": "#106c4e", - "description": "Step: 700", + "value": "#576ddb", "type": "color" }, "enum": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "operator": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "string": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "number": { - "value": "#484bed", - "description": "Step: 500", + "value": "#2a9292", "type": "color" }, "boolean": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#2a9292", "type": "color" } }, "player": { "1": { "baseColor": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "cursorColor": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "selectionColor": { - "value": "#2472f23d", - "description": "Step: 500", + "value": "#576ddb3d", "type": "color" }, "borderColor": { - "value": "#2472f2cc", - "description": "Step: 500", + "value": "#576ddbcc", "type": "color" } }, "2": { "baseColor": { - "value": "#12d796", - "description": "Step: 400", + "value": "#2a9292", "type": "color" }, "cursorColor": { - "value": "#12d796", - "description": "Step: 400", + "value": "#2a9292", "type": "color" }, "selectionColor": { - "value": "#12d7963d", - "description": "Step: 400", + "value": "#2a92923d", "type": "color" }, "borderColor": { - "value": "#12d796cc", - "description": "Step: 400", + "value": "#2a9292cc", "type": "color" } }, "3": { "baseColor": { - "value": "#de57e8", - "description": "Step: 400", + "value": "#bf40bf", "type": "color" }, "cursorColor": { - "value": "#de57e8", - "description": "Step: 400", + "value": "#bf40bf", "type": "color" }, "selectionColor": { - "value": "#de57e83d", - "description": "Step: 400", + "value": "#bf40bf3d", "type": "color" }, "borderColor": { - "value": "#de57e8cc", - "description": "Step: 400", + "value": "#bf40bfcc", "type": "color" } }, "4": { "baseColor": { - "value": "#f9812e", - "description": "Step: 400", + "value": "#aa573c", "type": "color" }, "cursorColor": { - "value": "#f9812e", - "description": "Step: 400", + "value": "#aa573c", "type": "color" }, "selectionColor": { - "value": "#f9812e3d", - "description": "Step: 400", + "value": "#aa573c3d", "type": "color" }, "borderColor": { - "value": "#f9812ecc", - "description": "Step: 400", + "value": "#aa573ccc", "type": "color" } }, "5": { "baseColor": { - "value": "#b066f8", - "description": "Step: 400", + "value": "#955ae7", "type": "color" }, "cursorColor": { - "value": "#b066f8", - "description": "Step: 400", + "value": "#955ae7", "type": "color" }, "selectionColor": { - "value": "#b066f83d", - "description": "Step: 400", + "value": "#955ae73d", "type": "color" }, "borderColor": { - "value": "#b066f8cc", - "description": "Step: 400", + "value": "#955ae7cc", "type": "color" } }, "6": { "baseColor": { - "value": "#16d6c1", - "description": "Step: 400", + "value": "#398bc6", "type": "color" }, "cursorColor": { - "value": "#16d6c1", - "description": "Step: 400", + "value": "#398bc6", "type": "color" }, "selectionColor": { - "value": "#16d6c13d", - "description": "Step: 400", + "value": "#398bc63d", "type": "color" }, "borderColor": { - "value": "#16d6c1cc", - "description": "Step: 400", + "value": "#398bc6cc", "type": "color" } }, "7": { "baseColor": { - "value": "#ef59a3", - "description": "Step: 400", + "value": "#be4678", "type": "color" }, "cursorColor": { - "value": "#ef59a3", - "description": "Step: 400", + "value": "#be4678", "type": "color" }, "selectionColor": { - "value": "#ef59a33d", - "description": "Step: 400", + "value": "#be46783d", "type": "color" }, "borderColor": { - "value": "#ef59a3cc", - "description": "Step: 400", + "value": "#be4678cc", "type": "color" } }, "8": { "baseColor": { - "value": "#f7bf17", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "cursorColor": { - "value": "#f7bf17", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "selectionColor": { - "value": "#f7bf173d", - "description": "Step: 400", + "value": "#a06e3b3d", "type": "color" }, "borderColor": { - "value": "#f7bf17cc", - "description": "Step: 400", + "value": "#a06e3bcc", "type": "color" } } diff --git a/styles/dist/solarized-dark.json b/styles/dist/solarized-dark.json index c59a9dffad..11c58dc944 100644 --- a/styles/dist/solarized-dark.json +++ b/styles/dist/solarized-dark.json @@ -99,10 +99,6 @@ "active": { "value": "#586e755c", "type": "color" - }, - "focused": { - "value": "#586e753d", - "type": "color" } }, "300": { @@ -117,10 +113,6 @@ "active": { "value": "#586e755c", "type": "color" - }, - "focused": { - "value": "#586e753d", - "type": "color" } }, "500": { @@ -135,10 +127,6 @@ "active": { "value": "#0736425c", "type": "color" - }, - "focused": { - "value": "#0736423d", - "type": "color" } }, "on300": { @@ -153,10 +141,6 @@ "active": { "value": "#0736427a", "type": "color" - }, - "focused": { - "value": "#0736423d", - "type": "color" } }, "on500": { @@ -171,10 +155,6 @@ "active": { "value": "#586e757a", "type": "color" - }, - "focused": { - "value": "#586e753d", - "type": "color" } }, "ok": { @@ -189,10 +169,6 @@ "active": { "value": "#85990040", "type": "color" - }, - "focused": { - "value": "#85990033", - "type": "color" } }, "error": { @@ -207,10 +183,6 @@ "active": { "value": "#dc322f40", "type": "color" - }, - "focused": { - "value": "#dc322f33", - "type": "color" } }, "warning": { @@ -225,10 +197,6 @@ "active": { "value": "#b5890040", "type": "color" - }, - "focused": { - "value": "#b5890033", - "type": "color" } }, "info": { @@ -243,10 +211,6 @@ "active": { "value": "#268bd240", "type": "color" - }, - "focused": { - "value": "#268bd233", - "type": "color" } } }, @@ -263,10 +227,6 @@ "value": "#657b83", "type": "color" }, - "focused": { - "value": "#657b83", - "type": "color" - }, "active": { "value": "#657b83", "type": "color" diff --git a/styles/dist/solarized-light.json b/styles/dist/solarized-light.json index 21e8e4ba6f..0bd8dada67 100644 --- a/styles/dist/solarized-light.json +++ b/styles/dist/solarized-light.json @@ -99,10 +99,6 @@ "active": { "value": "#93a1a12e", "type": "color" - }, - "focused": { - "value": "#93a1a11f", - "type": "color" } }, "300": { @@ -117,10 +113,6 @@ "active": { "value": "#93a1a12e", "type": "color" - }, - "focused": { - "value": "#93a1a11f", - "type": "color" } }, "500": { @@ -135,10 +127,6 @@ "active": { "value": "#eee8d52e", "type": "color" - }, - "focused": { - "value": "#eee8d51f", - "type": "color" } }, "on300": { @@ -153,10 +141,6 @@ "active": { "value": "#eee8d53d", "type": "color" - }, - "focused": { - "value": "#eee8d51f", - "type": "color" } }, "on500": { @@ -171,10 +155,6 @@ "active": { "value": "#93a1a13d", "type": "color" - }, - "focused": { - "value": "#93a1a11f", - "type": "color" } }, "ok": { @@ -189,10 +169,6 @@ "active": { "value": "#85990040", "type": "color" - }, - "focused": { - "value": "#85990033", - "type": "color" } }, "error": { @@ -207,10 +183,6 @@ "active": { "value": "#dc322f40", "type": "color" - }, - "focused": { - "value": "#dc322f33", - "type": "color" } }, "warning": { @@ -225,10 +197,6 @@ "active": { "value": "#b5890040", "type": "color" - }, - "focused": { - "value": "#b5890033", - "type": "color" } }, "info": { @@ -243,10 +211,6 @@ "active": { "value": "#268bd240", "type": "color" - }, - "focused": { - "value": "#268bd233", - "type": "color" } } }, @@ -263,10 +227,6 @@ "value": "#839496", "type": "color" }, - "focused": { - "value": "#839496", - "type": "color" - }, "active": { "value": "#839496", "type": "color" diff --git a/styles/dist/tokens.json b/styles/dist/tokens.json index 9ed6998725..29a39b1fbe 100644 --- a/styles/dist/tokens.json +++ b/styles/dist/tokens.json @@ -1180,1393 +1180,1059 @@ } } }, - "dark": { + "cave-dark": { "meta": { - "themeName": "dark" + "themeName": "cave-dark" }, "text": { "primary": { - "value": "#f1f1f1", - "description": "Step: 50", + "value": "#e2dfe7", "type": "color" }, "secondary": { - "value": "#9c9c9c", - "description": "Step: 350", + "value": "#8b8792", "type": "color" }, "muted": { - "value": "#808080", - "description": "Step: 450", + "value": "#8b8792", "type": "color" }, "placeholder": { - "value": "#474747", - "description": "Step: 650", + "value": "#7e7887", "type": "color" }, "active": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#efecf4", "type": "color" }, "feature": { - "value": "#4f8ff7", - "description": "Step: 400", + "value": "#576ddb", "type": "color" }, "ok": { - "value": "#1b9447", - "description": "Step: 600", + "value": "#2a9292", "type": "color" }, "error": { - "value": "#f15656", - "description": "Step: 400", + "value": "#be4678", "type": "color" }, "warning": { - "value": "#f7bb57", - "description": "Step: 300", + "value": "#a06e3b", "type": "color" }, "info": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" } }, "icon": { "primary": { - "value": "#c6c6c6", - "description": "Step: 200", + "value": "#e2dfe7", "type": "color" }, "secondary": { - "value": "#9c9c9c", - "description": "Step: 350", + "value": "#8b8792", "type": "color" }, "muted": { - "value": "#555555", - "description": "Step: 600", + "value": "#8b8792", "type": "color" }, "placeholder": { - "value": "#393939", - "description": "Step: 700", + "value": "#7e7887", "type": "color" }, "active": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#efecf4", "type": "color" }, "feature": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "ok": { - "value": "#1b9447", - "description": "Step: 600", + "value": "#2a9292", "type": "color" }, "error": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#be4678", "type": "color" }, "warning": { - "value": "#f6a724", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "info": { - "value": "#135acd", - "description": "Step: 600", + "value": "#576ddb", "type": "color" } }, "background": { "100": { "base": { - "value": "#2b2b2b", - "description": "Step: 750", + "value": "#26232a", "type": "color" }, "hovered": { - "value": "#323232", - "description": "Step: 725", + "value": "#5852603d", "type": "color" }, "active": { - "value": "#1c1c1c", - "description": "Step: 800", - "type": "color" - }, - "focused": { - "value": "#404040", - "description": "Step: 675", + "value": "#5852605c", "type": "color" } }, "300": { "base": { - "value": "#1c1c1c", - "description": "Step: 800", + "value": "#26232a", "type": "color" }, "hovered": { - "value": "#232323", - "description": "Step: 775", + "value": "#5852603d", "type": "color" }, "active": { - "value": "#2b2b2b", - "description": "Step: 750", - "type": "color" - }, - "focused": { - "value": "#232323", - "description": "Step: 775", + "value": "#5852605c", "type": "color" } }, "500": { "base": { - "value": "#000000", - "description": "Step: 900", + "value": "#19171c", "type": "color" }, "hovered": { - "value": "#ffffff14", - "description": "Step: 0", + "value": "#26232a3d", "type": "color" }, "active": { - "value": "#ffffff1f", - "description": "Step: 0", - "type": "color" - }, - "focused": { - "value": "#151515", - "description": "Step: 825", + "value": "#26232a5c", "type": "color" } }, "on300": { "base": { - "value": "#0e0e0e80", - "description": "Step: 850", + "value": "#19171c", "type": "color" }, "hovered": { - "value": "#070707", - "description": "Step: 875", + "value": "#26232a3d", "type": "color" }, "active": { - "value": "#000000", - "description": "Step: 900", - "type": "color" - }, - "focused": { - "value": "#070707", - "description": "Step: 875", + "value": "#26232a7a", "type": "color" } }, "on500": { "base": { - "value": "#0e0e0e", - "description": "Step: 850", + "value": "#26232a", "type": "color" }, "hovered": { - "value": "#1c1c1c", - "description": "Step: 800", + "value": "#5852603d", "type": "color" }, "active": { - "value": "#232323", - "description": "Step: 775", - "type": "color" - }, - "focused": { - "value": "#1c1c1c", - "description": "Step: 800", + "value": "#5852607a", "type": "color" } }, "ok": { "base": { - "value": "#1b944726", - "description": "Step: 600", + "value": "#2a929226", "type": "color" }, "hovered": { - "value": "#1b944733", - "description": "Step: 600", + "value": "#2a929233", "type": "color" }, "active": { - "value": "#1b944740", - "description": "Step: 600", - "type": "color" - }, - "focused": { - "value": "#1b944733", - "description": "Step: 600", + "value": "#2a929240", "type": "color" } }, "error": { "base": { - "value": "#c9181826", - "description": "Step: 600", + "value": "#be467826", "type": "color" }, "hovered": { - "value": "#c9181833", - "description": "Step: 600", + "value": "#be467833", "type": "color" }, "active": { - "value": "#c9181840", - "description": "Step: 600", - "type": "color" - }, - "focused": { - "value": "#c9181833", - "description": "Step: 600", + "value": "#be467840", "type": "color" } }, "warning": { "base": { - "value": "#f6a72426", - "description": "Step: 400", + "value": "#a06e3b26", "type": "color" }, "hovered": { - "value": "#f6a72433", - "description": "Step: 400", + "value": "#a06e3b33", "type": "color" }, "active": { - "value": "#f6a72440", - "description": "Step: 400", - "type": "color" - }, - "focused": { - "value": "#f6a72433", - "description": "Step: 400", + "value": "#a06e3b40", "type": "color" } }, "info": { "base": { - "value": "#2472f226", - "description": "Step: 500", + "value": "#576ddb26", "type": "color" }, "hovered": { - "value": "#2472f233", - "description": "Step: 500", + "value": "#576ddb33", "type": "color" }, "active": { - "value": "#2472f240", - "description": "Step: 500", - "type": "color" - }, - "focused": { - "value": "#2472f233", - "description": "Step: 500", + "value": "#576ddb40", "type": "color" } } }, "border": { "primary": { - "value": "#070707", - "description": "Step: 875", + "value": "#19171c", "type": "color" }, "secondary": { - "value": "#232323", - "description": "Step: 775", + "value": "#26232a", "type": "color" }, "muted": { - "value": "#404040", - "description": "Step: 675", - "type": "color" - }, - "focused": { - "value": "#484bed", - "description": "Step: 500", + "value": "#655f6d", "type": "color" }, "active": { - "value": "#000000", - "description": "Step: 900", + "value": "#655f6d", "type": "color" }, "onMedia": { - "value": "#0707071a", - "description": "Step: 875", + "value": "#19171c1a", "type": "color" }, "ok": { - "value": "#1b944726", - "description": "Step: 600", + "value": "#2a929226", "type": "color" }, "error": { - "value": "#eb2d2d26", - "description": "Step: 500", + "value": "#be467826", "type": "color" }, "warning": { - "value": "#f6a72426", - "description": "Step: 400", + "value": "#a06e3b26", "type": "color" }, "info": { - "value": "#2472f226", - "description": "Step: 500", + "value": "#576ddb26", "type": "color" } }, "editor": { "background": { - "value": "#000000", - "description": "Step: 900", + "value": "#19171c", "type": "color" }, "indent_guide": { - "value": "#404040", - "description": "Step: 675", + "value": "#655f6d", "type": "color" }, "indent_guide_active": { - "value": "#232323", - "description": "Step: 775", + "value": "#26232a", "type": "color" }, "line": { "active": { - "value": "#ffffff12", - "description": "Step: 0", + "value": "#efecf412", "type": "color" }, "highlighted": { - "value": "#ffffff1f", - "description": "Step: 0", + "value": "#efecf41f", "type": "color" }, "inserted": { - "value": "#1b944740", - "description": "Step: 600", + "value": "#2a929240", "type": "color" }, "deleted": { - "value": "#c9181840", - "description": "Step: 600", + "value": "#be467840", "type": "color" }, "modified": { - "value": "#2472f240", - "description": "Step: 500", + "value": "#576ddb40", "type": "color" } }, "highlight": { "selection": { - "value": "#2472f23d", - "description": "Step: 500", + "value": "#576ddb3d", "type": "color" }, "occurrence": { - "value": "#ffffff1f", - "description": "Step: 0", + "value": "#efecf41f", "type": "color" }, "activeOccurrence": { - "value": "#ffffff29", - "description": "Step: 0", + "value": "#efecf43d", "type": "color" }, "matchingBracket": { - "value": "#ffffff1f", - "description": "Step: 0", + "value": "#26232a5c", "type": "color" }, "match": { - "value": "#3f15a380", - "description": "Step: 700", + "value": "#955ae77a", "type": "color" }, "activeMatch": { - "value": "#5316e0b3", - "description": "Step: 600", + "value": "#955ae7b8", "type": "color" }, "related": { - "value": "#151515", - "description": "Step: 825", + "value": "#26232a3d", "type": "color" } }, "gutter": { "primary": { - "value": "#474747", - "description": "Step: 650", + "value": "#7e7887", "type": "color" }, "active": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#efecf4", "type": "color" } } }, "syntax": { "primary": { - "value": "#d5d5d5", - "description": "Step: 150", + "value": "#efecf4", "type": "color" }, "comment": { - "value": "#aaaaaa", - "description": "Step: 300", + "value": "#8b8792", "type": "color" }, "keyword": { - "value": "#4f8ff7", - "description": "Step: 400", + "value": "#576ddb", "type": "color" }, "function": { - "value": "#f9da82", - "description": "Step: 200", + "value": "#a06e3b", "type": "color" }, "type": { - "value": "#3eeeda", - "description": "Step: 300", + "value": "#398bc6", "type": "color" }, "variant": { - "value": "#53c1f5", - "description": "Step: 300", + "value": "#576ddb", "type": "color" }, "property": { - "value": "#4f8ff7", - "description": "Step: 400", + "value": "#576ddb", "type": "color" }, "enum": { - "value": "#ee670a", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "operator": { - "value": "#ee670a", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "string": { - "value": "#f99d5f", - "description": "Step: 300", + "value": "#aa573c", "type": "color" }, "number": { - "value": "#aeef4b", - "description": "Step: 300", + "value": "#2a9292", "type": "color" }, "boolean": { - "value": "#aeef4b", - "description": "Step: 300", + "value": "#2a9292", "type": "color" } }, "player": { "1": { "baseColor": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "cursorColor": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "selectionColor": { - "value": "#2472f23d", - "description": "Step: 500", + "value": "#576ddb3d", "type": "color" }, "borderColor": { - "value": "#2472f2cc", - "description": "Step: 500", + "value": "#576ddbcc", "type": "color" } }, "2": { "baseColor": { - "value": "#79ba16", - "description": "Step: 500", + "value": "#2a9292", "type": "color" }, "cursorColor": { - "value": "#79ba16", - "description": "Step: 500", + "value": "#2a9292", "type": "color" }, "selectionColor": { - "value": "#79ba163d", - "description": "Step: 500", + "value": "#2a92923d", "type": "color" }, "borderColor": { - "value": "#79ba16cc", - "description": "Step: 500", + "value": "#2a9292cc", "type": "color" } }, "3": { "baseColor": { - "value": "#d430e0", - "description": "Step: 500", + "value": "#bf40bf", "type": "color" }, "cursorColor": { - "value": "#d430e0", - "description": "Step: 500", + "value": "#bf40bf", "type": "color" }, "selectionColor": { - "value": "#d430e03d", - "description": "Step: 500", + "value": "#bf40bf3d", "type": "color" }, "borderColor": { - "value": "#d430e0cc", - "description": "Step: 500", + "value": "#bf40bfcc", "type": "color" } }, "4": { "baseColor": { - "value": "#ee670a", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "cursorColor": { - "value": "#ee670a", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "selectionColor": { - "value": "#ee670a3d", - "description": "Step: 500", + "value": "#aa573c3d", "type": "color" }, "borderColor": { - "value": "#ee670acc", - "description": "Step: 500", + "value": "#aa573ccc", "type": "color" } }, "5": { "baseColor": { - "value": "#993bf3", - "description": "Step: 500", + "value": "#955ae7", "type": "color" }, "cursorColor": { - "value": "#993bf3", - "description": "Step: 500", + "value": "#955ae7", "type": "color" }, "selectionColor": { - "value": "#993bf33d", - "description": "Step: 500", + "value": "#955ae73d", "type": "color" }, "borderColor": { - "value": "#993bf3cc", - "description": "Step: 500", + "value": "#955ae7cc", "type": "color" } }, "6": { "baseColor": { - "value": "#16d6c1", - "description": "Step: 400", + "value": "#398bc6", "type": "color" }, "cursorColor": { - "value": "#16d6c1", - "description": "Step: 400", + "value": "#398bc6", "type": "color" }, "selectionColor": { - "value": "#16d6c13d", - "description": "Step: 400", + "value": "#398bc63d", "type": "color" }, "borderColor": { - "value": "#16d6c1cc", - "description": "Step: 400", + "value": "#398bc6cc", "type": "color" } }, "7": { "baseColor": { - "value": "#ef59a3", - "description": "Step: 400", + "value": "#be4678", "type": "color" }, "cursorColor": { - "value": "#ef59a3", - "description": "Step: 400", + "value": "#be4678", "type": "color" }, "selectionColor": { - "value": "#ef59a33d", - "description": "Step: 400", + "value": "#be46783d", "type": "color" }, "borderColor": { - "value": "#ef59a3cc", - "description": "Step: 400", + "value": "#be4678cc", "type": "color" } }, "8": { "baseColor": { - "value": "#f7bf17", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "cursorColor": { - "value": "#f7bf17", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "selectionColor": { - "value": "#f7bf173d", - "description": "Step: 400", + "value": "#a06e3b3d", "type": "color" }, "borderColor": { - "value": "#f7bf17cc", - "description": "Step: 400", + "value": "#a06e3bcc", "type": "color" } } }, "shadowAlpha": { - "value": 0.32, + "value": 0.24, "type": "number" } }, - "light": { + "cave-light": { "meta": { - "themeName": "light" + "themeName": "cave-light" }, "text": { "primary": { - "value": "#2b2b2b", - "description": "Step: 750", + "value": "#26232a", "type": "color" }, "secondary": { - "value": "#474747", - "description": "Step: 650", + "value": "#585260", "type": "color" }, "muted": { - "value": "#636363", - "description": "Step: 550", + "value": "#585260", "type": "color" }, "placeholder": { - "value": "#808080", - "description": "Step: 450", + "value": "#655f6d", "type": "color" }, "active": { - "value": "#000000", - "description": "Step: 900", + "value": "#19171c", "type": "color" }, "feature": { - "value": "#484bed", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "ok": { - "value": "#20b456", - "description": "Step: 500", + "value": "#2a9292", "type": "color" }, "error": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#be4678", "type": "color" }, "warning": { - "value": "#d3a20b", - "description": "Step: 500", + "value": "#a06e3b", "type": "color" }, "info": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" } }, "icon": { "primary": { - "value": "#393939", - "description": "Step: 700", + "value": "#26232a", "type": "color" }, "secondary": { - "value": "#717171", - "description": "Step: 500", + "value": "#585260", "type": "color" }, "muted": { - "value": "#9c9c9c", - "description": "Step: 350", + "value": "#585260", "type": "color" }, "placeholder": { - "value": "#aaaaaa", - "description": "Step: 300", + "value": "#655f6d", "type": "color" }, "active": { - "value": "#000000", - "description": "Step: 900", + "value": "#19171c", "type": "color" }, "feature": { - "value": "#484bed", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "ok": { - "value": "#1b9447", - "description": "Step: 600", + "value": "#2a9292", "type": "color" }, "error": { - "value": "#c91818", - "description": "Step: 600", + "value": "#be4678", "type": "color" }, "warning": { - "value": "#f7bf17", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "info": { - "value": "#135acd", - "description": "Step: 600", + "value": "#576ddb", "type": "color" } }, "background": { "100": { "base": { - "value": "#eaeaea", - "description": "Step: 75", + "value": "#e2dfe7", "type": "color" }, "hovered": { - "value": "#e3e3e3", - "description": "Step: 100", + "value": "#8b87921f", "type": "color" }, "active": { - "value": "#d5d5d5", - "description": "Step: 150", - "type": "color" - }, - "focused": { - "value": "#e3e3e3", - "description": "Step: 100", + "value": "#8b87922e", "type": "color" } }, "300": { "base": { - "value": "#f8f8f8", - "description": "Step: 25", + "value": "#e2dfe7", "type": "color" }, "hovered": { - "value": "#eaeaea", - "description": "Step: 75", + "value": "#8b87921f", "type": "color" }, "active": { - "value": "#e3e3e3", - "description": "Step: 100", - "type": "color" - }, - "focused": { - "value": "#eaeaea", - "description": "Step: 75", + "value": "#8b87922e", "type": "color" } }, "500": { "base": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#efecf4", "type": "color" }, "hovered": { - "value": "#00000008", - "description": "Step: 900", + "value": "#e2dfe71f", "type": "color" }, "active": { - "value": "#0000000f", - "description": "Step: 900", - "type": "color" - }, - "focused": { - "value": "#f1f1f1", - "description": "Step: 50", + "value": "#e2dfe72e", "type": "color" } }, "on300": { "base": { - "value": "#f1f1f1", - "description": "Step: 50", + "value": "#efecf4", "type": "color" }, "hovered": { - "value": "#e3e3e3", - "description": "Step: 100", + "value": "#e2dfe71f", "type": "color" }, "active": { - "value": "#d5d5d5", - "description": "Step: 150", - "type": "color" - }, - "focused": { - "value": "#e3e3e3", - "description": "Step: 100", + "value": "#e2dfe73d", "type": "color" } }, "on500": { "base": { - "value": "#f1f1f1", - "description": "Step: 50", + "value": "#e2dfe7", "type": "color" }, "hovered": { - "value": "#f8f8f8", - "description": "Step: 25", + "value": "#8b87921f", "type": "color" }, "active": { - "value": "#ffffff", - "description": "Step: 0", - "type": "color" - }, - "focused": { - "value": "#f8f8f8", - "description": "Step: 25", + "value": "#8b87923d", "type": "color" } }, "ok": { "base": { - "value": "#1b944726", - "description": "Step: 600", + "value": "#2a929226", "type": "color" }, "hovered": { - "value": "#1b944733", - "description": "Step: 600", + "value": "#2a929233", "type": "color" }, "active": { - "value": "#1b944740", - "description": "Step: 600", - "type": "color" - }, - "focused": { - "value": "#1b944733", - "description": "Step: 600", + "value": "#2a929240", "type": "color" } }, "error": { "base": { - "value": "#c9181826", - "description": "Step: 600", + "value": "#be467826", "type": "color" }, "hovered": { - "value": "#c9181833", - "description": "Step: 600", + "value": "#be467833", "type": "color" }, "active": { - "value": "#c9181840", - "description": "Step: 600", - "type": "color" - }, - "focused": { - "value": "#c9181833", - "description": "Step: 600", + "value": "#be467840", "type": "color" } }, "warning": { "base": { - "value": "#f6a72426", - "description": "Step: 400", + "value": "#a06e3b26", "type": "color" }, "hovered": { - "value": "#f6a72433", - "description": "Step: 400", + "value": "#a06e3b33", "type": "color" }, "active": { - "value": "#f6a72440", - "description": "Step: 400", - "type": "color" - }, - "focused": { - "value": "#f6a72433", - "description": "Step: 400", + "value": "#a06e3b40", "type": "color" } }, "info": { "base": { - "value": "#2472f226", - "description": "Step: 500", + "value": "#576ddb26", "type": "color" }, "hovered": { - "value": "#2472f233", - "description": "Step: 500", + "value": "#576ddb33", "type": "color" }, "active": { - "value": "#2472f240", - "description": "Step: 500", - "type": "color" - }, - "focused": { - "value": "#2472f233", - "description": "Step: 500", + "value": "#576ddb40", "type": "color" } } }, "border": { "primary": { - "value": "#d5d5d5", - "description": "Step: 150", + "value": "#efecf4", "type": "color" }, "secondary": { - "value": "#d5d5d5", - "description": "Step: 150", + "value": "#e2dfe7", "type": "color" }, "muted": { - "value": "#e3e3e3", - "description": "Step: 100", - "type": "color" - }, - "focused": { - "value": "#484bed", - "description": "Step: 500", + "value": "#7e7887", "type": "color" }, "active": { - "value": "#b8b8b8", - "description": "Step: 250", + "value": "#7e7887", "type": "color" }, "onMedia": { - "value": "#b8b8b84d", - "description": "Step: 250", + "value": "#efecf41a", "type": "color" }, "ok": { - "value": "#1b944726", - "description": "Step: 600", + "value": "#2a929226", "type": "color" }, "error": { - "value": "#eb2d2d26", - "description": "Step: 500", + "value": "#be467826", "type": "color" }, "warning": { - "value": "#f6a72426", - "description": "Step: 400", + "value": "#a06e3b26", "type": "color" }, "info": { - "value": "#2472f226", - "description": "Step: 500", + "value": "#576ddb26", "type": "color" } }, "editor": { "background": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#efecf4", "type": "color" }, "indent_guide": { - "value": "#e3e3e3", - "description": "Step: 100", + "value": "#7e7887", "type": "color" }, "indent_guide_active": { - "value": "#d5d5d5", - "description": "Step: 150", + "value": "#e2dfe7", "type": "color" }, "line": { "active": { - "value": "#0000000f", - "description": "Step: 900", + "value": "#19171c12", "type": "color" }, "highlighted": { - "value": "#0000001f", - "description": "Step: 900", + "value": "#19171c1f", "type": "color" }, "inserted": { - "value": "#1b944740", - "description": "Step: 600", + "value": "#2a929240", "type": "color" }, "deleted": { - "value": "#c9181840", - "description": "Step: 600", + "value": "#be467840", "type": "color" }, "modified": { - "value": "#2472f240", - "description": "Step: 500", + "value": "#576ddb40", "type": "color" } }, "highlight": { "selection": { - "value": "#2472f23d", - "description": "Step: 500", + "value": "#576ddb3d", "type": "color" }, "occurrence": { - "value": "#0000000f", - "description": "Step: 900", + "value": "#19171c0f", "type": "color" }, "activeOccurrence": { - "value": "#00000029", - "description": "Step: 900", + "value": "#19171c1f", "type": "color" }, "matchingBracket": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#e2dfe72e", "type": "color" }, "match": { - "value": "#fce9b7", - "description": "Step: 100", + "value": "#955ae73d", "type": "color" }, "activeMatch": { - "value": "#f9da82", - "description": "Step: 200", + "value": "#955ae75c", "type": "color" }, "related": { - "value": "#ffffff", - "description": "Step: 0", + "value": "#e2dfe71f", "type": "color" } }, "gutter": { "primary": { - "value": "#aaaaaa", - "description": "Step: 300", + "value": "#655f6d", "type": "color" }, "active": { - "value": "#000000", - "description": "Step: 900", + "value": "#19171c", "type": "color" } } }, "syntax": { "primary": { - "value": "#1c1c1c", - "description": "Step: 800", + "value": "#19171c", "type": "color" }, "comment": { - "value": "#717171", - "description": "Step: 500", + "value": "#585260", "type": "color" }, "keyword": { - "value": "#1819a1", - "description": "Step: 700", + "value": "#576ddb", "type": "color" }, "function": { - "value": "#bb550e", - "description": "Step: 600", + "value": "#a06e3b", "type": "color" }, "type": { - "value": "#a8820e", - "description": "Step: 600", + "value": "#398bc6", "type": "color" }, "variant": { - "value": "#97142a", - "description": "Step: 700", + "value": "#576ddb", "type": "color" }, "property": { - "value": "#106c4e", - "description": "Step: 700", + "value": "#576ddb", "type": "color" }, "enum": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "operator": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "string": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#aa573c", "type": "color" }, "number": { - "value": "#484bed", - "description": "Step: 500", + "value": "#2a9292", "type": "color" }, "boolean": { - "value": "#eb2d2d", - "description": "Step: 500", + "value": "#2a9292", "type": "color" } }, "player": { "1": { "baseColor": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "cursorColor": { - "value": "#2472f2", - "description": "Step: 500", + "value": "#576ddb", "type": "color" }, "selectionColor": { - "value": "#2472f23d", - "description": "Step: 500", + "value": "#576ddb3d", "type": "color" }, "borderColor": { - "value": "#2472f2cc", - "description": "Step: 500", + "value": "#576ddbcc", "type": "color" } }, "2": { "baseColor": { - "value": "#12d796", - "description": "Step: 400", + "value": "#2a9292", "type": "color" }, "cursorColor": { - "value": "#12d796", - "description": "Step: 400", + "value": "#2a9292", "type": "color" }, "selectionColor": { - "value": "#12d7963d", - "description": "Step: 400", + "value": "#2a92923d", "type": "color" }, "borderColor": { - "value": "#12d796cc", - "description": "Step: 400", + "value": "#2a9292cc", "type": "color" } }, "3": { "baseColor": { - "value": "#de57e8", - "description": "Step: 400", + "value": "#bf40bf", "type": "color" }, "cursorColor": { - "value": "#de57e8", - "description": "Step: 400", + "value": "#bf40bf", "type": "color" }, "selectionColor": { - "value": "#de57e83d", - "description": "Step: 400", + "value": "#bf40bf3d", "type": "color" }, "borderColor": { - "value": "#de57e8cc", - "description": "Step: 400", + "value": "#bf40bfcc", "type": "color" } }, "4": { "baseColor": { - "value": "#f9812e", - "description": "Step: 400", + "value": "#aa573c", "type": "color" }, "cursorColor": { - "value": "#f9812e", - "description": "Step: 400", + "value": "#aa573c", "type": "color" }, "selectionColor": { - "value": "#f9812e3d", - "description": "Step: 400", + "value": "#aa573c3d", "type": "color" }, "borderColor": { - "value": "#f9812ecc", - "description": "Step: 400", + "value": "#aa573ccc", "type": "color" } }, "5": { "baseColor": { - "value": "#b066f8", - "description": "Step: 400", + "value": "#955ae7", "type": "color" }, "cursorColor": { - "value": "#b066f8", - "description": "Step: 400", + "value": "#955ae7", "type": "color" }, "selectionColor": { - "value": "#b066f83d", - "description": "Step: 400", + "value": "#955ae73d", "type": "color" }, "borderColor": { - "value": "#b066f8cc", - "description": "Step: 400", + "value": "#955ae7cc", "type": "color" } }, "6": { "baseColor": { - "value": "#16d6c1", - "description": "Step: 400", + "value": "#398bc6", "type": "color" }, "cursorColor": { - "value": "#16d6c1", - "description": "Step: 400", + "value": "#398bc6", "type": "color" }, "selectionColor": { - "value": "#16d6c13d", - "description": "Step: 400", + "value": "#398bc63d", "type": "color" }, "borderColor": { - "value": "#16d6c1cc", - "description": "Step: 400", + "value": "#398bc6cc", "type": "color" } }, "7": { "baseColor": { - "value": "#ef59a3", - "description": "Step: 400", + "value": "#be4678", "type": "color" }, "cursorColor": { - "value": "#ef59a3", - "description": "Step: 400", + "value": "#be4678", "type": "color" }, "selectionColor": { - "value": "#ef59a33d", - "description": "Step: 400", + "value": "#be46783d", "type": "color" }, "borderColor": { - "value": "#ef59a3cc", - "description": "Step: 400", + "value": "#be4678cc", "type": "color" } }, "8": { "baseColor": { - "value": "#f7bf17", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "cursorColor": { - "value": "#f7bf17", - "description": "Step: 400", + "value": "#a06e3b", "type": "color" }, "selectionColor": { - "value": "#f7bf173d", - "description": "Step: 400", + "value": "#a06e3b3d", "type": "color" }, "borderColor": { - "value": "#f7bf17cc", - "description": "Step: 400", + "value": "#a06e3bcc", "type": "color" } } @@ -2677,10 +2343,6 @@ "active": { "value": "#586e755c", "type": "color" - }, - "focused": { - "value": "#586e753d", - "type": "color" } }, "300": { @@ -2695,10 +2357,6 @@ "active": { "value": "#586e755c", "type": "color" - }, - "focused": { - "value": "#586e753d", - "type": "color" } }, "500": { @@ -2713,10 +2371,6 @@ "active": { "value": "#0736425c", "type": "color" - }, - "focused": { - "value": "#0736423d", - "type": "color" } }, "on300": { @@ -2731,10 +2385,6 @@ "active": { "value": "#0736427a", "type": "color" - }, - "focused": { - "value": "#0736423d", - "type": "color" } }, "on500": { @@ -2749,10 +2399,6 @@ "active": { "value": "#586e757a", "type": "color" - }, - "focused": { - "value": "#586e753d", - "type": "color" } }, "ok": { @@ -2767,10 +2413,6 @@ "active": { "value": "#85990040", "type": "color" - }, - "focused": { - "value": "#85990033", - "type": "color" } }, "error": { @@ -2785,10 +2427,6 @@ "active": { "value": "#dc322f40", "type": "color" - }, - "focused": { - "value": "#dc322f33", - "type": "color" } }, "warning": { @@ -2803,10 +2441,6 @@ "active": { "value": "#b5890040", "type": "color" - }, - "focused": { - "value": "#b5890033", - "type": "color" } }, "info": { @@ -2821,10 +2455,6 @@ "active": { "value": "#268bd240", "type": "color" - }, - "focused": { - "value": "#268bd233", - "type": "color" } } }, @@ -2841,10 +2471,6 @@ "value": "#657b83", "type": "color" }, - "focused": { - "value": "#657b83", - "type": "color" - }, "active": { "value": "#657b83", "type": "color" @@ -3248,10 +2874,6 @@ "active": { "value": "#93a1a12e", "type": "color" - }, - "focused": { - "value": "#93a1a11f", - "type": "color" } }, "300": { @@ -3266,10 +2888,6 @@ "active": { "value": "#93a1a12e", "type": "color" - }, - "focused": { - "value": "#93a1a11f", - "type": "color" } }, "500": { @@ -3284,10 +2902,6 @@ "active": { "value": "#eee8d52e", "type": "color" - }, - "focused": { - "value": "#eee8d51f", - "type": "color" } }, "on300": { @@ -3302,10 +2916,6 @@ "active": { "value": "#eee8d53d", "type": "color" - }, - "focused": { - "value": "#eee8d51f", - "type": "color" } }, "on500": { @@ -3320,10 +2930,6 @@ "active": { "value": "#93a1a13d", "type": "color" - }, - "focused": { - "value": "#93a1a11f", - "type": "color" } }, "ok": { @@ -3338,10 +2944,6 @@ "active": { "value": "#85990040", "type": "color" - }, - "focused": { - "value": "#85990033", - "type": "color" } }, "error": { @@ -3356,10 +2958,6 @@ "active": { "value": "#dc322f40", "type": "color" - }, - "focused": { - "value": "#dc322f33", - "type": "color" } }, "warning": { @@ -3374,10 +2972,6 @@ "active": { "value": "#b5890040", "type": "color" - }, - "focused": { - "value": "#b5890033", - "type": "color" } }, "info": { @@ -3392,10 +2986,6 @@ "active": { "value": "#268bd240", "type": "color" - }, - "focused": { - "value": "#268bd233", - "type": "color" } } }, @@ -3412,10 +3002,6 @@ "value": "#839496", "type": "color" }, - "focused": { - "value": "#839496", - "type": "color" - }, "active": { "value": "#839496", "type": "color" diff --git a/styles/src/buildThemes.ts b/styles/src/buildThemes.ts index 2f2d35dcf1..69bd96f2c5 100644 --- a/styles/src/buildThemes.ts +++ b/styles/src/buildThemes.ts @@ -2,19 +2,24 @@ import * as fs from "fs"; import * as path from "path"; import app from "./styleTree/app"; import { dark as caveDark, light as caveLight } from "./themes/cave"; -import dark from "./themes/dark"; -import light from "./themes/light"; import { dark as solarizedDark, light as solarizedLight } from "./themes/solarized"; import { dark as sulphurpoolDark, light as sulphurpoolLight } from "./themes/sulphurpool"; import snakeCase from "./utils/snakeCase"; const themes = [ - dark, light, caveDark, caveLight, solarizedDark, solarizedLight, sulphurpoolDark, sulphurpoolLight ]; +const themeDirectory = `${__dirname}/../../assets/themes/`; + +// Clear existing themes +for (const file of fs.readdirSync(themeDirectory)) { + fs.unlinkSync(path.join(themeDirectory, file)); +} + +// Write new themes to theme directory for (let theme of themes) { let styleTree = snakeCase(app(theme)); let styleTreeJSON = JSON.stringify(styleTree, null, 2); diff --git a/styles/src/buildTokens.ts b/styles/src/buildTokens.ts index 8c224717af..27ea50d814 100644 --- a/styles/src/buildTokens.ts +++ b/styles/src/buildTokens.ts @@ -1,8 +1,8 @@ import * as fs from "fs"; import * as path from "path"; -import dark from "./themes/dark"; -import light from "./themes/light"; import { light as solarizedLight, dark as solarizedDark } from "./themes/solarized"; +// Use cave as "light" and "dark" themes +import { light, dark } from "./themes/cave"; import Theme from "./themes/theme"; import { colors, fontFamilies, fontSizes, fontWeights, sizes } from "./tokens"; diff --git a/styles/src/themes/base16.ts b/styles/src/themes/base16.ts index f2a1909d89..8122350727 100644 --- a/styles/src/themes/base16.ts +++ b/styles/src/themes/base16.ts @@ -1,106 +1,123 @@ -import { ColorToken, fontWeights, NumberToken } from "../tokens"; +import chroma from "chroma-js"; +import { Scale, Color } from "chroma-js"; +import { color, ColorToken, fontWeights, NumberToken } from "../tokens"; import { withOpacity } from "../utils/color"; import Theme, { buildPlayer, Syntax } from "./theme"; -export interface Accents { - "red": ColorToken, - "orange": ColorToken, - "yellow": ColorToken, - "green": ColorToken, - "cyan": ColorToken, - "blue": ColorToken, - "violet": ColorToken, - "magenta": ColorToken, +export function colorRamp(color: Color): Scale { + let hue = color.hsl()[0]; + let endColor = chroma.hsl(hue, 0.88, 0.96); + let startColor = chroma.hsl(hue, 0.68, 0.12); + return chroma + .scale([startColor, color, endColor]) + .mode("hsl"); } -export function createTheme(name: string, isLight: boolean, neutral: ColorToken[], accent: Accents): Theme { +// Neutral. 8 stops from 0 to 1. + +export function createTheme(name: string, isLight: boolean, ramps: { [rampName: string]: Scale }, blend?: number): Theme { if (isLight) { - neutral = [...neutral].reverse(); + for (var rampName in ramps) { + ramps[rampName] = ramps[rampName].domain([1, 0]); + } + ramps.neutral = ramps.neutral.domain([7, 0]); + } else { + ramps.neutral = ramps.neutral.domain([0, 7]); + } + + if (blend === undefined) { + blend = isLight ? 0.12 : 0.24; + } + + function rampColor(ramp: Scale, index: number): ColorToken { + return color(ramp(index).hex()); } - let blend = isLight ? 0.12 : 0.24; const backgroundColor = { + // Title bar 100: { - base: neutral[1], - hovered: withOpacity(neutral[2], blend), - active: withOpacity(neutral[2], blend * 1.5), + base: rampColor(ramps.neutral, 1.25), + hovered: rampColor(ramps.neutral, 1.5), + active: rampColor(ramps.neutral, 1.75), }, + // Midground (panels, etc) 300: { - base: neutral[1], - hovered: withOpacity(neutral[2], blend), - active: withOpacity(neutral[2], blend * 1.5), + base: rampColor(ramps.neutral, 1), + hovered: rampColor(ramps.neutral, 1.25), + active: rampColor(ramps.neutral, 1.5), }, + // Editor 500: { - base: neutral[0], - hovered: withOpacity(neutral[1], blend), - active: withOpacity(neutral[1], blend * 1.5), + base: rampColor(ramps.neutral, 0), + hovered: rampColor(ramps.neutral, 0.25), + active: rampColor(ramps.neutral, 0.5), }, on300: { - base: neutral[0], - hovered: withOpacity(neutral[1], blend), - active: withOpacity(neutral[1], blend * 2), + base: rampColor(ramps.neutral, 0), + hovered: rampColor(ramps.neutral, 0.25), + active: rampColor(ramps.neutral, 0.5), }, on500: { - base: neutral[1], - hovered: withOpacity(neutral[2], blend), - active: withOpacity(neutral[2], blend * 2), + base: rampColor(ramps.neutral, 1.25), + hovered: rampColor(ramps.neutral, 1.5), + active: rampColor(ramps.neutral, 1.75), }, ok: { - base: withOpacity(accent.green, 0.15), - hovered: withOpacity(accent.green, 0.20), - active: withOpacity(accent.green, 0.25), + base: withOpacity(rampColor(ramps.green, 0.5), 0.15), + hovered: withOpacity(rampColor(ramps.green, 0.5), 0.20), + active: withOpacity(rampColor(ramps.green, 0.5), 0.25), }, error: { - base: withOpacity(accent.red, 0.15), - hovered: withOpacity(accent.red, 0.20), - active: withOpacity(accent.red, 0.25), + base: withOpacity(rampColor(ramps.red, 0.5), 0.15), + hovered: withOpacity(rampColor(ramps.red, 0.5), 0.20), + active: withOpacity(rampColor(ramps.red, 0.5), 0.25), }, warning: { - base: withOpacity(accent.yellow, 0.15), - hovered: withOpacity(accent.yellow, 0.20), - active: withOpacity(accent.yellow, 0.25), + base: withOpacity(rampColor(ramps.yellow, 0.5), 0.15), + hovered: withOpacity(rampColor(ramps.yellow, 0.5), 0.20), + active: withOpacity(rampColor(ramps.yellow, 0.5), 0.25), }, info: { - base: withOpacity(accent.blue, 0.15), - hovered: withOpacity(accent.blue, 0.20), - active: withOpacity(accent.blue, 0.25), + base: withOpacity(rampColor(ramps.blue, 0.5), 0.15), + hovered: withOpacity(rampColor(ramps.blue, 0.5), 0.20), + active: withOpacity(rampColor(ramps.blue, 0.5), 0.25), }, }; const borderColor = { - primary: neutral[0], - secondary: neutral[1], - muted: neutral[3], - active: neutral[3], - onMedia: withOpacity(neutral[0], 0.1), - ok: withOpacity(accent.green, 0.15), - error: withOpacity(accent.red, 0.15), - warning: withOpacity(accent.yellow, 0.15), - info: withOpacity(accent.blue, 0.15), + primary: rampColor(ramps.neutral, isLight ? 2 : 0), + secondary: rampColor(ramps.neutral, isLight ? 2 : 1), + muted: rampColor(ramps.neutral, isLight ? 4 : 3), + active: rampColor(ramps.neutral, isLight ? 4 : 3), + onMedia: withOpacity(rampColor(ramps.neutral, 0), 0.1), + ok: withOpacity(rampColor(ramps.green, 0.5), 0.15), + error: withOpacity(rampColor(ramps.red, 0.5), 0.15), + warning: withOpacity(rampColor(ramps.yellow, 0.5), 0.15), + info: withOpacity(rampColor(ramps.blue, 0.5), 0.15), }; const textColor = { - primary: neutral[6], - secondary: neutral[5], - muted: neutral[5], - placeholder: neutral[4], - active: neutral[7], - feature: accent.blue, - ok: accent.green, - error: accent.red, - warning: accent.yellow, - info: accent.blue, + primary: rampColor(ramps.neutral, 6), + secondary: rampColor(ramps.neutral, 5), + muted: rampColor(ramps.neutral, 5), + placeholder: rampColor(ramps.neutral, 4), + active: rampColor(ramps.neutral, 7), + feature: rampColor(ramps.blue, 0.5), + ok: rampColor(ramps.green, 0.5), + error: rampColor(ramps.red, 0.5), + warning: rampColor(ramps.yellow, 0.5), + info: rampColor(ramps.blue, 0.5), }; const player = { - 1: buildPlayer(accent.blue), - 2: buildPlayer(accent.green), - 3: buildPlayer(accent.magenta), - 4: buildPlayer(accent.orange), - 5: buildPlayer(accent.violet), - 6: buildPlayer(accent.cyan), - 7: buildPlayer(accent.red), - 8: buildPlayer(accent.yellow), + 1: buildPlayer(rampColor(ramps.blue, 0.5)), + 2: buildPlayer(rampColor(ramps.green, 0.5)), + 3: buildPlayer(rampColor(ramps.magenta, 0.5)), + 4: buildPlayer(rampColor(ramps.orange, 0.5)), + 5: buildPlayer(rampColor(ramps.violet, 0.5)), + 6: buildPlayer(rampColor(ramps.cyan, 0.5)), + 7: buildPlayer(rampColor(ramps.red, 0.5)), + 8: buildPlayer(rampColor(ramps.yellow, 0.5)), }; const editor = { @@ -108,19 +125,16 @@ export function createTheme(name: string, isLight: boolean, neutral: ColorToken[ indent_guide: borderColor.muted, indent_guide_active: borderColor.secondary, line: { - active: withOpacity(neutral[7], 0.07), - highlighted: withOpacity(neutral[7], 0.12), - inserted: backgroundColor.ok.active, - deleted: backgroundColor.error.active, - modified: backgroundColor.info.active, + active: rampColor(ramps.neutral, 1), + highlighted: rampColor(ramps.neutral, 1.25), // TODO: Where is this used? }, highlight: { selection: player[1].selectionColor, - occurrence: withOpacity(neutral[7], blend / 2), - activeOccurrence: withOpacity(neutral[7], blend), - matchingBracket: backgroundColor[500].active, - match: withOpacity(accent.violet, blend * 2), - activeMatch: withOpacity(accent.violet, blend * 3), + occurrence: withOpacity(rampColor(ramps.neutral, 2), blend), + activeOccurrence: withOpacity(rampColor(ramps.neutral, 2), blend * 2), // TODO: Not hooked up - https://github.com/zed-industries/zed/issues/751 + matchingBracket: backgroundColor[500].active, // TODO: Not hooked up + match: rampColor(ramps.violet, 0.15), + activeMatch: withOpacity(rampColor(ramps.violet, 0.4), blend * 2), // TODO: Not hooked up - https://github.com/zed-industries/zed/issues/751 related: backgroundColor[500].hovered, }, gutter: { @@ -131,59 +145,59 @@ export function createTheme(name: string, isLight: boolean, neutral: ColorToken[ const syntax: Syntax = { primary: { - color: neutral[7], + color: rampColor(ramps.neutral, 7), weight: fontWeights.normal, }, comment: { - color: neutral[5], + color: rampColor(ramps.neutral, 5), weight: fontWeights.normal, }, punctuation: { - color: neutral[5], + color: rampColor(ramps.neutral, 6), weight: fontWeights.normal, }, constant: { - color: neutral[4], + color: rampColor(ramps.neutral, 4), weight: fontWeights.normal, }, keyword: { - color: accent.blue, + color: rampColor(ramps.blue, 0.5), weight: fontWeights.normal, }, function: { - color: accent.yellow, + color: rampColor(ramps.yellow, 0.5), weight: fontWeights.normal, }, type: { - color: accent.cyan, + color: rampColor(ramps.cyan, 0.5), weight: fontWeights.normal, }, variant: { - color: accent.blue, + color: rampColor(ramps.blue, 0.5), weight: fontWeights.normal, }, property: { - color: accent.blue, + color: rampColor(ramps.blue, 0.5), weight: fontWeights.normal, }, enum: { - color: accent.orange, + color: rampColor(ramps.orange, 0.5), weight: fontWeights.normal, }, operator: { - color: accent.orange, + color: rampColor(ramps.orange, 0.5), weight: fontWeights.normal, }, string: { - color: accent.orange, + color: rampColor(ramps.orange, 0.5), weight: fontWeights.normal, }, number: { - color: accent.green, + color: rampColor(ramps.green, 0.5), weight: fontWeights.normal, }, boolean: { - color: accent.green, + color: rampColor(ramps.green, 0.5), weight: fontWeights.normal, }, predictive: { @@ -191,7 +205,7 @@ export function createTheme(name: string, isLight: boolean, neutral: ColorToken[ weight: fontWeights.normal, }, title: { - color: accent.yellow, + color: rampColor(ramps.yellow, 0.5), weight: fontWeights.bold, }, emphasis: { @@ -203,12 +217,12 @@ export function createTheme(name: string, isLight: boolean, neutral: ColorToken[ weight: fontWeights.bold, }, linkUri: { - color: accent.green, + color: rampColor(ramps.green, 0.5), weight: fontWeights.normal, underline: true, }, linkText: { - color: accent.orange, + color: rampColor(ramps.orange, 0.5), weight: fontWeights.normal, italic: true, }, diff --git a/styles/src/themes/cave.ts b/styles/src/themes/cave.ts index 681285dd12..aa443dc837 100644 --- a/styles/src/themes/cave.ts +++ b/styles/src/themes/cave.ts @@ -1,29 +1,19 @@ -import { createTheme } from "./base16"; -import { color } from "../tokens"; +import chroma from "chroma-js"; +import { colorRamp, createTheme } from "./base16"; const name = "cave"; -const neutrals = [ - color("#19171c"), - color("#26232a"), - color("#585260"), - color("#655f6d"), - color("#7e7887"), - color("#8b8792"), - color("#e2dfe7"), - color("#efecf4"), -]; +const ramps = { + neutral: chroma.scale(["#19171c", "#26232a", "#585260", "#655f6d", "#7e7887", "#8b8792", "#e2dfe7", "#efecf4"]), + red: colorRamp(chroma("#be4678")), + orange: colorRamp(chroma("#aa573c")), + yellow: colorRamp(chroma("#a06e3b")), + green: colorRamp(chroma("#2a9292")), + cyan: colorRamp(chroma("#398bc6")), + blue: colorRamp(chroma("#576ddb")), + violet: colorRamp(chroma("#955ae7")), + magenta: colorRamp(chroma("#bf40bf")), +} -const colors = { - "red": color("#be4678"), - "orange": color("#aa573c"), - "yellow": color("#a06e3b"), - "green": color("#2a9292"), - "cyan": color("#398bc6"), - "blue": color("#576ddb"), - "violet": color("#955ae7"), - "magenta": color("#bf40bf"), -}; - -export const dark = createTheme(`${name}-dark`, false, neutrals, colors); -export const light = createTheme(`${name}-light`, true, neutrals, colors); \ No newline at end of file +export const dark = createTheme(`${name}-dark`, false, ramps); +export const light = createTheme(`${name}-light`, true, ramps); \ No newline at end of file diff --git a/styles/src/themes/dark.ts b/styles/src/themes/dark.ts deleted file mode 100644 index 8614414fa7..0000000000 --- a/styles/src/themes/dark.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { colors, fontWeights, NumberToken } from "../tokens"; -import { withOpacity } from "../utils/color"; -import Theme, { buildPlayer, Syntax } from "./theme"; - -const backgroundColor = { - 100: { - base: colors.neutral[750], - hovered: colors.neutral[725], - active: colors.neutral[800], - }, - 300: { - base: colors.neutral[800], - hovered: colors.neutral[775], - active: colors.neutral[750], - }, - 500: { - base: colors.neutral[900], - hovered: withOpacity(colors.neutral[0], 0.08), - active: withOpacity(colors.neutral[0], 0.12), - }, - on300: { - base: withOpacity(colors.neutral[850], 0.5), - hovered: colors.neutral[875], - active: colors.neutral[900], - }, - on500: { - base: colors.neutral[850], - hovered: colors.neutral[800], - active: colors.neutral[775], - }, - ok: { - base: withOpacity(colors.green[600], 0.15), - hovered: withOpacity(colors.green[600], 0.20), - active: withOpacity(colors.green[600], 0.25), - }, - error: { - base: withOpacity(colors.red[600], 0.15), - hovered: withOpacity(colors.red[600], 0.20), - active: withOpacity(colors.red[600], 0.25), - }, - warning: { - base: withOpacity(colors.amber[400], 0.15), - hovered: withOpacity(colors.amber[400], 0.20), - active: withOpacity(colors.amber[400], 0.25), - }, - info: { - base: withOpacity(colors.blue[500], 0.15), - hovered: withOpacity(colors.blue[500], 0.20), - active: withOpacity(colors.blue[500], 0.25), - }, -}; - -const borderColor = { - primary: colors.neutral[875], - secondary: colors.neutral[775], - muted: colors.neutral[675], - active: colors.neutral[900], - onMedia: withOpacity(colors.neutral[875], 0.1), - ok: withOpacity(colors.green[600], 0.15), - error: withOpacity(colors.red[500], 0.15), - warning: withOpacity(colors.amber[400], 0.15), - info: withOpacity(colors.blue[500], 0.15), -}; - -const textColor = { - primary: colors.neutral[50], - secondary: colors.neutral[350], - muted: colors.neutral[450], - placeholder: colors.neutral[650], - active: colors.neutral[0], - feature: colors.blue[400], - ok: colors.green[600], - error: colors.red[400], - warning: colors.amber[300], - info: colors.blue[500], -}; - -const iconColor = { - primary: colors.neutral[200], - secondary: colors.neutral[350], - muted: colors.neutral[600], - placeholder: colors.neutral[700], - active: colors.neutral[0], - feature: colors.blue[500], - ok: colors.green[600], - error: colors.red[500], - warning: colors.amber[400], - info: colors.blue[600], -}; - -const player = { - 1: buildPlayer(colors.blue[500]), - 2: buildPlayer(colors.lime[500]), - 3: buildPlayer(colors.fuschia[500]), - 4: buildPlayer(colors.orange[500]), - 5: buildPlayer(colors.purple[500]), - 6: buildPlayer(colors.teal[400]), - 7: buildPlayer(colors.pink[400]), - 8: buildPlayer(colors.yellow[400]), -}; - -const editor = { - background: backgroundColor[500].base, - indent_guide: borderColor.muted, - indent_guide_active: borderColor.secondary, - line: { - active: withOpacity(colors.neutral[0], 0.07), - highlighted: withOpacity(colors.neutral[0], 0.12), - inserted: backgroundColor.ok.active, - deleted: backgroundColor.error.active, - modified: backgroundColor.info.active, - }, - highlight: { - selection: player[1].selectionColor, - occurrence: withOpacity(colors.neutral[0], 0.12), - activeOccurrence: withOpacity(colors.neutral[0], 0.16), - matchingBracket: backgroundColor[500].active, - match: withOpacity(colors.violet[700], 0.5), - activeMatch: withOpacity(colors.violet[600], 0.7), - related: backgroundColor[500].hovered, - }, - gutter: { - primary: textColor.placeholder, - active: textColor.active, - }, -}; - -const syntax: Syntax = { - primary: { - color: colors.neutral[150], - weight: fontWeights.normal, - }, - comment: { - color: colors.neutral[300], - weight: fontWeights.normal, - }, - punctuation: { - color: colors.neutral[200], - weight: fontWeights.normal, - }, - constant: { - color: colors.neutral[150], - weight: fontWeights.normal, - }, - keyword: { - color: colors.blue[400], - weight: fontWeights.normal, - }, - function: { - color: colors.yellow[200], - weight: fontWeights.normal, - }, - type: { - color: colors.teal[300], - weight: fontWeights.normal, - }, - variant: { - color: colors.sky[300], - weight: fontWeights.normal, - }, - property: { - color: colors.blue[400], - weight: fontWeights.normal, - }, - enum: { - color: colors.orange[500], - weight: fontWeights.normal, - }, - operator: { - color: colors.orange[500], - weight: fontWeights.normal, - }, - string: { - color: colors.orange[300], - weight: fontWeights.normal, - }, - number: { - color: colors.lime[300], - weight: fontWeights.normal, - }, - boolean: { - color: colors.lime[300], - weight: fontWeights.normal, - }, - predictive: { - color: textColor.muted, - weight: fontWeights.normal, - }, - title: { - color: colors.amber[500], - weight: fontWeights.bold, - }, - emphasis: { - color: textColor.feature, - weight: fontWeights.normal, - }, - "emphasis.strong": { - color: textColor.feature, - weight: fontWeights.bold, - }, - linkUri: { - color: colors.lime[500], - weight: fontWeights.normal, - underline: true, - }, - linkText: { - color: colors.orange[500], - weight: fontWeights.normal, - italic: true, - }, -}; - -const shadowAlpha: NumberToken = { - value: 0.32, - type: "number", -}; - -const theme: Theme = { - name: "dark", - backgroundColor, - borderColor, - textColor, - iconColor, - editor, - syntax, - player, - shadowAlpha, -}; - -export default theme; diff --git a/styles/src/themes/gruvbox.ts b/styles/src/themes/gruvbox.ts new file mode 100644 index 0000000000..f0100fa327 --- /dev/null +++ b/styles/src/themes/gruvbox.ts @@ -0,0 +1,30 @@ +import chroma from "chroma-js"; +import { createTheme } from "./base16"; + +const name = "cave"; + +const colors = { + "red": chroma("#be4678"), + "orange": chroma("#aa573c"), + "yellow": chroma("#a06e3b"), + "green": chroma("#2a9292"), + "cyan": chroma("#398bc6"), + "blue": chroma("#576ddb"), + "violet": chroma("#955ae7"), + "magenta": chroma("#bf40bf"), +}; + +const ramps = { + neutral: chroma.scale(["#19171c", "#26232a", "#585260", "#655f6d", "#7e7887", "#8b8792", "#e2dfe7", "#efecf4"]), + red: chroma.scale([colors.red.darken(3), colors.red, colors.red.brighten(3)]), + orange: chroma.scale([colors.orange.darken(3), colors.orange, colors.orange.brighten(3)]), + yellow: chroma.scale([colors.yellow.darken(3), colors.yellow, colors.yellow.brighten(3)]), + green: chroma.scale([colors.green.darken(3), colors.green, colors.green.brighten(3)]), + cyan: chroma.scale([colors.cyan.darken(3), colors.cyan, colors.cyan.brighten(3)]), + blue: chroma.scale([colors.blue.darken(3), colors.blue, colors.blue.brighten(3)]), + violet: chroma.scale([colors.violet.darken(3), colors.violet, colors.violet.brighten(3)]), + magenta: chroma.scale([colors.magenta.darken(3), colors.magenta, colors.magenta.brighten(3)]), +} + +export const dark = createTheme(`${name}-dark`, false, ramps); +export const light = createTheme(`${name}-light`, true, ramps); \ No newline at end of file diff --git a/styles/src/themes/light.ts b/styles/src/themes/light.ts deleted file mode 100644 index c2eecf5391..0000000000 --- a/styles/src/themes/light.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { colors, fontWeights, NumberToken } from "../tokens"; -import { withOpacity } from "../utils/color"; -import Theme, { buildPlayer, Syntax } from "./theme"; - -const backgroundColor = { - 100: { - base: colors.neutral[75], - hovered: colors.neutral[100], - active: colors.neutral[150], - }, - 300: { - base: colors.neutral[25], - hovered: colors.neutral[75], - active: colors.neutral[100], - }, - 500: { - base: colors.neutral[0], - hovered: withOpacity(colors.neutral[900], 0.03), - active: withOpacity(colors.neutral[900], 0.06), - }, - on300: { - base: colors.neutral[50], - hovered: colors.neutral[100], - active: colors.neutral[150], - }, - on500: { - base: colors.neutral[50], - hovered: colors.neutral[25], - active: colors.neutral[0], - }, - ok: { - base: withOpacity(colors.green[600], 0.15), - hovered: withOpacity(colors.green[600], 0.20), - active: withOpacity(colors.green[600], 0.25), - }, - error: { - base: withOpacity(colors.red[600], 0.15), - hovered: withOpacity(colors.red[600], 0.20), - active: withOpacity(colors.red[600], 0.25), - }, - warning: { - base: withOpacity(colors.amber[400], 0.15), - hovered: withOpacity(colors.amber[400], 0.20), - active: withOpacity(colors.amber[400], 0.25), - }, - info: { - base: withOpacity(colors.blue[500], 0.15), - hovered: withOpacity(colors.blue[500], 0.20), - active: withOpacity(colors.blue[500], 0.25), - }, -}; - -const borderColor = { - primary: colors.neutral[150], - secondary: colors.neutral[150], - muted: colors.neutral[100], - active: colors.neutral[250], - onMedia: withOpacity(colors.neutral[250], 0.3), - ok: withOpacity(colors.green[600], 0.15), - error: withOpacity(colors.red[500], 0.15), - warning: withOpacity(colors.amber[400], 0.15), - info: withOpacity(colors.blue[500], 0.15), -}; - -const textColor = { - primary: colors.neutral[750], - secondary: colors.neutral[650], - muted: colors.neutral[550], - placeholder: colors.neutral[450], - active: colors.neutral[900], - feature: colors.indigo[500], - ok: colors.green[500], - error: colors.red[500], - warning: colors.yellow[500], - info: colors.blue[500], -}; - -const iconColor = { - primary: colors.neutral[700], - secondary: colors.neutral[500], - muted: colors.neutral[350], - placeholder: colors.neutral[300], - active: colors.neutral[900], - feature: colors.indigo[500], - ok: colors.green[600], - error: colors.red[600], - warning: colors.yellow[400], - info: colors.blue[600], -}; - -const player = { - 1: buildPlayer(colors.blue[500]), - 2: buildPlayer(colors.emerald[400]), - 3: buildPlayer(colors.fuschia[400]), - 4: buildPlayer(colors.orange[400]), - 5: buildPlayer(colors.purple[400]), - 6: buildPlayer(colors.teal[400]), - 7: buildPlayer(colors.pink[400]), - 8: buildPlayer(colors.yellow[400]), -}; - -const editor = { - background: backgroundColor[500].base, - indent_guide: borderColor.muted, - indent_guide_active: borderColor.secondary, - line: { - active: withOpacity(colors.neutral[900], 0.06), - highlighted: withOpacity(colors.neutral[900], 0.12), - inserted: backgroundColor.ok.active, - deleted: backgroundColor.error.active, - modified: backgroundColor.info.active, - }, - highlight: { - selection: player[1].selectionColor, - occurrence: withOpacity(colors.neutral[900], 0.06), - activeOccurrence: withOpacity(colors.neutral[900], 0.16), - matchingBracket: colors.neutral[0], - match: colors.yellow[100], - activeMatch: colors.yellow[200], - related: colors.neutral[0], - }, - gutter: { - primary: colors.neutral[300], - active: textColor.active, - }, -}; - -const syntax: Syntax = { - primary: { - color: colors.neutral[800], - weight: fontWeights.normal, - }, - comment: { - color: colors.neutral[500], - weight: fontWeights.normal, - }, - punctuation: { - color: colors.neutral[600], - weight: fontWeights.normal, - }, - constant: { - color: colors.neutral[800], - weight: fontWeights.normal, - }, - keyword: { - color: colors.indigo[700], - weight: fontWeights.normal, - }, - function: { - color: colors.orange[600], - weight: fontWeights.normal, - }, - type: { - color: colors.yellow[600], - weight: fontWeights.normal, - }, - variant: { - color: colors.rose[700], - weight: fontWeights.normal, - }, - property: { - color: colors.emerald[700], - weight: fontWeights.normal, - }, - enum: { - color: colors.red[500], - weight: fontWeights.normal, - }, - operator: { - color: colors.red[500], - weight: fontWeights.normal, - }, - string: { - color: colors.red[500], - weight: fontWeights.normal, - }, - number: { - color: colors.indigo[500], - weight: fontWeights.normal, - }, - boolean: { - color: colors.red[500], - weight: fontWeights.normal, - }, - predictive: { - color: textColor.placeholder, - weight: fontWeights.normal, - }, - title: { - color: colors.sky[500], - weight: fontWeights.bold, - }, - emphasis: { - color: textColor.feature, - weight: fontWeights.normal, - }, - "emphasis.strong": { - color: textColor.feature, - weight: fontWeights.bold, - }, - linkUri: { - color: colors.lime[500], - weight: fontWeights.normal, - underline: true - }, - linkText: { - color: colors.red[500], - weight: fontWeights.normal, - italic: true - }, -}; - -const shadowAlpha: NumberToken = { - value: 0.12, - type: "number", -}; - -const theme: Theme = { - name: "light", - backgroundColor, - borderColor, - textColor, - iconColor, - editor, - syntax, - player, - shadowAlpha, -}; - -export default theme; diff --git a/styles/src/themes/solarized.ts b/styles/src/themes/solarized.ts index 6116c83d17..2b9db83311 100644 --- a/styles/src/themes/solarized.ts +++ b/styles/src/themes/solarized.ts @@ -1,29 +1,19 @@ -import { createTheme } from "./base16"; -import { color } from "../tokens"; +import chroma from "chroma-js"; +import { colorRamp, createTheme } from "./base16"; const name = "solarized"; -const neutrals = [ - color("#002b36"), - color("#073642"), - color("#586e75"), - color("#657b83"), - color("#839496"), - color("#93a1a1"), - color("#eee8d5"), - color("#fdf6e3"), -]; +const ramps = { + neutral: chroma.scale(["#002b36", "#073642", "#586e75", "#657b83", "#839496", "#93a1a1", "#eee8d5", "#fdf6e3"]), + red: colorRamp(chroma("#dc322f")), + orange: colorRamp(chroma("#cb4b16")), + yellow: colorRamp(chroma("#b58900")), + green: colorRamp(chroma("#859900")), + cyan: colorRamp(chroma("#2aa198")), + blue: colorRamp(chroma("#268bd2")), + violet: colorRamp(chroma("#6c71c4")), + magenta: colorRamp(chroma("#d33682")), +} -const colors = { - "red": color("#dc322f"), - "orange": color("#cb4b16"), - "yellow": color("#b58900"), - "green": color("#859900"), - "cyan": color("#2aa198"), - "blue": color("#268bd2"), - "violet": color("#6c71c4"), - "magenta": color("#d33682"), -}; - -export const dark = createTheme(`${name}-dark`, false, neutrals, colors); -export const light = createTheme(`${name}-light`, true, neutrals, colors); \ No newline at end of file +export const dark = createTheme(`${name}-dark`, false, ramps); +export const light = createTheme(`${name}-light`, true, ramps); \ No newline at end of file diff --git a/styles/src/themes/sulphurpool.ts b/styles/src/themes/sulphurpool.ts index 01e7c419f1..727f1ce38a 100644 --- a/styles/src/themes/sulphurpool.ts +++ b/styles/src/themes/sulphurpool.ts @@ -1,29 +1,19 @@ -import { createTheme } from "./base16"; -import { color } from "../tokens"; +import chroma from "chroma-js"; +import { colorRamp, createTheme } from "./base16"; const name = "sulphurpool"; -const neutrals = [ - color("#202746"), - color("#293256"), - color("#5e6687"), - color("#6b7394"), - color("#898ea4"), - color("#979db4"), - color("#dfe2f1"), - color("#f5f7ff"), -] +const ramps = { + neutral: chroma.scale(["#202746", "#293256", "#5e6687", "#6b7394", "#898ea4", "#979db4", "#dfe2f1", "#f5f7ff"]), + red: colorRamp(chroma("#c94922")), + orange: colorRamp(chroma("#c76b29")), + yellow: colorRamp(chroma("#c08b30")), + green: colorRamp(chroma("#ac9739")), + cyan: colorRamp(chroma("#22a2c9")), + blue: colorRamp(chroma("#3d8fd1")), + violet: colorRamp(chroma("#6679cc")), + magenta: colorRamp(chroma("#9c637a")), +} -const colors = { - "red": color("#c94922"), - "orange": color("#c76b29"), - "yellow": color("#c08b30"), - "green": color("#ac9739"), - "cyan": color("#22a2c9"), - "blue": color("#3d8fd1"), - "violet": color("#6679cc"), - "magenta": color("#9c637a"), -}; - -export const dark = createTheme(`${name}-dark`, false, neutrals, colors); -export const light = createTheme(`${name}-light`, true, neutrals, colors); \ No newline at end of file +export const dark = createTheme(`${name}-dark`, false, ramps); +export const light = createTheme(`${name}-light`, true, ramps); \ No newline at end of file diff --git a/styles/src/themes/theme.ts b/styles/src/themes/theme.ts index d1196d21fa..21eda88268 100644 --- a/styles/src/themes/theme.ts +++ b/styles/src/themes/theme.ts @@ -125,9 +125,6 @@ export default interface Theme { line: { active: ColorToken; highlighted: ColorToken; - inserted: ColorToken; - deleted: ColorToken; - modified: ColorToken; }; highlight: { selection: ColorToken;