From fbf1552be910a61e9a5a237d836847736fc197ae Mon Sep 17 00:00:00 2001 From: Sergey Onufrienko Date: Mon, 10 Jul 2023 20:41:39 +0100 Subject: [PATCH 001/160] Add color_family to theme --- styles/src/theme/create_theme.ts | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/styles/src/theme/create_theme.ts b/styles/src/theme/create_theme.ts index d2701f8341af973a3a4511c149c983cb221fa14d..3f4a0766547534d39e43546c722cd2179ce628b1 100644 --- a/styles/src/theme/create_theme.ts +++ b/styles/src/theme/create_theme.ts @@ -1,4 +1,4 @@ -import { Scale, Color } from "chroma-js" +import chroma, { Scale, Color } from "chroma-js" import { Syntax, ThemeSyntax, SyntaxHighlightStyle } from "./syntax" export { Syntax, ThemeSyntax, SyntaxHighlightStyle } import { @@ -32,6 +32,7 @@ export interface Theme { players: Players syntax?: Partial + color_family: ColorFamily } export interface Meta { @@ -69,6 +70,12 @@ export interface Players { "7": Player } +export interface ColorFamily { + range: ColorFamilyRange +} + +export type ColorFamilyRange = Partial<{ [K in keyof RampSet]: number }> + export interface Shadow { blur: number color: string @@ -162,6 +169,10 @@ export function create_theme(theme: ThemeConfig): Theme { "7": player(ramps.yellow), } + const color_family = { + range: build_color_family(ramps) + } + return { name, is_light, @@ -177,6 +188,7 @@ export function create_theme(theme: ThemeConfig): Theme { players, syntax, + color_family, } } @@ -187,6 +199,16 @@ function player(ramp: Scale): Player { } } +function build_color_family(ramps: RampSet): ColorFamilyRange { + const color_family: ColorFamilyRange = {} + + for (const ramp in ramps) { + color_family[ramp as keyof RampSet] = chroma(ramps[ramp as keyof RampSet](0.5)).luminance() + } + + return color_family +} + function lowest_layer(ramps: RampSet): Layer { return { base: build_style_set(ramps.neutral, 0.2, 1), From a56d454a0760420899d8c6582bde60e851efcf27 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Thu, 13 Jul 2023 10:10:24 -0400 Subject: [PATCH 002/160] added semantic search support for c --- crates/zed/src/languages/c/embedding.scm | 39 ++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 crates/zed/src/languages/c/embedding.scm diff --git a/crates/zed/src/languages/c/embedding.scm b/crates/zed/src/languages/c/embedding.scm new file mode 100644 index 0000000000000000000000000000000000000000..cd1915f62bb5c27f7617bde91327a78129564511 --- /dev/null +++ b/crates/zed/src/languages/c/embedding.scm @@ -0,0 +1,39 @@ +(declaration + (type_qualifier)? @context + type: (_)? @context + declarator: [ + (function_declarator + declarator: (_) @name) + (pointer_declarator + "*" @context + declarator: (function_declarator + declarator: (_) @name)) + (pointer_declarator + "*" @context + declarator: (pointer_declarator + "*" @context + declarator: (function_declarator + declarator: (_) @name))) + ] +) @item + +(function_definition + (type_qualifier)? @context + type: (_)? @context + declarator: [ + (function_declarator + declarator: (_) @name + ) + (pointer_declarator + "*" @context + declarator: (function_declarator + declarator: (_) @name + )) + (pointer_declarator + "*" @context + declarator: (pointer_declarator + "*" @context + declarator: (function_declarator + declarator: (_) @name))) + ] +) @item From 5eab62858004493879172ff4576ca32ced8e6bea Mon Sep 17 00:00:00 2001 From: KCaverly Date: Thu, 13 Jul 2023 14:33:31 -0400 Subject: [PATCH 003/160] Added go parsing for semantic search, and added preceeding comments on go and rust. Co-authored-by: Alex Co-authored-by: maxbrunsfeld --- crates/language/src/language.rs | 4 -- crates/vector_store/src/parsing.rs | 23 ++++---- crates/zed/src/languages/go/embedding.scm | 24 +++++++++ crates/zed/src/languages/rust/embedding.scm | 58 ++++++++------------- 4 files changed, 55 insertions(+), 54 deletions(-) create mode 100644 crates/zed/src/languages/go/embedding.scm diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index dbd35f0e87bc602ac91aaf8196b81a4a017fff93..4ec5e88a7edde55c90e975c4bd944e3f38c1bb8b 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -525,7 +525,6 @@ pub struct EmbeddingConfig { pub item_capture_ix: u32, pub name_capture_ix: u32, pub context_capture_ix: Option, - pub extra_context_capture_ix: Option, } struct InjectionConfig { @@ -1246,14 +1245,12 @@ impl Language { let mut item_capture_ix = None; let mut name_capture_ix = None; let mut context_capture_ix = None; - let mut extra_context_capture_ix = None; get_capture_indices( &query, &mut [ ("item", &mut item_capture_ix), ("name", &mut name_capture_ix), ("context", &mut context_capture_ix), - ("context.extra", &mut extra_context_capture_ix), ], ); if let Some((item_capture_ix, name_capture_ix)) = item_capture_ix.zip(name_capture_ix) { @@ -1262,7 +1259,6 @@ impl Language { item_capture_ix, name_capture_ix, context_capture_ix, - extra_context_capture_ix, }); } Ok(self) diff --git a/crates/vector_store/src/parsing.rs b/crates/vector_store/src/parsing.rs index 91dcf699f8c3add9088b2af4f0d4df59b7551ac2..3e697399b1fa5b6dc2a42a29ec97f1e490643613 100644 --- a/crates/vector_store/src/parsing.rs +++ b/crates/vector_store/src/parsing.rs @@ -53,7 +53,7 @@ impl CodeContextRetriever { .ok_or_else(|| anyhow!("parsing failed"))?; let mut documents = Vec::new(); - let mut context_spans = Vec::new(); + let mut document_texts = Vec::new(); // Iterate through query matches for mat in self.cursor.matches( @@ -61,11 +61,10 @@ impl CodeContextRetriever { tree.root_node(), content.as_bytes(), ) { - // log::info!("-----MATCH-----"); - let mut name: Vec<&str> = vec![]; let mut item: Option<&str> = None; let mut offset: Option = None; + let mut context_spans: Vec<&str> = vec![]; for capture in mat.captures { if capture.index == embedding_config.item_capture_ix { offset = Some(capture.node.byte_range().start); @@ -79,25 +78,21 @@ impl CodeContextRetriever { if let Some(context_capture_ix) = embedding_config.context_capture_ix { if capture.index == context_capture_ix { if let Some(context) = content.get(capture.node.byte_range()) { - name.push(context); + context_spans.push(context); } } } } if item.is_some() && offset.is_some() && name.len() > 0 { - let context_span = CODE_CONTEXT_TEMPLATE + let item = format!("{}\n{}", context_spans.join("\n"), item.unwrap()); + + let document_text = CODE_CONTEXT_TEMPLATE .replace("", pending_file.relative_path.to_str().unwrap()) .replace("", &pending_file.language.name().to_lowercase()) - .replace("", item.unwrap()); - - let mut truncated_span = context_span.clone(); - truncated_span.truncate(100); - - // log::info!("Name: {:?}", name); - // log::info!("Span: {:?}", truncated_span); + .replace("", item.as_str()); - context_spans.push(context_span); + document_texts.push(document_text); documents.push(Document { name: name.join(" "), offset: offset.unwrap(), @@ -112,7 +107,7 @@ impl CodeContextRetriever { mtime: pending_file.modified_time, documents, }, - context_spans, + document_texts, )); } } diff --git a/crates/zed/src/languages/go/embedding.scm b/crates/zed/src/languages/go/embedding.scm new file mode 100644 index 0000000000000000000000000000000000000000..9d8700cdfb57d1008acc09c11013f2046e7bd157 --- /dev/null +++ b/crates/zed/src/languages/go/embedding.scm @@ -0,0 +1,24 @@ +( + (comment)* @context + . + (type_declaration + (type_spec + name: (_) @name) + ) @item +) + +( + (comment)* @context + . + (function_declaration + name: (_) @name + ) @item +) + +( + (comment)* @context + . + (method_declaration + name: (_) @name + ) @item +) diff --git a/crates/zed/src/languages/rust/embedding.scm b/crates/zed/src/languages/rust/embedding.scm index ea8bab9f68113a9b725e094a4d31f3e572c4bed7..3aec101e9fbb5d63a49db52869f34757135b0ab2 100644 --- a/crates/zed/src/languages/rust/embedding.scm +++ b/crates/zed/src/languages/rust/embedding.scm @@ -1,36 +1,22 @@ -(struct_item - (visibility_modifier)? @context - "struct" @context - name: (_) @name) @item - -(enum_item - (visibility_modifier)? @context - "enum" @context - name: (_) @name) @item - -(impl_item - "impl" @context - trait: (_)? @name - "for"? @context - type: (_) @name) @item - -(trait_item - (visibility_modifier)? @context - "trait" @context - name: (_) @name) @item - -(function_item - (visibility_modifier)? @context - (function_modifiers)? @context - "fn" @context - name: (_) @name) @item - -(function_signature_item - (visibility_modifier)? @context - (function_modifiers)? @context - "fn" @context - name: (_) @name) @item - -(macro_definition - . "macro_rules!" @context - name: (_) @name) @item +( + (line_comment)* @context + . + [ + (enum_item + name: (_) @name) @item + (struct_item + name: (_) @name) @item + (impl_item + trait: (_)? @name + "for"? @name + type: (_) @name) @item + (trait_item + name: (_) @name) @item + (function_item + name: (_) @name) @item + (macro_definition + name: (_) @name) @item + (function_signature_item + name: (_) @name) @item + ] +) From 0a0e40fb246b3f1e0e8751f24bf008387f223c4b Mon Sep 17 00:00:00 2001 From: KCaverly Date: Thu, 13 Jul 2023 16:34:32 -0400 Subject: [PATCH 004/160] refactored code context retrieval and standardized database migration Co-authored-by: maxbrunsfeld --- Cargo.lock | 2 + crates/vector_store/Cargo.toml | 3 + crates/vector_store/src/db.rs | 132 +++++++++++------ crates/vector_store/src/modal.rs | 2 +- crates/vector_store/src/parsing.rs | 82 +++++----- crates/vector_store/src/vector_store.rs | 140 ++++++++++-------- crates/vector_store/src/vector_store_tests.rs | 21 ++- 7 files changed, 233 insertions(+), 149 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ac6a2ee890418104d6851a961d321f1ef7e8f36..4359659a53bad7b2b33bca0fa9e41cd6ae09b11f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8483,7 +8483,9 @@ dependencies = [ "anyhow", "async-trait", "bincode", + "ctor", "editor", + "env_logger 0.9.3", "futures 0.3.28", "gpui", "isahc", diff --git a/crates/vector_store/Cargo.toml b/crates/vector_store/Cargo.toml index 40bff8b95c167e43c9f20d31e47871d52d5ff8b1..8e1dea59fd8c0fe890291388fccaa9ac7cd3443d 100644 --- a/crates/vector_store/Cargo.toml +++ b/crates/vector_store/Cargo.toml @@ -44,6 +44,9 @@ rpc = { path = "../rpc", features = ["test-support"] } workspace = { path = "../workspace", features = ["test-support"] } settings = { path = "../settings", features = ["test-support"]} tree-sitter-rust = "*" + rand.workspace = true unindent.workspace = true tempdir.workspace = true +ctor.workspace = true +env_logger.workspace = true diff --git a/crates/vector_store/src/db.rs b/crates/vector_store/src/db.rs index a91a1872b59774a1863ae2a9ff867cf1b7ad39b3..d3d05f8c62c9d5639e641094204caa112e96c54f 100644 --- a/crates/vector_store/src/db.rs +++ b/crates/vector_store/src/db.rs @@ -1,21 +1,21 @@ +use crate::{parsing::Document, VECTOR_STORE_VERSION}; +use anyhow::{anyhow, Result}; +use project::Fs; +use rpc::proto::Timestamp; +use rusqlite::{ + params, + types::{FromSql, FromSqlResult, ValueRef}, +}; use std::{ cmp::Ordering, collections::HashMap, + ops::Range, path::{Path, PathBuf}, rc::Rc, + sync::Arc, time::SystemTime, }; -use anyhow::{anyhow, Result}; - -use crate::parsing::ParsedFile; -use crate::VECTOR_STORE_VERSION; -use rpc::proto::Timestamp; -use rusqlite::{ - params, - types::{FromSql, FromSqlResult, ValueRef}, -}; - #[derive(Debug)] pub struct FileRecord { pub id: usize, @@ -42,48 +42,88 @@ pub struct VectorDatabase { } impl VectorDatabase { - pub fn new(path: String) -> Result { + pub async fn new(fs: Arc, path: Arc) -> Result { + if let Some(db_directory) = path.parent() { + fs.create_dir(db_directory).await?; + } + let this = Self { - db: rusqlite::Connection::open(path)?, + db: rusqlite::Connection::open(path.as_path())?, }; this.initialize_database()?; Ok(this) } + fn get_existing_version(&self) -> Result { + let mut version_query = self.db.prepare("SELECT version from vector_store_config")?; + version_query + .query_row([], |row| Ok(row.get::<_, i64>(0)?)) + .map_err(|err| anyhow!("version query failed: {err}")) + } + fn initialize_database(&self) -> Result<()> { rusqlite::vtab::array::load_module(&self.db)?; - // This will create the database if it doesnt exist + if self + .get_existing_version() + .map_or(false, |version| version == VECTOR_STORE_VERSION as i64) + { + return Ok(()); + } + + self.db + .execute( + " + DROP TABLE vector_store_config; + DROP TABLE worktrees; + DROP TABLE files; + DROP TABLE documents; + ", + [], + ) + .ok(); // Initialize Vector Databasing Tables self.db.execute( - "CREATE TABLE IF NOT EXISTS worktrees ( + "CREATE TABLE vector_store_config ( + version INTEGER NOT NULL + )", + [], + )?; + + self.db.execute( + "INSERT INTO vector_store_config (version) VALUES (?1)", + params![VECTOR_STORE_VERSION], + )?; + + self.db.execute( + "CREATE TABLE worktrees ( id INTEGER PRIMARY KEY AUTOINCREMENT, absolute_path VARCHAR NOT NULL ); - CREATE UNIQUE INDEX IF NOT EXISTS worktrees_absolute_path ON worktrees (absolute_path); + CREATE UNIQUE INDEX worktrees_absolute_path ON worktrees (absolute_path); ", [], )?; self.db.execute( - "CREATE TABLE IF NOT EXISTS files ( + "CREATE TABLE files ( id INTEGER PRIMARY KEY AUTOINCREMENT, worktree_id INTEGER NOT NULL, relative_path VARCHAR NOT NULL, mtime_seconds INTEGER NOT NULL, mtime_nanos INTEGER NOT NULL, - vector_store_version INTEGER NOT NULL, FOREIGN KEY(worktree_id) REFERENCES worktrees(id) ON DELETE CASCADE )", [], )?; self.db.execute( - "CREATE TABLE IF NOT EXISTS documents ( + "CREATE TABLE documents ( id INTEGER PRIMARY KEY AUTOINCREMENT, file_id INTEGER NOT NULL, - offset INTEGER NOT NULL, + start_byte INTEGER NOT NULL, + end_byte INTEGER NOT NULL, name VARCHAR NOT NULL, embedding BLOB NOT NULL, FOREIGN KEY(file_id) REFERENCES files(id) ON DELETE CASCADE @@ -102,43 +142,44 @@ impl VectorDatabase { Ok(()) } - pub fn insert_file(&self, worktree_id: i64, indexed_file: ParsedFile) -> Result<()> { + pub fn insert_file( + &self, + worktree_id: i64, + path: PathBuf, + mtime: SystemTime, + documents: Vec, + ) -> Result<()> { // Write to files table, and return generated id. self.db.execute( " DELETE FROM files WHERE worktree_id = ?1 AND relative_path = ?2; ", - params![worktree_id, indexed_file.path.to_str()], + params![worktree_id, path.to_str()], )?; - let mtime = Timestamp::from(indexed_file.mtime); + let mtime = Timestamp::from(mtime); self.db.execute( " INSERT INTO files - (worktree_id, relative_path, mtime_seconds, mtime_nanos, vector_store_version) + (worktree_id, relative_path, mtime_seconds, mtime_nanos) VALUES - (?1, ?2, $3, $4, $5); + (?1, ?2, $3, $4); ", - params![ - worktree_id, - indexed_file.path.to_str(), - mtime.seconds, - mtime.nanos, - VECTOR_STORE_VERSION - ], + params![worktree_id, path.to_str(), mtime.seconds, mtime.nanos], )?; let file_id = self.db.last_insert_rowid(); // Currently inserting at approximately 3400 documents a second // I imagine we can speed this up with a bulk insert of some kind. - for document in indexed_file.documents { + for document in documents { let embedding_blob = bincode::serialize(&document.embedding)?; self.db.execute( - "INSERT INTO documents (file_id, offset, name, embedding) VALUES (?1, ?2, ?3, ?4)", + "INSERT INTO documents (file_id, start_byte, end_byte, name, embedding) VALUES (?1, ?2, ?3, ?4, $5)", params![ file_id, - document.offset.to_string(), + document.range.start.to_string(), + document.range.end.to_string(), document.name, embedding_blob ], @@ -204,7 +245,7 @@ impl VectorDatabase { worktree_ids: &[i64], query_embedding: &Vec, limit: usize, - ) -> Result> { + ) -> Result, String)>> { let mut results = Vec::<(i64, f32)>::with_capacity(limit + 1); self.for_each_document(&worktree_ids, |id, embedding| { let similarity = dot(&embedding, &query_embedding); @@ -248,11 +289,18 @@ impl VectorDatabase { Ok(()) } - fn get_documents_by_ids(&self, ids: &[i64]) -> Result> { + fn get_documents_by_ids( + &self, + ids: &[i64], + ) -> Result, String)>> { let mut statement = self.db.prepare( " SELECT - documents.id, files.worktree_id, files.relative_path, documents.offset, documents.name + documents.id, + files.worktree_id, + files.relative_path, + documents.start_byte, + documents.end_byte, documents.name FROM documents, files WHERE @@ -266,15 +314,15 @@ impl VectorDatabase { row.get::<_, i64>(0)?, row.get::<_, i64>(1)?, row.get::<_, String>(2)?.into(), - row.get(3)?, - row.get(4)?, + row.get(3)?..row.get(4)?, + row.get(5)?, )) })?; - let mut values_by_id = HashMap::::default(); + let mut values_by_id = HashMap::, String)>::default(); for row in result_iter { - let (id, worktree_id, path, offset, name) = row?; - values_by_id.insert(id, (worktree_id, path, offset, name)); + let (id, worktree_id, path, range, name) = row?; + values_by_id.insert(id, (worktree_id, path, range, name)); } let mut results = Vec::with_capacity(ids.len()); diff --git a/crates/vector_store/src/modal.rs b/crates/vector_store/src/modal.rs index 9225fe8786e9173a82b32a9aedf5a7e979ff6f88..b797a208062ee623db11fbbfe40948847639465f 100644 --- a/crates/vector_store/src/modal.rs +++ b/crates/vector_store/src/modal.rs @@ -66,7 +66,7 @@ impl PickerDelegate for SemanticSearchDelegate { }); let workspace = self.workspace.clone(); - let position = search_result.clone().offset; + let position = search_result.clone().byte_range.start; cx.spawn(|_, mut cx| async move { let buffer = buffer.await?; workspace.update(&mut cx, |workspace, cx| { diff --git a/crates/vector_store/src/parsing.rs b/crates/vector_store/src/parsing.rs index 3e697399b1fa5b6dc2a42a29ec97f1e490643613..23dcf505c92896b1eb18499d4b05b633d1c37bf7 100644 --- a/crates/vector_store/src/parsing.rs +++ b/crates/vector_store/src/parsing.rs @@ -1,41 +1,39 @@ -use std::{path::PathBuf, sync::Arc, time::SystemTime}; - use anyhow::{anyhow, Ok, Result}; -use project::Fs; +use language::Language; +use std::{ops::Range, path::Path, sync::Arc}; use tree_sitter::{Parser, QueryCursor}; -use crate::PendingFile; - #[derive(Debug, PartialEq, Clone)] pub struct Document { - pub offset: usize, pub name: String, + pub range: Range, + pub content: String, pub embedding: Vec, } -#[derive(Debug, PartialEq, Clone)] -pub struct ParsedFile { - pub path: PathBuf, - pub mtime: SystemTime, - pub documents: Vec, -} - const CODE_CONTEXT_TEMPLATE: &str = "The below code snippet is from file ''\n\n```\n\n```"; pub struct CodeContextRetriever { pub parser: Parser, pub cursor: QueryCursor, - pub fs: Arc, } impl CodeContextRetriever { - pub async fn parse_file( + pub fn new() -> Self { + Self { + parser: Parser::new(), + cursor: QueryCursor::new(), + } + } + + pub fn parse_file( &mut self, - pending_file: PendingFile, - ) -> Result<(ParsedFile, Vec)> { - let grammar = pending_file - .language + relative_path: &Path, + content: &str, + language: Arc, + ) -> Result> { + let grammar = language .grammar() .ok_or_else(|| anyhow!("no grammar for language"))?; let embedding_config = grammar @@ -43,8 +41,6 @@ impl CodeContextRetriever { .as_ref() .ok_or_else(|| anyhow!("no embedding queries"))?; - let content = self.fs.load(&pending_file.absolute_path).await?; - self.parser.set_language(grammar.ts_language).unwrap(); let tree = self @@ -53,7 +49,6 @@ impl CodeContextRetriever { .ok_or_else(|| anyhow!("parsing failed"))?; let mut documents = Vec::new(); - let mut document_texts = Vec::new(); // Iterate through query matches for mat in self.cursor.matches( @@ -63,11 +58,11 @@ impl CodeContextRetriever { ) { let mut name: Vec<&str> = vec![]; let mut item: Option<&str> = None; - let mut offset: Option = None; + let mut byte_range: Option> = None; let mut context_spans: Vec<&str> = vec![]; for capture in mat.captures { if capture.index == embedding_config.item_capture_ix { - offset = Some(capture.node.byte_range().start); + byte_range = Some(capture.node.byte_range()); item = content.get(capture.node.byte_range()); } else if capture.index == embedding_config.name_capture_ix { if let Some(name_content) = content.get(capture.node.byte_range()) { @@ -84,30 +79,25 @@ impl CodeContextRetriever { } } - if item.is_some() && offset.is_some() && name.len() > 0 { - let item = format!("{}\n{}", context_spans.join("\n"), item.unwrap()); - - let document_text = CODE_CONTEXT_TEMPLATE - .replace("", pending_file.relative_path.to_str().unwrap()) - .replace("", &pending_file.language.name().to_lowercase()) - .replace("", item.as_str()); - - document_texts.push(document_text); - documents.push(Document { - name: name.join(" "), - offset: offset.unwrap(), - embedding: Vec::new(), - }) + if let Some((item, byte_range)) = item.zip(byte_range) { + if !name.is_empty() { + let item = format!("{}\n{}", context_spans.join("\n"), item); + + let document_text = CODE_CONTEXT_TEMPLATE + .replace("", relative_path.to_str().unwrap()) + .replace("", &language.name().to_lowercase()) + .replace("", item.as_str()); + + documents.push(Document { + range: byte_range, + content: document_text, + embedding: Vec::new(), + name: name.join(" ").to_string(), + }); + } } } - return Ok(( - ParsedFile { - path: pending_file.relative_path, - mtime: pending_file.modified_time, - documents, - }, - document_texts, - )); + return Ok(documents); } } diff --git a/crates/vector_store/src/vector_store.rs b/crates/vector_store/src/vector_store.rs index 0a197bc40663034d4156cf025c731449cef725c7..3d9c32875eef17c6cc58b1bed1637c1b920c2b0f 100644 --- a/crates/vector_store/src/vector_store.rs +++ b/crates/vector_store/src/vector_store.rs @@ -18,16 +18,16 @@ use gpui::{ }; use language::{Language, LanguageRegistry}; use modal::{SemanticSearch, SemanticSearchDelegate, Toggle}; -use parsing::{CodeContextRetriever, ParsedFile}; +use parsing::{CodeContextRetriever, Document}; use project::{Fs, PathChange, Project, ProjectEntryId, WorktreeId}; use smol::channel; use std::{ collections::HashMap, + ops::Range, path::{Path, PathBuf}, sync::Arc, time::{Duration, Instant, SystemTime}, }; -use tree_sitter::{Parser, QueryCursor}; use util::{ channel::{ReleaseChannel, RELEASE_CHANNEL, RELEASE_CHANNEL_NAME}, http::HttpClient, @@ -36,7 +36,7 @@ use util::{ }; use workspace::{Workspace, WorkspaceCreated}; -const VECTOR_STORE_VERSION: usize = 0; +const VECTOR_STORE_VERSION: usize = 1; const EMBEDDINGS_BATCH_SIZE: usize = 150; pub fn init( @@ -80,11 +80,11 @@ pub fn init( let vector_store = VectorStore::new( fs, db_file_path, - // Arc::new(embedding::DummyEmbeddings {}), - Arc::new(OpenAIEmbeddings { - client: http_client, - executor: cx.background(), - }), + Arc::new(embedding::DummyEmbeddings {}), + // Arc::new(OpenAIEmbeddings { + // client: http_client, + // executor: cx.background(), + // }), language_registry, cx.clone(), ) @@ -212,14 +212,16 @@ pub struct PendingFile { pub struct SearchResult { pub worktree_id: WorktreeId, pub name: String, - pub offset: usize, + pub byte_range: Range, pub file_path: PathBuf, } enum DbOperation { InsertFile { worktree_id: i64, - indexed_file: ParsedFile, + documents: Vec, + path: PathBuf, + mtime: SystemTime, }, Delete { worktree_id: i64, @@ -238,8 +240,9 @@ enum DbOperation { enum EmbeddingJob { Enqueue { worktree_id: i64, - parsed_file: ParsedFile, - document_spans: Vec, + path: PathBuf, + mtime: SystemTime, + documents: Vec, }, Flush, } @@ -256,18 +259,7 @@ impl VectorStore { let db = cx .background() - .spawn({ - let fs = fs.clone(); - let database_url = database_url.clone(); - async move { - if let Some(db_directory) = database_url.parent() { - fs.create_dir(db_directory).await.log_err(); - } - - let db = VectorDatabase::new(database_url.to_string_lossy().to_string())?; - anyhow::Ok(db) - } - }) + .spawn(VectorDatabase::new(fs.clone(), database_url.clone())) .await?; Ok(cx.add_model(|cx| { @@ -280,9 +272,12 @@ impl VectorStore { match job { DbOperation::InsertFile { worktree_id, - indexed_file, + documents, + path, + mtime, } => { - db.insert_file(worktree_id, indexed_file).log_err(); + db.insert_file(worktree_id, path, mtime, documents) + .log_err(); } DbOperation::Delete { worktree_id, path } => { db.delete_file(worktree_id, path).log_err(); @@ -304,35 +299,45 @@ impl VectorStore { // embed_tx/rx: Embed Batch and Send to Database let (embed_batch_tx, embed_batch_rx) = - channel::unbounded::)>>(); + channel::unbounded::, PathBuf, SystemTime)>>(); let _embed_batch_task = cx.background().spawn({ let db_update_tx = db_update_tx.clone(); let embedding_provider = embedding_provider.clone(); async move { while let Ok(mut embeddings_queue) = embed_batch_rx.recv().await { // Construct Batch - let mut document_spans = vec![]; - for (_, _, document_span) in embeddings_queue.iter() { - document_spans.extend(document_span.iter().map(|s| s.as_str())); + let mut batch_documents = vec![]; + for (_, documents, _, _) in embeddings_queue.iter() { + batch_documents + .extend(documents.iter().map(|document| document.content.as_str())); } - if let Ok(embeddings) = embedding_provider.embed_batch(document_spans).await + if let Ok(embeddings) = + embedding_provider.embed_batch(batch_documents).await { + log::trace!( + "created {} embeddings for {} files", + embeddings.len(), + embeddings_queue.len(), + ); + let mut i = 0; let mut j = 0; for embedding in embeddings.iter() { - while embeddings_queue[i].1.documents.len() == j { + while embeddings_queue[i].1.len() == j { i += 1; j = 0; } - embeddings_queue[i].1.documents[j].embedding = embedding.to_owned(); + embeddings_queue[i].1[j].embedding = embedding.to_owned(); j += 1; } - for (worktree_id, indexed_file, _) in embeddings_queue.into_iter() { - for document in indexed_file.documents.iter() { + for (worktree_id, documents, path, mtime) in + embeddings_queue.into_iter() + { + for document in documents.iter() { // TODO: Update this so it doesn't panic assert!( document.embedding.len() > 0, @@ -343,7 +348,9 @@ impl VectorStore { db_update_tx .send(DbOperation::InsertFile { worktree_id, - indexed_file, + documents, + path, + mtime, }) .await .unwrap(); @@ -362,12 +369,13 @@ impl VectorStore { while let Ok(job) = batch_files_rx.recv().await { let should_flush = match job { EmbeddingJob::Enqueue { - document_spans, + documents, worktree_id, - parsed_file, + path, + mtime, } => { - queue_len += &document_spans.len(); - embeddings_queue.push((worktree_id, parsed_file, document_spans)); + queue_len += &documents.len(); + embeddings_queue.push((worktree_id, documents, path, mtime)); queue_len >= EMBEDDINGS_BATCH_SIZE } EmbeddingJob::Flush => true, @@ -385,26 +393,38 @@ impl VectorStore { let (parsing_files_tx, parsing_files_rx) = channel::unbounded::(); let mut _parsing_files_tasks = Vec::new(); - // for _ in 0..cx.background().num_cpus() { - for _ in 0..1 { + for _ in 0..cx.background().num_cpus() { let fs = fs.clone(); let parsing_files_rx = parsing_files_rx.clone(); let batch_files_tx = batch_files_tx.clone(); _parsing_files_tasks.push(cx.background().spawn(async move { - let parser = Parser::new(); - let cursor = QueryCursor::new(); - let mut retriever = CodeContextRetriever { parser, cursor, fs }; + let mut retriever = CodeContextRetriever::new(); while let Ok(pending_file) = parsing_files_rx.recv().await { - if let Some((indexed_file, document_spans)) = - retriever.parse_file(pending_file.clone()).await.log_err() + if let Some(content) = fs.load(&pending_file.absolute_path).await.log_err() { - batch_files_tx - .try_send(EmbeddingJob::Enqueue { - worktree_id: pending_file.worktree_db_id, - parsed_file: indexed_file, - document_spans, - }) - .unwrap(); + if let Some(documents) = retriever + .parse_file( + &pending_file.relative_path, + &content, + pending_file.language, + ) + .log_err() + { + log::trace!( + "parsed path {:?}: {} documents", + pending_file.relative_path, + documents.len() + ); + + batch_files_tx + .try_send(EmbeddingJob::Enqueue { + worktree_id: pending_file.worktree_db_id, + path: pending_file.relative_path, + mtime: pending_file.modified_time, + documents, + }) + .unwrap(); + } } if parsing_files_rx.len() == 0 { @@ -543,6 +563,7 @@ impl VectorStore { }); if !already_stored { + log::trace!("sending for parsing: {:?}", path_buf); parsing_files_tx .try_send(PendingFile { worktree_db_id: db_ids_by_worktree_id @@ -565,8 +586,8 @@ impl VectorStore { .unwrap(); } } - log::info!( - "Parsing Worktree Completed in {:?}", + log::trace!( + "parsing worktree completed in {:?}", t0.elapsed().as_millis() ); } @@ -622,11 +643,12 @@ impl VectorStore { let embedding_provider = self.embedding_provider.clone(); let database_url = self.database_url.clone(); + let fs = self.fs.clone(); cx.spawn(|this, cx| async move { let documents = cx .background() .spawn(async move { - let database = VectorDatabase::new(database_url.to_string_lossy().into())?; + let database = VectorDatabase::new(fs, database_url).await?; let phrase_embedding = embedding_provider .embed_batch(vec![&phrase]) @@ -648,12 +670,12 @@ impl VectorStore { Ok(documents .into_iter() - .filter_map(|(worktree_db_id, file_path, offset, name)| { + .filter_map(|(worktree_db_id, file_path, byte_range, name)| { let worktree_id = project_state.worktree_id_for_db_id(worktree_db_id)?; Some(SearchResult { worktree_id, name, - offset, + byte_range, file_path, }) }) diff --git a/crates/vector_store/src/vector_store_tests.rs b/crates/vector_store/src/vector_store_tests.rs index b6e47e7a2341e71a790a749642770e81cd147aaf..c4349c72808a90ff2baeedd2485a11592a56d87c 100644 --- a/crates/vector_store/src/vector_store_tests.rs +++ b/crates/vector_store/src/vector_store_tests.rs @@ -12,6 +12,13 @@ use settings::SettingsStore; use std::sync::Arc; use unindent::Unindent; +#[ctor::ctor] +fn init_logger() { + if std::env::var("RUST_LOG").is_ok() { + env_logger::init(); + } +} + #[gpui::test] async fn test_vector_store(cx: &mut TestAppContext) { cx.update(|cx| { @@ -95,11 +102,23 @@ async fn test_vector_store(cx: &mut TestAppContext) { .await .unwrap(); - assert_eq!(search_results[0].offset, 0); + assert_eq!(search_results[0].byte_range.start, 0); assert_eq!(search_results[0].name, "aaa"); assert_eq!(search_results[0].worktree_id, worktree_id); } +#[gpui::test] +async fn test_code_context_retrieval(cx: &mut TestAppContext) { + // let mut retriever = CodeContextRetriever::new(fs); + + // retriever::parse_file( + // " + // // + // ", + // ); + // +} + #[gpui::test] fn test_dot_product(mut rng: StdRng) { assert_eq!(dot(&[1., 0., 0., 0., 0.], &[0., 1., 0., 0., 0.]), 0.); From 623cb9833c17aaac11d4a2d4bea03295ffa842c4 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Thu, 13 Jul 2023 16:58:42 -0400 Subject: [PATCH 005/160] add tests for rust context parsing, and update rust embedding query Co-authored-by: maxbrunsfeld --- crates/vector_store/src/parsing.rs | 6 +- crates/vector_store/src/vector_store_tests.rs | 156 ++++++++++++++---- crates/zed/src/languages/rust/embedding.scm | 64 +++++-- 3 files changed, 179 insertions(+), 47 deletions(-) diff --git a/crates/vector_store/src/parsing.rs b/crates/vector_store/src/parsing.rs index 23dcf505c92896b1eb18499d4b05b633d1c37bf7..8d6e03d6eb29d524db23848adfa15a8ac6b4b164 100644 --- a/crates/vector_store/src/parsing.rs +++ b/crates/vector_store/src/parsing.rs @@ -81,7 +81,11 @@ impl CodeContextRetriever { if let Some((item, byte_range)) = item.zip(byte_range) { if !name.is_empty() { - let item = format!("{}\n{}", context_spans.join("\n"), item); + let item = if context_spans.is_empty() { + item.to_string() + } else { + format!("{}\n{}", context_spans.join("\n"), item) + }; let document_text = CODE_CONTEXT_TEMPLATE .replace("", relative_path.to_str().unwrap()) diff --git a/crates/vector_store/src/vector_store_tests.rs b/crates/vector_store/src/vector_store_tests.rs index c4349c72808a90ff2baeedd2485a11592a56d87c..ccdd9fdaf07605b36f025d3a4bad63a3a2f516c2 100644 --- a/crates/vector_store/src/vector_store_tests.rs +++ b/crates/vector_store/src/vector_store_tests.rs @@ -1,5 +1,9 @@ use crate::{ - db::dot, embedding::EmbeddingProvider, vector_store_settings::VectorStoreSettings, VectorStore, + db::dot, + embedding::EmbeddingProvider, + parsing::{CodeContextRetriever, Document}, + vector_store_settings::VectorStoreSettings, + VectorStore, }; use anyhow::Result; use async_trait::async_trait; @@ -9,7 +13,7 @@ use project::{project_settings::ProjectSettings, FakeFs, Project}; use rand::{rngs::StdRng, Rng}; use serde_json::json; use settings::SettingsStore; -use std::sync::Arc; +use std::{path::Path, sync::Arc}; use unindent::Unindent; #[ctor::ctor] @@ -52,24 +56,7 @@ async fn test_vector_store(cx: &mut TestAppContext) { .await; let languages = Arc::new(LanguageRegistry::new(Task::ready(()))); - let rust_language = Arc::new( - Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".into()], - ..Default::default() - }, - Some(tree_sitter_rust::language()), - ) - .with_embedding_query( - r#" - (function_item - name: (identifier) @name - body: (block)) @item - "#, - ) - .unwrap(), - ); + let rust_language = rust_lang(); languages.add(rust_language); let db_dir = tempdir::TempDir::new("vector-store").unwrap(); @@ -109,14 +96,59 @@ async fn test_vector_store(cx: &mut TestAppContext) { #[gpui::test] async fn test_code_context_retrieval(cx: &mut TestAppContext) { - // let mut retriever = CodeContextRetriever::new(fs); - - // retriever::parse_file( - // " - // // - // ", - // ); - // + let language = rust_lang(); + let mut retriever = CodeContextRetriever::new(); + + let text = " + /// A doc comment + /// that spans multiple lines + fn a() { + b + } + + impl C for D { + } + " + .unindent(); + + let parsed_files = retriever + .parse_file(Path::new("foo.rs"), &text, language) + .unwrap(); + + assert_eq!( + parsed_files, + &[ + Document { + name: "a".into(), + range: text.find("fn a").unwrap()..(text.find("}").unwrap() + 1), + content: " + The below code snippet is from file 'foo.rs' + + ```rust + /// A doc comment + /// that spans multiple lines + fn a() { + b + } + ```" + .unindent(), + embedding: vec![], + }, + Document { + name: "C for D".into(), + range: text.find("impl C").unwrap()..(text.rfind("}").unwrap() + 1), + content: " + The below code snippet is from file 'foo.rs' + + ```rust + impl C for D { + } + ```" + .unindent(), + embedding: vec![], + } + ] + ); } #[gpui::test] @@ -178,3 +210,71 @@ impl EmbeddingProvider for FakeEmbeddingProvider { .collect()) } } + +fn rust_lang() -> Arc { + Arc::new( + Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".into()], + ..Default::default() + }, + Some(tree_sitter_rust::language()), + ) + .with_embedding_query( + r#" + ( + (line_comment)* @context + . + (enum_item + name: (_) @name) @item + ) + + ( + (line_comment)* @context + . + (struct_item + name: (_) @name) @item + ) + + ( + (line_comment)* @context + . + (impl_item + trait: (_)? @name + "for"? @name + type: (_) @name) @item + ) + + ( + (line_comment)* @context + . + (trait_item + name: (_) @name) @item + ) + + ( + (line_comment)* @context + . + (function_item + name: (_) @name) @item + ) + + ( + (line_comment)* @context + . + (macro_definition + name: (_) @name) @item + ) + + ( + (line_comment)* @context + . + (function_signature_item + name: (_) @name) @item + ) + "#, + ) + .unwrap(), + ) +} diff --git a/crates/zed/src/languages/rust/embedding.scm b/crates/zed/src/languages/rust/embedding.scm index 3aec101e9fbb5d63a49db52869f34757135b0ab2..66e4083de5f0fe8b1adfa2ea657668e4453e4b61 100644 --- a/crates/zed/src/languages/rust/embedding.scm +++ b/crates/zed/src/languages/rust/embedding.scm @@ -1,22 +1,50 @@ ( (line_comment)* @context . - [ - (enum_item - name: (_) @name) @item - (struct_item - name: (_) @name) @item - (impl_item - trait: (_)? @name - "for"? @name - type: (_) @name) @item - (trait_item - name: (_) @name) @item - (function_item - name: (_) @name) @item - (macro_definition - name: (_) @name) @item - (function_signature_item - name: (_) @name) @item - ] + (enum_item + name: (_) @name) @item +) + +( + (line_comment)* @context + . + (struct_item + name: (_) @name) @item +) + +( + (line_comment)* @context + . + (impl_item + trait: (_)? @name + "for"? @name + type: (_) @name) @item +) + +( + (line_comment)* @context + . + (trait_item + name: (_) @name) @item +) + +( + (line_comment)* @context + . + (function_item + name: (_) @name) @item +) + +( + (line_comment)* @context + . + (macro_definition + name: (_) @name) @item +) + +( + (line_comment)* @context + . + (function_signature_item + name: (_) @name) @item ) From d8fd0be59832d52ef7e21784a43c697c53e789e9 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Thu, 13 Jul 2023 17:01:56 -0400 Subject: [PATCH 006/160] update vector store to remove dummy embeddings --- crates/vector_store/src/vector_store.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/vector_store/src/vector_store.rs b/crates/vector_store/src/vector_store.rs index 3d9c32875eef17c6cc58b1bed1637c1b920c2b0f..d35798a58db607f4b979e34ac2c00ae1f7bef8bf 100644 --- a/crates/vector_store/src/vector_store.rs +++ b/crates/vector_store/src/vector_store.rs @@ -80,11 +80,10 @@ pub fn init( let vector_store = VectorStore::new( fs, db_file_path, - Arc::new(embedding::DummyEmbeddings {}), - // Arc::new(OpenAIEmbeddings { - // client: http_client, - // executor: cx.background(), - // }), + Arc::new(OpenAIEmbeddings { + client: http_client, + executor: cx.background(), + }), language_registry, cx.clone(), ) From 036d3e811aa48bf62368dfcd6c9e5812bc16398f Mon Sep 17 00:00:00 2001 From: Sergey Onufrienko Date: Thu, 13 Jul 2023 22:09:31 +0100 Subject: [PATCH 007/160] feat: add low, high, range and scaling --- styles/src/theme/create_theme.ts | 33 ++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/styles/src/theme/create_theme.ts b/styles/src/theme/create_theme.ts index 3f4a0766547534d39e43546c722cd2179ce628b1..e0da345bc52a81a8519f5f36d1d7ab76d9a6ff4c 100644 --- a/styles/src/theme/create_theme.ts +++ b/styles/src/theme/create_theme.ts @@ -70,11 +70,14 @@ export interface Players { "7": Player } -export interface ColorFamily { - range: ColorFamilyRange -} +export type ColorFamily = Partial<{ [K in keyof RampSet]: ColorFamilyRange }> -export type ColorFamilyRange = Partial<{ [K in keyof RampSet]: number }> +export interface ColorFamilyRange { + low: number + high: number + range: number + scaling_value: number +} export interface Shadow { blur: number @@ -169,9 +172,7 @@ export function create_theme(theme: ThemeConfig): Theme { "7": player(ramps.yellow), } - const color_family = { - range: build_color_family(ramps) - } + const color_family = build_color_family(ramps) return { name, @@ -199,11 +200,23 @@ function player(ramp: Scale): Player { } } -function build_color_family(ramps: RampSet): ColorFamilyRange { - const color_family: ColorFamilyRange = {} +function build_color_family(ramps: RampSet): ColorFamily { + const color_family: ColorFamily = {} for (const ramp in ramps) { - color_family[ramp as keyof RampSet] = chroma(ramps[ramp as keyof RampSet](0.5)).luminance() + const ramp_value = ramps[ramp as keyof RampSet] + + const lightnessValues = [ramp_value(0).get('hsl.l') * 100, ramp_value(1).get('hsl.l') * 100] + const low = Math.min(...lightnessValues) + const high = Math.max(...lightnessValues) + const range = high - low + + color_family[ramp as keyof RampSet] = { + low, + high, + range, + scaling_value: 100 / range, + } } return color_family From b38e3b804c7e1124c8a41ac3fb471c305e522639 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Thu, 13 Jul 2023 18:14:44 -0400 Subject: [PATCH 008/160] remove reindexing subscription, and add status methods for vector store Co-authored-by: maxbrunsfeld --- Cargo.lock | 1 + crates/vector_store/Cargo.toml | 1 + crates/vector_store/src/modal.rs | 2 +- crates/vector_store/src/vector_store.rs | 379 +++++++----------- crates/vector_store/src/vector_store_tests.rs | 78 +++- 5 files changed, 208 insertions(+), 253 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4359659a53bad7b2b33bca0fa9e41cd6ae09b11f..239aa6a302ded4391422e1c2d8752236f4019bb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8493,6 +8493,7 @@ dependencies = [ "lazy_static", "log", "matrixmultiply", + "parking_lot 0.11.2", "picker", "project", "rand 0.8.5", diff --git a/crates/vector_store/Cargo.toml b/crates/vector_store/Cargo.toml index 8e1dea59fd8c0fe890291388fccaa9ac7cd3443d..bac9cdedfafc4567f24b7502e0f9ea9e4d0e71e3 100644 --- a/crates/vector_store/Cargo.toml +++ b/crates/vector_store/Cargo.toml @@ -33,6 +33,7 @@ async-trait.workspace = true bincode = "1.3.3" matrixmultiply = "0.3.7" tiktoken-rs = "0.5.0" +parking_lot.workspace = true rand.workspace = true schemars.workspace = true diff --git a/crates/vector_store/src/modal.rs b/crates/vector_store/src/modal.rs index b797a208062ee623db11fbbfe40948847639465f..2981fa4e73ef77ce3b54b68da9b177452f6d245e 100644 --- a/crates/vector_store/src/modal.rs +++ b/crates/vector_store/src/modal.rs @@ -124,7 +124,7 @@ impl PickerDelegate for SemanticSearchDelegate { if let Some(retrieved) = retrieved_cached.log_err() { if !retrieved { let task = vector_store.update(&mut cx, |store, cx| { - store.search(project.clone(), query.to_string(), 10, cx) + store.search_project(project.clone(), query.to_string(), 10, cx) }); if let Some(results) = task.await.log_err() { diff --git a/crates/vector_store/src/vector_store.rs b/crates/vector_store/src/vector_store.rs index d35798a58db607f4b979e34ac2c00ae1f7bef8bf..3f7ab5c6cd1b2e0296ee560071377a84a6c527db 100644 --- a/crates/vector_store/src/vector_store.rs +++ b/crates/vector_store/src/vector_store.rs @@ -18,15 +18,19 @@ use gpui::{ }; use language::{Language, LanguageRegistry}; use modal::{SemanticSearch, SemanticSearchDelegate, Toggle}; +use parking_lot::Mutex; use parsing::{CodeContextRetriever, Document}; -use project::{Fs, PathChange, Project, ProjectEntryId, WorktreeId}; +use project::{Fs, Project, WorktreeId}; use smol::channel; use std::{ - collections::HashMap, + collections::{HashMap, HashSet}, ops::Range, path::{Path, PathBuf}, - sync::Arc, - time::{Duration, Instant, SystemTime}, + sync::{ + atomic::{self, AtomicUsize}, + Arc, Weak, + }, + time::{Instant, SystemTime}, }; use util::{ channel::{ReleaseChannel, RELEASE_CHANNEL, RELEASE_CHANNEL_NAME}, @@ -99,7 +103,7 @@ pub fn init( let project = workspace.read(cx).project().clone(); if project.read(cx).is_local() { vector_store.update(cx, |store, cx| { - store.add_project(project, cx).detach(); + store.index_project(project, cx).detach(); }); } } @@ -124,13 +128,20 @@ pub struct VectorStore { _embed_batch_task: Task<()>, _batch_files_task: Task<()>, _parsing_files_tasks: Vec>, + next_job_id: Arc, projects: HashMap, ProjectState>, } struct ProjectState { worktree_db_ids: Vec<(WorktreeId, i64)>, - pending_files: HashMap, - _subscription: gpui::Subscription, + outstanding_jobs: Arc>>, +} + +type JobId = usize; + +struct JobHandle { + id: JobId, + set: Weak>>, } impl ProjectState { @@ -157,54 +168,15 @@ impl ProjectState { } }) } - - fn update_pending_files(&mut self, pending_file: PendingFile, indexing_time: SystemTime) { - // If Pending File Already Exists, Replace it with the new one - // but keep the old indexing time - if let Some(old_file) = self - .pending_files - .remove(&pending_file.relative_path.clone()) - { - self.pending_files.insert( - pending_file.relative_path.clone(), - (pending_file, old_file.1), - ); - } else { - self.pending_files.insert( - pending_file.relative_path.clone(), - (pending_file, indexing_time), - ); - }; - } - - fn get_outstanding_files(&mut self) -> Vec { - let mut outstanding_files = vec![]; - let mut remove_keys = vec![]; - for key in self.pending_files.keys().into_iter() { - if let Some(pending_details) = self.pending_files.get(key) { - let (pending_file, index_time) = pending_details; - if index_time <= &SystemTime::now() { - outstanding_files.push(pending_file.clone()); - remove_keys.push(key.clone()); - } - } - } - - for key in remove_keys.iter() { - self.pending_files.remove(key); - } - - return outstanding_files; - } } -#[derive(Clone, Debug)] pub struct PendingFile { worktree_db_id: i64, relative_path: PathBuf, absolute_path: PathBuf, language: Arc, modified_time: SystemTime, + job_handle: JobHandle, } #[derive(Debug, Clone)] @@ -221,6 +193,7 @@ enum DbOperation { documents: Vec, path: PathBuf, mtime: SystemTime, + job_handle: JobHandle, }, Delete { worktree_id: i64, @@ -242,6 +215,7 @@ enum EmbeddingJob { path: PathBuf, mtime: SystemTime, documents: Vec, + job_handle: JobHandle, }, Flush, } @@ -274,9 +248,11 @@ impl VectorStore { documents, path, mtime, + job_handle, } => { db.insert_file(worktree_id, path, mtime, documents) .log_err(); + drop(job_handle) } DbOperation::Delete { worktree_id, path } => { db.delete_file(worktree_id, path).log_err(); @@ -298,7 +274,7 @@ impl VectorStore { // embed_tx/rx: Embed Batch and Send to Database let (embed_batch_tx, embed_batch_rx) = - channel::unbounded::, PathBuf, SystemTime)>>(); + channel::unbounded::, PathBuf, SystemTime, JobHandle)>>(); let _embed_batch_task = cx.background().spawn({ let db_update_tx = db_update_tx.clone(); let embedding_provider = embedding_provider.clone(); @@ -306,7 +282,7 @@ impl VectorStore { while let Ok(mut embeddings_queue) = embed_batch_rx.recv().await { // Construct Batch let mut batch_documents = vec![]; - for (_, documents, _, _) in embeddings_queue.iter() { + for (_, documents, _, _, _) in embeddings_queue.iter() { batch_documents .extend(documents.iter().map(|document| document.content.as_str())); } @@ -333,7 +309,7 @@ impl VectorStore { j += 1; } - for (worktree_id, documents, path, mtime) in + for (worktree_id, documents, path, mtime, job_handle) in embeddings_queue.into_iter() { for document in documents.iter() { @@ -350,6 +326,7 @@ impl VectorStore { documents, path, mtime, + job_handle, }) .await .unwrap(); @@ -372,9 +349,16 @@ impl VectorStore { worktree_id, path, mtime, + job_handle, } => { queue_len += &documents.len(); - embeddings_queue.push((worktree_id, documents, path, mtime)); + embeddings_queue.push(( + worktree_id, + documents, + path, + mtime, + job_handle, + )); queue_len >= EMBEDDINGS_BATCH_SIZE } EmbeddingJob::Flush => true, @@ -420,6 +404,7 @@ impl VectorStore { worktree_id: pending_file.worktree_db_id, path: pending_file.relative_path, mtime: pending_file.modified_time, + job_handle: pending_file.job_handle, documents, }) .unwrap(); @@ -439,6 +424,7 @@ impl VectorStore { embedding_provider, language_registry, db_update_tx, + next_job_id: Default::default(), parsing_files_tx, _db_update_task, _embed_batch_task, @@ -471,11 +457,11 @@ impl VectorStore { async move { rx.await? } } - fn add_project( + fn index_project( &mut self, project: ModelHandle, cx: &mut ModelContext, - ) -> Task> { + ) -> Task> { let worktree_scans_complete = project .read(cx) .worktrees(cx) @@ -494,21 +480,16 @@ impl VectorStore { }) .collect::>(); - let fs = self.fs.clone(); let language_registry = self.language_registry.clone(); - let database_url = self.database_url.clone(); let db_update_tx = self.db_update_tx.clone(); let parsing_files_tx = self.parsing_files_tx.clone(); + let next_job_id = self.next_job_id.clone(); cx.spawn(|this, mut cx| async move { futures::future::join_all(worktree_scans_complete).await; let worktree_db_ids = futures::future::join_all(worktree_db_ids).await; - if let Some(db_directory) = database_url.parent() { - fs.create_dir(db_directory).await.log_err(); - } - let worktrees = project.read_with(&cx, |project, cx| { project .worktrees(cx) @@ -516,109 +497,115 @@ impl VectorStore { .collect::>() }); - let mut worktree_file_times = HashMap::new(); + let mut worktree_file_mtimes = HashMap::new(); let mut db_ids_by_worktree_id = HashMap::new(); for (worktree, db_id) in worktrees.iter().zip(worktree_db_ids) { let db_id = db_id?; db_ids_by_worktree_id.insert(worktree.id(), db_id); - worktree_file_times.insert( + worktree_file_mtimes.insert( worktree.id(), this.read_with(&cx, |this, _| this.get_file_mtimes(db_id)) .await?, ); } - cx.background() - .spawn({ - let db_ids_by_worktree_id = db_ids_by_worktree_id.clone(); - let db_update_tx = db_update_tx.clone(); - let language_registry = language_registry.clone(); - let parsing_files_tx = parsing_files_tx.clone(); - async move { - let t0 = Instant::now(); - for worktree in worktrees.into_iter() { - let mut file_mtimes = - worktree_file_times.remove(&worktree.id()).unwrap(); - for file in worktree.files(false, 0) { - let absolute_path = worktree.absolutize(&file.path); - - if let Ok(language) = language_registry - .language_for_file(&absolute_path, None) - .await - { - if language - .grammar() - .and_then(|grammar| grammar.embedding_config.as_ref()) - .is_none() - { - continue; - } - - let path_buf = file.path.to_path_buf(); - let stored_mtime = file_mtimes.remove(&file.path.to_path_buf()); - let already_stored = stored_mtime - .map_or(false, |existing_mtime| { - existing_mtime == file.mtime - }); - - if !already_stored { - log::trace!("sending for parsing: {:?}", path_buf); - parsing_files_tx - .try_send(PendingFile { - worktree_db_id: db_ids_by_worktree_id - [&worktree.id()], - relative_path: path_buf, - absolute_path, - language, - modified_time: file.mtime, - }) - .unwrap(); - } - } - } - for file in file_mtimes.keys() { - db_update_tx - .try_send(DbOperation::Delete { - worktree_id: db_ids_by_worktree_id[&worktree.id()], - path: file.to_owned(), - }) - .unwrap(); - } - } - log::trace!( - "parsing worktree completed in {:?}", - t0.elapsed().as_millis() - ); - } - }) - .detach(); - // let mut pending_files: Vec<(PathBuf, ((i64, PathBuf, Arc, SystemTime), SystemTime))> = vec![]; - this.update(&mut cx, |this, cx| { - // The below is managing for updated on save - // Currently each time a file is saved, this code is run, and for all the files that were changed, if the current time is - // greater than the previous embedded time by the REINDEXING_DELAY variable, we will send the file off to be indexed. - let _subscription = cx.subscribe(&project, |this, project, event, cx| { - if let project::Event::WorktreeUpdatedEntries(worktree_id, changes) = event { - this.project_entries_changed(project, changes.clone(), cx, worktree_id); - } - }); - + let outstanding_jobs = Arc::new(Mutex::new(HashSet::new())); + this.update(&mut cx, |this, _| { this.projects.insert( project.downgrade(), ProjectState { - pending_files: HashMap::new(), - worktree_db_ids: db_ids_by_worktree_id.into_iter().collect(), - _subscription, + worktree_db_ids: db_ids_by_worktree_id + .iter() + .map(|(a, b)| (*a, *b)) + .collect(), + outstanding_jobs: outstanding_jobs.clone(), }, ); }); - anyhow::Ok(()) + cx.background() + .spawn(async move { + let mut count = 0; + let t0 = Instant::now(); + for worktree in worktrees.into_iter() { + let mut file_mtimes = worktree_file_mtimes.remove(&worktree.id()).unwrap(); + for file in worktree.files(false, 0) { + let absolute_path = worktree.absolutize(&file.path); + + if let Ok(language) = language_registry + .language_for_file(&absolute_path, None) + .await + { + if language + .grammar() + .and_then(|grammar| grammar.embedding_config.as_ref()) + .is_none() + { + continue; + } + + let path_buf = file.path.to_path_buf(); + let stored_mtime = file_mtimes.remove(&file.path.to_path_buf()); + let already_stored = stored_mtime + .map_or(false, |existing_mtime| existing_mtime == file.mtime); + + if !already_stored { + log::trace!("sending for parsing: {:?}", path_buf); + count += 1; + let job_id = next_job_id.fetch_add(1, atomic::Ordering::SeqCst); + let job_handle = JobHandle { + id: job_id, + set: Arc::downgrade(&outstanding_jobs), + }; + outstanding_jobs.lock().insert(job_id); + parsing_files_tx + .try_send(PendingFile { + worktree_db_id: db_ids_by_worktree_id[&worktree.id()], + relative_path: path_buf, + absolute_path, + language, + job_handle, + modified_time: file.mtime, + }) + .unwrap(); + } + } + } + for file in file_mtimes.keys() { + db_update_tx + .try_send(DbOperation::Delete { + worktree_id: db_ids_by_worktree_id[&worktree.id()], + path: file.to_owned(), + }) + .unwrap(); + } + } + log::trace!( + "parsing worktree completed in {:?}", + t0.elapsed().as_millis() + ); + + Ok(count) + }) + .await }) } - pub fn search( + pub fn remaining_files_to_index_for_project( + &self, + project: &ModelHandle, + ) -> Option { + Some( + self.projects + .get(&project.downgrade())? + .outstanding_jobs + .lock() + .len(), + ) + } + + pub fn search_project( &mut self, project: ModelHandle, phrase: String, @@ -682,110 +669,16 @@ impl VectorStore { }) }) } - - fn project_entries_changed( - &mut self, - project: ModelHandle, - changes: Arc<[(Arc, ProjectEntryId, PathChange)]>, - cx: &mut ModelContext<'_, VectorStore>, - worktree_id: &WorktreeId, - ) -> Option<()> { - let reindexing_delay = settings::get::(cx).reindexing_delay_seconds; - - let worktree = project - .read(cx) - .worktree_for_id(worktree_id.clone(), cx)? - .read(cx) - .snapshot(); - - let worktree_db_id = self - .projects - .get(&project.downgrade())? - .db_id_for_worktree_id(worktree.id())?; - let file_mtimes = self.get_file_mtimes(worktree_db_id); - - let language_registry = self.language_registry.clone(); - - cx.spawn(|this, mut cx| async move { - let file_mtimes = file_mtimes.await.log_err()?; - - for change in changes.into_iter() { - let change_path = change.0.clone(); - let absolute_path = worktree.absolutize(&change_path); - - // Skip if git ignored or symlink - if let Some(entry) = worktree.entry_for_id(change.1) { - if entry.is_ignored || entry.is_symlink || entry.is_external { - continue; - } - } - - match change.2 { - PathChange::Removed => this.update(&mut cx, |this, _| { - this.db_update_tx - .try_send(DbOperation::Delete { - worktree_id: worktree_db_id, - path: absolute_path, - }) - .unwrap(); - }), - _ => { - if let Ok(language) = language_registry - .language_for_file(&change_path.to_path_buf(), None) - .await - { - if language - .grammar() - .and_then(|grammar| grammar.embedding_config.as_ref()) - .is_none() - { - continue; - } - - let modified_time = - change_path.metadata().log_err()?.modified().log_err()?; - - let existing_time = file_mtimes.get(&change_path.to_path_buf()); - let already_stored = existing_time - .map_or(false, |existing_time| &modified_time != existing_time); - - if !already_stored { - this.update(&mut cx, |this, _| { - let reindex_time = modified_time - + Duration::from_secs(reindexing_delay as u64); - - let project_state = - this.projects.get_mut(&project.downgrade())?; - project_state.update_pending_files( - PendingFile { - relative_path: change_path.to_path_buf(), - absolute_path, - modified_time, - worktree_db_id, - language: language.clone(), - }, - reindex_time, - ); - - for file in project_state.get_outstanding_files() { - this.parsing_files_tx.try_send(file).unwrap(); - } - Some(()) - }); - } - } - } - } - } - - Some(()) - }) - .detach(); - - Some(()) - } } impl Entity for VectorStore { type Event = (); } + +impl Drop for JobHandle { + fn drop(&mut self) { + if let Some(set) = self.set.upgrade() { + set.lock().remove(&self.id); + } + } +} diff --git a/crates/vector_store/src/vector_store_tests.rs b/crates/vector_store/src/vector_store_tests.rs index ccdd9fdaf07605b36f025d3a4bad63a3a2f516c2..de82bc2f482351166d4f57d37c0a82087dbaa662 100644 --- a/crates/vector_store/src/vector_store_tests.rs +++ b/crates/vector_store/src/vector_store_tests.rs @@ -9,11 +9,17 @@ use anyhow::Result; use async_trait::async_trait; use gpui::{Task, TestAppContext}; use language::{Language, LanguageConfig, LanguageRegistry}; -use project::{project_settings::ProjectSettings, FakeFs, Project}; +use project::{project_settings::ProjectSettings, FakeFs, Fs, Project}; use rand::{rngs::StdRng, Rng}; use serde_json::json; use settings::SettingsStore; -use std::{path::Path, sync::Arc}; +use std::{ + path::Path, + sync::{ + atomic::{self, AtomicUsize}, + Arc, + }, +}; use unindent::Unindent; #[ctor::ctor] @@ -62,29 +68,37 @@ async fn test_vector_store(cx: &mut TestAppContext) { let db_dir = tempdir::TempDir::new("vector-store").unwrap(); let db_path = db_dir.path().join("db.sqlite"); + let embedding_provider = Arc::new(FakeEmbeddingProvider::default()); let store = VectorStore::new( fs.clone(), db_path, - Arc::new(FakeEmbeddingProvider), + embedding_provider.clone(), languages, cx.to_async(), ) .await .unwrap(); - let project = Project::test(fs, ["/the-root".as_ref()], cx).await; + let project = Project::test(fs.clone(), ["/the-root".as_ref()], cx).await; let worktree_id = project.read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() }); - store - .update(cx, |store, cx| store.add_project(project.clone(), cx)) + let file_count = store + .update(cx, |store, cx| store.index_project(project.clone(), cx)) .await .unwrap(); + assert_eq!(file_count, 2); cx.foreground().run_until_parked(); + store.update(cx, |store, _cx| { + assert_eq!( + store.remaining_files_to_index_for_project(&project), + Some(0) + ); + }); let search_results = store .update(cx, |store, cx| { - store.search(project.clone(), "aaaa".to_string(), 5, cx) + store.search_project(project.clone(), "aaaa".to_string(), 5, cx) }) .await .unwrap(); @@ -92,10 +106,45 @@ async fn test_vector_store(cx: &mut TestAppContext) { assert_eq!(search_results[0].byte_range.start, 0); assert_eq!(search_results[0].name, "aaa"); assert_eq!(search_results[0].worktree_id, worktree_id); + + fs.save( + "/the-root/src/file2.rs".as_ref(), + &" + fn dddd() { println!(\"ddddd!\"); } + struct pqpqpqp {} + " + .unindent() + .into(), + Default::default(), + ) + .await + .unwrap(); + + cx.foreground().run_until_parked(); + + let prev_embedding_count = embedding_provider.embedding_count(); + let file_count = store + .update(cx, |store, cx| store.index_project(project.clone(), cx)) + .await + .unwrap(); + assert_eq!(file_count, 1); + + cx.foreground().run_until_parked(); + store.update(cx, |store, _cx| { + assert_eq!( + store.remaining_files_to_index_for_project(&project), + Some(0) + ); + }); + + assert_eq!( + embedding_provider.embedding_count() - prev_embedding_count, + 2 + ); } #[gpui::test] -async fn test_code_context_retrieval(cx: &mut TestAppContext) { +async fn test_code_context_retrieval() { let language = rust_lang(); let mut retriever = CodeContextRetriever::new(); @@ -181,11 +230,22 @@ fn test_dot_product(mut rng: StdRng) { } } -struct FakeEmbeddingProvider; +#[derive(Default)] +struct FakeEmbeddingProvider { + embedding_count: AtomicUsize, +} + +impl FakeEmbeddingProvider { + fn embedding_count(&self) -> usize { + self.embedding_count.load(atomic::Ordering::SeqCst) + } +} #[async_trait] impl EmbeddingProvider for FakeEmbeddingProvider { async fn embed_batch(&self, spans: Vec<&str>) -> Result>> { + self.embedding_count + .fetch_add(spans.len(), atomic::Ordering::SeqCst); Ok(spans .iter() .map(|span| { From 3a625d15d30ba26c4500f88de7a16dc980bc0019 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Fri, 14 Jul 2023 11:33:49 -0400 Subject: [PATCH 009/160] update c embedding query for preceding comments --- crates/zed/src/languages/c/embedding.scm | 74 +++++++++++++----------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/crates/zed/src/languages/c/embedding.scm b/crates/zed/src/languages/c/embedding.scm index cd1915f62bb5c27f7617bde91327a78129564511..0178abeb18374771967c09c93b9fcfc504e1e556 100644 --- a/crates/zed/src/languages/c/embedding.scm +++ b/crates/zed/src/languages/c/embedding.scm @@ -1,39 +1,43 @@ -(declaration - (type_qualifier)? @context - type: (_)? @context - declarator: [ - (function_declarator - declarator: (_) @name) - (pointer_declarator - "*" @context - declarator: (function_declarator - declarator: (_) @name)) - (pointer_declarator - "*" @context - declarator: (pointer_declarator - "*" @context +( + (comment)* @context + . + (declaration + declarator: [ + (function_declarator + declarator: (_) @name) + (pointer_declarator + "*" @name declarator: (function_declarator - declarator: (_) @name))) - ] -) @item + declarator: (_) @name)) + (pointer_declarator + "*" @name + declarator: (pointer_declarator + "*" @name + declarator: (function_declarator + declarator: (_) @name))) + ] + ) @item + ) -(function_definition - (type_qualifier)? @context - type: (_)? @context - declarator: [ - (function_declarator - declarator: (_) @name - ) - (pointer_declarator - "*" @context - declarator: (function_declarator +( + (comment)* @context + . + (function_definition + declarator: [ + (function_declarator declarator: (_) @name - )) - (pointer_declarator - "*" @context - declarator: (pointer_declarator - "*" @context + ) + (pointer_declarator + "*" @name declarator: (function_declarator - declarator: (_) @name))) - ] -) @item + declarator: (_) @name + )) + (pointer_declarator + "*" @name + declarator: (pointer_declarator + "*" @name + declarator: (function_declarator + declarator: (_) @name))) + ] + ) @item + ) From d4971e9eadebc9e629ca413a0df309230f2d14fc Mon Sep 17 00:00:00 2001 From: KCaverly Date: Fri, 14 Jul 2023 13:47:10 -0400 Subject: [PATCH 010/160] update typescript parsing to manage for leading tsdoc comments --- crates/vector_store/src/parsing.rs | 8 +- .../src/languages/typescript/embedding.scm | 113 +++++++++--------- 2 files changed, 62 insertions(+), 59 deletions(-) diff --git a/crates/vector_store/src/parsing.rs b/crates/vector_store/src/parsing.rs index 8d6e03d6eb29d524db23848adfa15a8ac6b4b164..4ce8b6763a33cae8253a1e6518cbc53b19eff030 100644 --- a/crates/vector_store/src/parsing.rs +++ b/crates/vector_store/src/parsing.rs @@ -51,6 +51,7 @@ impl CodeContextRetriever { let mut documents = Vec::new(); // Iterate through query matches + let mut name_ranges: Vec> = vec![]; for mat in self.cursor.matches( &embedding_config.query, tree.root_node(), @@ -65,7 +66,12 @@ impl CodeContextRetriever { byte_range = Some(capture.node.byte_range()); item = content.get(capture.node.byte_range()); } else if capture.index == embedding_config.name_capture_ix { - if let Some(name_content) = content.get(capture.node.byte_range()) { + let name_range = capture.node.byte_range(); + if name_ranges.contains(&name_range) { + continue; + } + name_ranges.push(name_range.clone()); + if let Some(name_content) = content.get(name_range.clone()) { name.push(name_content); } } diff --git a/crates/zed/src/languages/typescript/embedding.scm b/crates/zed/src/languages/typescript/embedding.scm index f261a0a56577176108dc1ef2b5cf6de3569a0531..d850f9b82307fc9bd0560c866ca149cffe5a1f5e 100644 --- a/crates/zed/src/languages/typescript/embedding.scm +++ b/crates/zed/src/languages/typescript/embedding.scm @@ -1,59 +1,56 @@ -; (internal_module -; "namespace" @context -; name: (_) @name) @item - -(enum_declaration - "enum" @context - name: (_) @name) @item - -; (type_alias_declaration -; "type" @context -; name: (_) @name) @item - -(function_declaration - "async"? @context - "function" @context - name: (_) @name) @item - -(interface_declaration - "interface" @context - name: (_) @name) @item - -; (export_statement -; (lexical_declaration -; ["let" "const"] @context -; (variable_declarator -; name: (_) @name) @item)) - -(program - (lexical_declaration - ["let" "const"] @context - (variable_declarator - name: (_) @name) @item)) - -(class_declaration - "class" @context - name: (_) @name) @item - -(method_definition +( + (comment)* @context + . + (enum_declaration + "enum" @context + name: (_) @name) @item + ) + +( + (comment)* @context + . [ - "get" - "set" - "async" - "*" - "readonly" - "static" - (override_modifier) - (accessibility_modifier) - ]* @context - name: (_) @name) @item - -; (public_field_definition -; [ -; "declare" -; "readonly" -; "abstract" -; "static" -; (accessibility_modifier) -; ]* @context -; name: (_) @name) @item + (export_statement + (function_declaration + "async"? @name + "function" @name + name: (_) @name) + ) @item + (function_declaration + "async"? @name + "function" @name + name: (_) @name) @item + ]) + +( + (comment)* @context + . + (interface_declaration + "interface" @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (class_declaration + "class" @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (method_definition + [ + "get" + "set" + "async" + "*" + "readonly" + "static" + (override_modifier) + (accessibility_modifier) + ]* @name + name: (_) @name) @item + ) From 2dae42b1ba49b4e10fe13826674610774078454f Mon Sep 17 00:00:00 2001 From: KCaverly Date: Fri, 14 Jul 2023 14:25:08 -0400 Subject: [PATCH 011/160] update embedding query for tsx to accomodate for leading comments --- crates/zed/src/languages/tsx/embedding.scm | 83 ++++++++++++++-------- 1 file changed, 52 insertions(+), 31 deletions(-) diff --git a/crates/zed/src/languages/tsx/embedding.scm b/crates/zed/src/languages/tsx/embedding.scm index 305f634e04ba245115907c1f113fe0c64cab1143..1c47a5a238ff9d944dc321b4eb10b0e56d8a6221 100644 --- a/crates/zed/src/languages/tsx/embedding.scm +++ b/crates/zed/src/languages/tsx/embedding.scm @@ -1,35 +1,56 @@ -(enum_declaration - "enum" @context - name: (_) @name) @item +( + (comment)* @context + . + (enum_declaration + "enum" @context + name: (_) @name) @item + ) -(function_declaration - "async"? @context - "function" @context - name: (_) @name) @item - -(interface_declaration - "interface" @context - name: (_) @name) @item +( + (comment)* @context + . + [ + (export_statement + (function_declaration + "async"? @name + "function" @name + name: (_) @name) + ) @item + (function_declaration + "async"? @name + "function" @name + name: (_) @name) @item + ]) -(program - (lexical_declaration - ["let" "const"] @context - (variable_declarator - name: (_) @name) @item)) +( + (comment)* @context + . + (interface_declaration + "interface" @name + name: (_) @name) @item + ) -(class_declaration - "class" @context - name: (_) @name) @item +( + (comment)* @context + . + (class_declaration + "class" @name + name: (_) @name) @item + ) -(method_definition - [ - "get" - "set" - "async" - "*" - "readonly" - "static" - (override_modifier) - (accessibility_modifier) - ]* @context - name: (_) @name) @item +( + (comment)* @context + . + (method_definition + [ + "get" + "set" + "async" + "*" + "readonly" + "static" + (override_modifier) + (accessibility_modifier) + ]* @name + name: (_) @name) @item + ) From 4bece54655980ac9c2f6ec5266e9bfc9306cc422 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 17 Jul 2023 09:22:37 -0400 Subject: [PATCH 012/160] update jsx family of languages for preceeding comments and nested exports --- Cargo.lock | 2 + crates/vector_store/Cargo.toml | 5 +- crates/vector_store/src/vector_store_tests.rs | 242 +++++++++++++++++- .../src/languages/javascript/embedding.scm | 139 ++++++---- crates/zed/src/languages/tsx/embedding.scm | 85 ++++-- .../src/languages/typescript/embedding.scm | 85 ++++-- 6 files changed, 458 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 239aa6a302ded4391422e1c2d8752236f4019bb3..b6049e611ed0c72a0fc13d822545dc994d80af4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8508,7 +8508,9 @@ dependencies = [ "theme", "tiktoken-rs 0.5.0", "tree-sitter", + "tree-sitter-javascript", "tree-sitter-rust", + "tree-sitter-typescript 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)", "unindent", "util", "workspace", diff --git a/crates/vector_store/Cargo.toml b/crates/vector_store/Cargo.toml index bac9cdedfafc4567f24b7502e0f9ea9e4d0e71e3..6b2e77e904016eb9e27584e8fc4e9ede71134d0a 100644 --- a/crates/vector_store/Cargo.toml +++ b/crates/vector_store/Cargo.toml @@ -44,10 +44,13 @@ project = { path = "../project", features = ["test-support"] } rpc = { path = "../rpc", features = ["test-support"] } workspace = { path = "../workspace", features = ["test-support"] } settings = { path = "../settings", features = ["test-support"]} -tree-sitter-rust = "*" rand.workspace = true unindent.workspace = true tempdir.workspace = true ctor.workspace = true env_logger.workspace = true + +tree-sitter-javascript = "*" +tree-sitter-typescript = "*" +tree-sitter-rust = "*" diff --git a/crates/vector_store/src/vector_store_tests.rs b/crates/vector_store/src/vector_store_tests.rs index de82bc2f482351166d4f57d37c0a82087dbaa662..76465b1aaf95ef98b2305e35dbead3628bc461ed 100644 --- a/crates/vector_store/src/vector_store_tests.rs +++ b/crates/vector_store/src/vector_store_tests.rs @@ -144,7 +144,7 @@ async fn test_vector_store(cx: &mut TestAppContext) { } #[gpui::test] -async fn test_code_context_retrieval() { +async fn test_code_context_retrieval_rust() { let language = rust_lang(); let mut retriever = CodeContextRetriever::new(); @@ -200,6 +200,142 @@ async fn test_code_context_retrieval() { ); } +#[gpui::test] +async fn test_code_context_retrieval_javascript() { + let language = js_lang(); + let mut retriever = CodeContextRetriever::new(); + + let text = " +/* globals importScripts, backend */ +function _authorize() {} + +/** + * Sometimes the frontend build is way faster than backend. + */ +export async function authorizeBank() { + _authorize(pushModal, upgradingAccountId, {}); +} + +export class SettingsPage { + /* This is a test setting */ + constructor(page) { + this.page = page; + } +} + +/* This is a test comment */ +class TestClass {} + +/* Schema for editor_events in Clickhouse. */ +export interface ClickhouseEditorEvent { + installation_id: string + operation: string +} +"; + + let parsed_files = retriever + .parse_file(Path::new("foo.js"), &text, language) + .unwrap(); + + let test_documents = &[ + Document { + name: "function _authorize".into(), + range: text.find("function _authorize").unwrap()..(text.find("}").unwrap() + 1), + content: " + The below code snippet is from file 'foo.js' + + ```javascript + /* globals importScripts, backend */ + function _authorize() {} + ```" + .unindent(), + embedding: vec![], + }, + Document { + name: "async function authorizeBank".into(), + range: text.find("export async").unwrap()..224, + content: " + The below code snippet is from file 'foo.js' + + ```javascript + /** + * Sometimes the frontend build is way faster than backend. + */ + export async function authorizeBank() { + _authorize(pushModal, upgradingAccountId, {}); + } + ```" + .unindent(), + embedding: vec![], + }, + Document { + name: "class SettingsPage".into(), + range: 226..344, + content: " + The below code snippet is from file 'foo.js' + + ```javascript + export class SettingsPage { + /* This is a test setting */ + constructor(page) { + this.page = page; + } + } + ```" + .unindent(), + embedding: vec![], + }, + Document { + name: "constructor".into(), + range: 291..342, + content: " + The below code snippet is from file 'foo.js' + + ```javascript + /* This is a test setting */ + constructor(page) { + this.page = page; + } + ```" + .unindent(), + embedding: vec![], + }, + Document { + name: "class TestClass".into(), + range: 375..393, + content: " + The below code snippet is from file 'foo.js' + + ```javascript + /* This is a test comment */ + class TestClass {} + ```" + .unindent(), + embedding: vec![], + }, + Document { + name: "interface ClickhouseEditorEvent".into(), + range: 441..533, + content: " + The below code snippet is from file 'foo.js' + + ```javascript + /* Schema for editor_events in Clickhouse. */ + export interface ClickhouseEditorEvent { + installation_id: string + operation: string + } + ```" + .unindent(), + embedding: vec![], + }, + ]; + + for idx in 0..test_documents.len() { + assert_eq!(test_documents[idx], parsed_files[idx]); + } +} + #[gpui::test] fn test_dot_product(mut rng: StdRng) { assert_eq!(dot(&[1., 0., 0., 0., 0.], &[0., 1., 0., 0., 0.]), 0.); @@ -271,6 +407,110 @@ impl EmbeddingProvider for FakeEmbeddingProvider { } } +fn js_lang() -> Arc { + Arc::new( + Language::new( + LanguageConfig { + name: "Javascript".into(), + path_suffixes: vec!["js".into()], + ..Default::default() + }, + Some(tree_sitter_typescript::language_tsx()), + ) + .with_embedding_query( + &r#" + + ( + (comment)* @context + . + (export_statement + (function_declaration + "async"? @name + "function" @name + name: (_) @name)) @item + ) + + ( + (comment)* @context + . + (function_declaration + "async"? @name + "function" @name + name: (_) @name) @item + ) + + ( + (comment)* @context + . + (export_statement + (class_declaration + "class" @name + name: (_) @name)) @item + ) + + ( + (comment)* @context + . + (class_declaration + "class" @name + name: (_) @name) @item + ) + + ( + (comment)* @context + . + (method_definition + [ + "get" + "set" + "async" + "*" + "static" + ]* @name + name: (_) @name) @item + ) + + ( + (comment)* @context + . + (export_statement + (interface_declaration + "interface" @name + name: (_) @name)) @item + ) + + ( + (comment)* @context + . + (interface_declaration + "interface" @name + name: (_) @name) @item + ) + + ( + (comment)* @context + . + (export_statement + (enum_declaration + "enum" @name + name: (_) @name)) @item + ) + + ( + (comment)* @context + . + (enum_declaration + "enum" @name + name: (_) @name) @item + ) + + "# + .unindent(), + ) + .unwrap(), + ) +} + fn rust_lang() -> Arc { Arc::new( Language::new( diff --git a/crates/zed/src/languages/javascript/embedding.scm b/crates/zed/src/languages/javascript/embedding.scm index ec6eb5ab1a8be481bc7a9987056ce2d1cb7d2474..a2140400318db95a8d29074402ab2d212561a79b 100644 --- a/crates/zed/src/languages/javascript/embedding.scm +++ b/crates/zed/src/languages/javascript/embedding.scm @@ -1,56 +1,83 @@ -; (internal_module -; "namespace" @context -; name: (_) @name) @item - -(enum_declaration - "enum" @context - name: (_) @name) @item - -(function_declaration - "async"? @context - "function" @context - name: (_) @name) @item - -(interface_declaration - "interface" @context - name: (_) @name) @item - -; (program -; (export_statement -; (lexical_declaration -; ["let" "const"] @context -; (variable_declarator -; name: (_) @name) @item))) - -(program - (lexical_declaration - ["let" "const"] @context - (variable_declarator - name: (_) @name) @item)) - -(class_declaration - "class" @context - name: (_) @name) @item - -(method_definition - [ - "get" - "set" - "async" - "*" - "readonly" - "static" - (override_modifier) - (accessibility_modifier) - ]* @context - name: (_) @name) @item - -; (public_field_definition -; [ -; "declare" -; "readonly" -; "abstract" -; "static" -; (accessibility_modifier) -; ]* @context -; name: (_) @name) @item +( + (comment)* @context + . + (export_statement + (function_declaration + "async"? @name + "function" @name + name: (_) @name)) @item + ) + +( + (comment)* @context + . + (function_declaration + "async"? @name + "function" @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (export_statement + (class_declaration + "class" @name + name: (_) @name)) @item + ) + +( + (comment)* @context + . + (class_declaration + "class" @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (method_definition + [ + "get" + "set" + "async" + "*" + "static" + ]* @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (export_statement + (interface_declaration + "interface" @name + name: (_) @name)) @item + ) + +( + (comment)* @context + . + (interface_declaration + "interface" @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (export_statement + (enum_declaration + "enum" @name + name: (_) @name)) @item + ) + +( + (comment)* @context + . + (enum_declaration + "enum" @name + name: (_) @name) @item + ) diff --git a/crates/zed/src/languages/tsx/embedding.scm b/crates/zed/src/languages/tsx/embedding.scm index 1c47a5a238ff9d944dc321b4eb10b0e56d8a6221..4bb4fea254d0cf86f2fbb9d5c8f657e06238971f 100644 --- a/crates/zed/src/languages/tsx/embedding.scm +++ b/crates/zed/src/languages/tsx/embedding.scm @@ -1,33 +1,29 @@ ( (comment)* @context . - (enum_declaration - "enum" @context - name: (_) @name) @item + (export_statement + (function_declaration + "async"? @name + "function" @name + name: (_) @name)) @item ) ( (comment)* @context . - [ - (export_statement - (function_declaration - "async"? @name - "function" @name - name: (_) @name) - ) @item - (function_declaration - "async"? @name - "function" @name - name: (_) @name) @item - ]) + (function_declaration + "async"? @name + "function" @name + name: (_) @name) @item + ) ( (comment)* @context . - (interface_declaration - "interface" @name - name: (_) @name) @item + (export_statement + (class_declaration + "class" @name + name: (_) @name)) @item ) ( @@ -47,10 +43,57 @@ "set" "async" "*" - "readonly" "static" - (override_modifier) - (accessibility_modifier) ]* @name name: (_) @name) @item ) + +( + (comment)* @context + . + (export_statement + (interface_declaration + "interface" @name + name: (_) @name)) @item + ) + +( + (comment)* @context + . + (interface_declaration + "interface" @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (export_statement + (enum_declaration + "enum" @name + name: (_) @name)) @item + ) + +( + (comment)* @context + . + (enum_declaration + "enum" @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (export_statement + (type_alias_declaration + "type" @name + name: (_) @name)) @item + ) + +( + (comment)* @context + . + (type_alias_declaration + "type" @name + name: (_) @name) @item) diff --git a/crates/zed/src/languages/typescript/embedding.scm b/crates/zed/src/languages/typescript/embedding.scm index d850f9b82307fc9bd0560c866ca149cffe5a1f5e..4bb4fea254d0cf86f2fbb9d5c8f657e06238971f 100644 --- a/crates/zed/src/languages/typescript/embedding.scm +++ b/crates/zed/src/languages/typescript/embedding.scm @@ -1,33 +1,29 @@ ( (comment)* @context . - (enum_declaration - "enum" @context - name: (_) @name) @item + (export_statement + (function_declaration + "async"? @name + "function" @name + name: (_) @name)) @item ) ( (comment)* @context . - [ - (export_statement - (function_declaration - "async"? @name - "function" @name - name: (_) @name) - ) @item - (function_declaration - "async"? @name - "function" @name - name: (_) @name) @item - ]) + (function_declaration + "async"? @name + "function" @name + name: (_) @name) @item + ) ( (comment)* @context . - (interface_declaration - "interface" @name - name: (_) @name) @item + (export_statement + (class_declaration + "class" @name + name: (_) @name)) @item ) ( @@ -47,10 +43,57 @@ "set" "async" "*" - "readonly" "static" - (override_modifier) - (accessibility_modifier) ]* @name name: (_) @name) @item ) + +( + (comment)* @context + . + (export_statement + (interface_declaration + "interface" @name + name: (_) @name)) @item + ) + +( + (comment)* @context + . + (interface_declaration + "interface" @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (export_statement + (enum_declaration + "enum" @name + name: (_) @name)) @item + ) + +( + (comment)* @context + . + (enum_declaration + "enum" @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (export_statement + (type_alias_declaration + "type" @name + name: (_) @name)) @item + ) + +( + (comment)* @context + . + (type_alias_declaration + "type" @name + name: (_) @name) @item) From cf0dd09b5cdd9fd18c06d43a6774121cb86ce544 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 17 Jul 2023 10:04:32 -0400 Subject: [PATCH 013/160] update vector_store to accomodate for full file parsing for JSON, TOML and YAML files --- Cargo.lock | 14 ++++++++-- crates/vector_store/Cargo.toml | 2 +- crates/vector_store/src/parsing.rs | 26 +++++++++++++++++++ crates/vector_store/src/vector_store.rs | 11 ++++---- crates/vector_store/src/vector_store_tests.rs | 18 ++++++++++++- 5 files changed, 62 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6049e611ed0c72a0fc13d822545dc994d80af4e..afd40fd3081b0948d38afc37a6fd7e37066e625e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8134,6 +8134,16 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "tree-sitter-toml" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca517f578a98b23d20780247cc2688407fa81effad5b627a5a364ec3339b53e8" +dependencies = [ + "cc", + "tree-sitter", +] + [[package]] name = "tree-sitter-typescript" version = "0.20.2" @@ -8508,8 +8518,8 @@ dependencies = [ "theme", "tiktoken-rs 0.5.0", "tree-sitter", - "tree-sitter-javascript", "tree-sitter-rust", + "tree-sitter-toml 0.20.0", "tree-sitter-typescript 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)", "unindent", "util", @@ -9560,7 +9570,7 @@ dependencies = [ "tree-sitter-ruby", "tree-sitter-rust", "tree-sitter-scheme", - "tree-sitter-toml", + "tree-sitter-toml 0.5.1", "tree-sitter-typescript 0.20.2 (git+https://github.com/tree-sitter/tree-sitter-typescript?rev=5d20856f34315b068c41edaee2ac8a100081d259)", "tree-sitter-yaml", "unindent", diff --git a/crates/vector_store/Cargo.toml b/crates/vector_store/Cargo.toml index 6b2e77e904016eb9e27584e8fc4e9ede71134d0a..31119a1ba65363721593d68fa705b75763bafd58 100644 --- a/crates/vector_store/Cargo.toml +++ b/crates/vector_store/Cargo.toml @@ -51,6 +51,6 @@ tempdir.workspace = true ctor.workspace = true env_logger.workspace = true -tree-sitter-javascript = "*" tree-sitter-typescript = "*" tree-sitter-rust = "*" +tree-sitter-toml = "*" diff --git a/crates/vector_store/src/parsing.rs b/crates/vector_store/src/parsing.rs index 4ce8b6763a33cae8253a1e6518cbc53b19eff030..216ef1b5e11697519900dd4445234ebacb5ade21 100644 --- a/crates/vector_store/src/parsing.rs +++ b/crates/vector_store/src/parsing.rs @@ -13,6 +13,9 @@ pub struct Document { const CODE_CONTEXT_TEMPLATE: &str = "The below code snippet is from file ''\n\n```\n\n```"; +const ENTIRE_FILE_TEMPLATE: &str = + "The below snippet is from file ''\n\n```\n\n```"; +pub const PARSEABLE_ENTIRE_FILE_TYPES: [&str; 3] = ["TOML", "YAML", "JSON"]; pub struct CodeContextRetriever { pub parser: Parser, @@ -27,12 +30,35 @@ impl CodeContextRetriever { } } + fn _parse_entire_file( + &self, + relative_path: &Path, + language_name: Arc, + content: &str, + ) -> Result> { + let document_span = ENTIRE_FILE_TEMPLATE + .replace("", relative_path.to_string_lossy().as_ref()) + .replace("", language_name.as_ref()) + .replace("item", &content); + + Ok(vec![Document { + range: 0..content.len(), + content: document_span, + embedding: Vec::new(), + name: language_name.to_string(), + }]) + } + pub fn parse_file( &mut self, relative_path: &Path, content: &str, language: Arc, ) -> Result> { + if PARSEABLE_ENTIRE_FILE_TYPES.contains(&language.name().as_ref()) { + return self._parse_entire_file(relative_path, language.name(), &content); + } + let grammar = language .grammar() .ok_or_else(|| anyhow!("no grammar for language"))?; diff --git a/crates/vector_store/src/vector_store.rs b/crates/vector_store/src/vector_store.rs index 3f7ab5c6cd1b2e0296ee560071377a84a6c527db..0f55bd9e63f3a95ce113478a406f485600348973 100644 --- a/crates/vector_store/src/vector_store.rs +++ b/crates/vector_store/src/vector_store.rs @@ -19,7 +19,7 @@ use gpui::{ use language::{Language, LanguageRegistry}; use modal::{SemanticSearch, SemanticSearchDelegate, Toggle}; use parking_lot::Mutex; -use parsing::{CodeContextRetriever, Document}; +use parsing::{CodeContextRetriever, Document, PARSEABLE_ENTIRE_FILE_TYPES}; use project::{Fs, Project, WorktreeId}; use smol::channel; use std::{ @@ -537,10 +537,11 @@ impl VectorStore { .language_for_file(&absolute_path, None) .await { - if language - .grammar() - .and_then(|grammar| grammar.embedding_config.as_ref()) - .is_none() + if !PARSEABLE_ENTIRE_FILE_TYPES.contains(&language.name().as_ref()) + && language + .grammar() + .and_then(|grammar| grammar.embedding_config.as_ref()) + .is_none() { continue; } diff --git a/crates/vector_store/src/vector_store_tests.rs b/crates/vector_store/src/vector_store_tests.rs index 76465b1aaf95ef98b2305e35dbead3628bc461ed..84c9962493a78c4fe7a27fd74581863476440570 100644 --- a/crates/vector_store/src/vector_store_tests.rs +++ b/crates/vector_store/src/vector_store_tests.rs @@ -56,6 +56,9 @@ async fn test_vector_store(cx: &mut TestAppContext) { println!(\"bbbb!\"); } ".unindent(), + "file3.toml": " + ZZZZZZZ = 5 + ".unindent(), } }), ) @@ -63,7 +66,9 @@ async fn test_vector_store(cx: &mut TestAppContext) { let languages = Arc::new(LanguageRegistry::new(Task::ready(()))); let rust_language = rust_lang(); + let toml_language = toml_lang(); languages.add(rust_language); + languages.add(toml_language); let db_dir = tempdir::TempDir::new("vector-store").unwrap(); let db_path = db_dir.path().join("db.sqlite"); @@ -87,7 +92,7 @@ async fn test_vector_store(cx: &mut TestAppContext) { .update(cx, |store, cx| store.index_project(project.clone(), cx)) .await .unwrap(); - assert_eq!(file_count, 2); + assert_eq!(file_count, 3); cx.foreground().run_until_parked(); store.update(cx, |store, _cx| { assert_eq!( @@ -578,3 +583,14 @@ fn rust_lang() -> Arc { .unwrap(), ) } + +fn toml_lang() -> Arc { + Arc::new(Language::new( + LanguageConfig { + name: "TOML".into(), + path_suffixes: vec!["toml".into()], + ..Default::default() + }, + Some(tree_sitter_toml::language()), + )) +} From cb8762d855d27de1a422090fd4a1fabb8944152b Mon Sep 17 00:00:00 2001 From: Sergey Onufrienko Date: Mon, 17 Jul 2023 17:54:37 +0100 Subject: [PATCH 014/160] chore: add theme types docs --- docs/theme/generating-theme-types.md | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 docs/theme/generating-theme-types.md diff --git a/docs/theme/generating-theme-types.md b/docs/theme/generating-theme-types.md new file mode 100644 index 0000000000000000000000000000000000000000..efebc8d21df7e52dcc2c64b9a78602251b4847c5 --- /dev/null +++ b/docs/theme/generating-theme-types.md @@ -0,0 +1,29 @@ +[⬅ Back to Index](../index.md) + +# Generating Theme Types + + +## How to generate theme types: + +Run a script + +```bash +./script/build-theme-types +``` + +Types are generated in `styles/src/types/zed.ts` + + +## How it works: + +1. Rust types + + The `crates/theme` contains theme types. + Crate `schemars` used to generate a JSON schema from the theme structs. + Every struct that represent theme type has a `#[derive(JsonSchema)]` attribute. + + Task lotaked at `crates/xtask/src/main.rs` generates a JSON schema from the theme structs. + +2. TypeScript types + + Script `npm run build-types` from `styles` package generates TypeScript types from the JSON schema and saves them to `styles/src/types/zed.ts`. From 1362c5a3d9753702820bc615dcfd4a4b261f0a3f Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 17 Jul 2023 14:43:29 -0400 Subject: [PATCH 015/160] add embedding treesitter query for cpp --- Cargo.lock | 1 + crates/vector_store/Cargo.toml | 1 + crates/vector_store/src/vector_store_tests.rs | 312 ++++++++++++++++-- crates/zed/src/languages/cpp/embedding.scm | 61 ++++ 4 files changed, 347 insertions(+), 28 deletions(-) create mode 100644 crates/zed/src/languages/cpp/embedding.scm diff --git a/Cargo.lock b/Cargo.lock index afd40fd3081b0948d38afc37a6fd7e37066e625e..28a0e76d143086ba6af22d8c8d01a69de47872b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8518,6 +8518,7 @@ dependencies = [ "theme", "tiktoken-rs 0.5.0", "tree-sitter", + "tree-sitter-cpp", "tree-sitter-rust", "tree-sitter-toml 0.20.0", "tree-sitter-typescript 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crates/vector_store/Cargo.toml b/crates/vector_store/Cargo.toml index 31119a1ba65363721593d68fa705b75763bafd58..0009665e26a1b4e6b57c4aab061f6c457138fd2f 100644 --- a/crates/vector_store/Cargo.toml +++ b/crates/vector_store/Cargo.toml @@ -54,3 +54,4 @@ env_logger.workspace = true tree-sitter-typescript = "*" tree-sitter-rust = "*" tree-sitter-toml = "*" +tree-sitter-cpp = "*" diff --git a/crates/vector_store/src/vector_store_tests.rs b/crates/vector_store/src/vector_store_tests.rs index 84c9962493a78c4fe7a27fd74581863476440570..3a9e1748c54fd576fb1d0b49dada41a39842dad0 100644 --- a/crates/vector_store/src/vector_store_tests.rs +++ b/crates/vector_store/src/vector_store_tests.rs @@ -211,32 +211,33 @@ async fn test_code_context_retrieval_javascript() { let mut retriever = CodeContextRetriever::new(); let text = " -/* globals importScripts, backend */ -function _authorize() {} - -/** - * Sometimes the frontend build is way faster than backend. - */ -export async function authorizeBank() { - _authorize(pushModal, upgradingAccountId, {}); -} + /* globals importScripts, backend */ + function _authorize() {} + + /** + * Sometimes the frontend build is way faster than backend. + */ + export async function authorizeBank() { + _authorize(pushModal, upgradingAccountId, {}); + } -export class SettingsPage { - /* This is a test setting */ - constructor(page) { - this.page = page; - } -} + export class SettingsPage { + /* This is a test setting */ + constructor(page) { + this.page = page; + } + } -/* This is a test comment */ -class TestClass {} + /* This is a test comment */ + class TestClass {} -/* Schema for editor_events in Clickhouse. */ -export interface ClickhouseEditorEvent { - installation_id: string - operation: string -} -"; + /* Schema for editor_events in Clickhouse. */ + export interface ClickhouseEditorEvent { + installation_id: string + operation: string + } + " + .unindent(); let parsed_files = retriever .parse_file(Path::new("foo.js"), &text, language) @@ -258,7 +259,7 @@ export interface ClickhouseEditorEvent { }, Document { name: "async function authorizeBank".into(), - range: text.find("export async").unwrap()..224, + range: text.find("export async").unwrap()..223, content: " The below code snippet is from file 'foo.js' @@ -275,7 +276,7 @@ export interface ClickhouseEditorEvent { }, Document { name: "class SettingsPage".into(), - range: 226..344, + range: 225..343, content: " The below code snippet is from file 'foo.js' @@ -292,7 +293,7 @@ export interface ClickhouseEditorEvent { }, Document { name: "constructor".into(), - range: 291..342, + range: 290..341, content: " The below code snippet is from file 'foo.js' @@ -307,7 +308,7 @@ export interface ClickhouseEditorEvent { }, Document { name: "class TestClass".into(), - range: 375..393, + range: 374..392, content: " The below code snippet is from file 'foo.js' @@ -320,7 +321,7 @@ export interface ClickhouseEditorEvent { }, Document { name: "interface ClickhouseEditorEvent".into(), - range: 441..533, + range: 440..532, content: " The below code snippet is from file 'foo.js' @@ -341,6 +342,181 @@ export interface ClickhouseEditorEvent { } } +#[gpui::test] +async fn test_code_context_retrieval_cpp() { + let language = cpp_lang(); + let mut retriever = CodeContextRetriever::new(); + + let text = " + /** + * @brief Main function + * @returns 0 on exit + */ + int main() { return 0; } + + /** + * This is a test comment + */ + class MyClass { // The class + public: // Access specifier + int myNum; // Attribute (int variable) + string myString; // Attribute (string variable) + }; + + // This is a test comment + enum Color { red, green, blue }; + + /** This is a preceeding block comment + * This is the second line + */ + struct { // Structure declaration + int myNum; // Member (int variable) + string myString; // Member (string variable) + } myStructure; + + /** + * @brief Matrix class. + */ + template ::value || std::is_floating_point::value, + bool>::type> + class Matrix2 { + std::vector> _mat; + + public: + /** + * @brief Constructor + * @tparam Integer ensuring integers are being evaluated and not other + * data types. + * @param size denoting the size of Matrix as size x size + */ + template ::value, + Integer>::type> + explicit Matrix(const Integer size) { + for (size_t i = 0; i < size; ++i) { + _mat.emplace_back(std::vector(size, 0)); + } + } + }" + .unindent(); + + let parsed_files = retriever + .parse_file(Path::new("foo.cpp"), &text, language) + .unwrap(); + + let test_documents = &[ + Document { + name: "int main".into(), + range: 54..78, + content: " + The below code snippet is from file 'foo.cpp' + + ```cpp + /** + * @brief Main function + * @returns 0 on exit + */ + int main() { return 0; } + ```" + .unindent(), + embedding: vec![], + }, + Document { + name: "class MyClass".into(), + range: 112..295, + content: " + The below code snippet is from file 'foo.cpp' + + ```cpp + /** + * This is a test comment + */ + class MyClass { // The class + public: // Access specifier + int myNum; // Attribute (int variable) + string myString; // Attribute (string variable) + } + ```" + .unindent(), + embedding: vec![], + }, + Document { + name: "enum Color".into(), + range: 324..355, + content: " + The below code snippet is from file 'foo.cpp' + + ```cpp + // This is a test comment + enum Color { red, green, blue } + ```" + .unindent(), + embedding: vec![], + }, + Document { + name: "struct myStructure".into(), + range: 428..581, + content: " + The below code snippet is from file 'foo.cpp' + + ```cpp + /** This is a preceeding block comment + * This is the second line + */ + struct { // Structure declaration + int myNum; // Member (int variable) + string myString; // Member (string variable) + } myStructure; + ```" + .unindent(), + embedding: vec![], + }, + Document { + name: "class Matrix2".into(), + range: 613..1342, + content: " + The below code snippet is from file 'foo.cpp' + + ```cpp + /** + * @brief Matrix class. + */ + template ::value || std::is_floating_point::value, + bool>::type> + class Matrix2 { + std::vector> _mat; + + public: + /** + * @brief Constructor + * @tparam Integer ensuring integers are being evaluated and not other + * data types. + * @param size denoting the size of Matrix as size x size + */ + template ::value, + Integer>::type> + explicit Matrix(const Integer size) { + for (size_t i = 0; i < size; ++i) { + _mat.emplace_back(std::vector(size, 0)); + } + } + } + ```" + .unindent(), + embedding: vec![], + }, + ]; + + for idx in 0..test_documents.len() { + assert_eq!(test_documents[idx], parsed_files[idx]); + } +} + #[gpui::test] fn test_dot_product(mut rng: StdRng) { assert_eq!(dot(&[1., 0., 0., 0., 0.], &[0., 1., 0., 0., 0.]), 0.); @@ -594,3 +770,83 @@ fn toml_lang() -> Arc { Some(tree_sitter_toml::language()), )) } + +fn cpp_lang() -> Arc { + Arc::new( + Language::new( + LanguageConfig { + name: "CPP".into(), + path_suffixes: vec!["cpp".into()], + ..Default::default() + }, + Some(tree_sitter_cpp::language()), + ) + .with_embedding_query( + r#" + ( + (comment)* @context + . + (function_definition + (type_qualifier)? @name + type: (_)? @name + declarator: [ + (function_declarator + declarator: (_) @name) + (pointer_declarator + "*" @name + declarator: (function_declarator + declarator: (_) @name)) + (pointer_declarator + "*" @name + declarator: (pointer_declarator + "*" @name + declarator: (function_declarator + declarator: (_) @name))) + (reference_declarator + ["&" "&&"] @name + (function_declarator + declarator: (_) @name)) + ] + (type_qualifier)? @name) @item + ) + + ( + (comment)* @context + . + (template_declaration + (class_specifier + "class" @name + name: (_) @name) + ) @item + ) + + ( + (comment)* @context + . + (class_specifier + "class" @name + name: (_) @name) @item + ) + + ( + (comment)* @context + . + (enum_specifier + "enum" @name + name: (_) @name) @item + ) + + ( + (comment)* @context + . + (declaration + type: (struct_specifier + "struct" @name) + declarator: (_) @name) @item + ) + + "#, + ) + .unwrap(), + ) +} diff --git a/crates/zed/src/languages/cpp/embedding.scm b/crates/zed/src/languages/cpp/embedding.scm new file mode 100644 index 0000000000000000000000000000000000000000..bbd93f20dbdf6eddd097f49b7603ec5e0dc9bc59 --- /dev/null +++ b/crates/zed/src/languages/cpp/embedding.scm @@ -0,0 +1,61 @@ +( + (comment)* @context + . + (function_definition + (type_qualifier)? @name + type: (_)? @name + declarator: [ + (function_declarator + declarator: (_) @name) + (pointer_declarator + "*" @name + declarator: (function_declarator + declarator: (_) @name)) + (pointer_declarator + "*" @name + declarator: (pointer_declarator + "*" @name + declarator: (function_declarator + declarator: (_) @name))) + (reference_declarator + ["&" "&&"] @name + (function_declarator + declarator: (_) @name)) + ] + (type_qualifier)? @name) @item + ) + +( + (comment)* @context + . + (template_declaration + (class_specifier + "class" @name + name: (_) @name) + ) @item +) + +( + (comment)* @context + . + (class_specifier + "class" @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (enum_specifier + "enum" @name + name: (_) @name) @item + ) + +( + (comment)* @context + . + (declaration + type: (struct_specifier + "struct" @name) + declarator: (_) @name) @item +) From f0bf60fdedc56ec594a5e60f4442e8eb5a998c0b Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 17 Jul 2023 14:53:57 -0400 Subject: [PATCH 016/160] add css as a embeddable file type in which the entire file is embedded individually --- crates/vector_store/src/parsing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/vector_store/src/parsing.rs b/crates/vector_store/src/parsing.rs index 216ef1b5e11697519900dd4445234ebacb5ade21..663f0f473b63358496c8dcbc337aa7ccbe452c76 100644 --- a/crates/vector_store/src/parsing.rs +++ b/crates/vector_store/src/parsing.rs @@ -15,7 +15,7 @@ const CODE_CONTEXT_TEMPLATE: &str = "The below code snippet is from file ''\n\n```\n\n```"; const ENTIRE_FILE_TEMPLATE: &str = "The below snippet is from file ''\n\n```\n\n```"; -pub const PARSEABLE_ENTIRE_FILE_TYPES: [&str; 3] = ["TOML", "YAML", "JSON"]; +pub const PARSEABLE_ENTIRE_FILE_TYPES: [&str; 4] = ["TOML", "YAML", "JSON", "CSS"]; pub struct CodeContextRetriever { pub parser: Parser, From e630ff38c4f4099e4e9c8d926c6a75c3e364fc58 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 17 Jul 2023 16:29:25 -0400 Subject: [PATCH 017/160] add embedding treesitter queries for elixir --- Cargo.lock | 13 +- crates/vector_store/Cargo.toml | 1 + crates/vector_store/src/vector_store_tests.rs | 182 ++++++++++++++++++ crates/zed/src/languages/elixir/embedding.scm | 27 +++ 4 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 crates/zed/src/languages/elixir/embedding.scm diff --git a/Cargo.lock b/Cargo.lock index 28a0e76d143086ba6af22d8c8d01a69de47872b6..8fcca507d1fa47309793843f2268a87ff59a2e49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7982,6 +7982,16 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "tree-sitter-elixir" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a9916f3e1c80b3c8aab8582604e97e8720cb9b893489b347cf999f80f9d469e" +dependencies = [ + "cc", + "tree-sitter", +] + [[package]] name = "tree-sitter-elixir" version = "0.1.0" @@ -8519,6 +8529,7 @@ dependencies = [ "tiktoken-rs 0.5.0", "tree-sitter", "tree-sitter-cpp", + "tree-sitter-elixir 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tree-sitter-rust", "tree-sitter-toml 0.20.0", "tree-sitter-typescript 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -9558,7 +9569,7 @@ dependencies = [ "tree-sitter-c", "tree-sitter-cpp", "tree-sitter-css", - "tree-sitter-elixir", + "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=4ba9dab6e2602960d95b2b625f3386c27e08084e)", "tree-sitter-embedded-template", "tree-sitter-go", "tree-sitter-heex", diff --git a/crates/vector_store/Cargo.toml b/crates/vector_store/Cargo.toml index 0009665e26a1b4e6b57c4aab061f6c457138fd2f..6808f6c630ca8dda97fce819765995b78f3d2a9a 100644 --- a/crates/vector_store/Cargo.toml +++ b/crates/vector_store/Cargo.toml @@ -55,3 +55,4 @@ tree-sitter-typescript = "*" tree-sitter-rust = "*" tree-sitter-toml = "*" tree-sitter-cpp = "*" +tree-sitter-elixir = "*" diff --git a/crates/vector_store/src/vector_store_tests.rs b/crates/vector_store/src/vector_store_tests.rs index 3a9e1748c54fd576fb1d0b49dada41a39842dad0..d55dfcfc7151eb04efb5a33b119ae33b0875d86d 100644 --- a/crates/vector_store/src/vector_store_tests.rs +++ b/crates/vector_store/src/vector_store_tests.rs @@ -342,6 +342,143 @@ async fn test_code_context_retrieval_javascript() { } } +#[gpui::test] +async fn test_code_context_retrieval_elixir() { + let language = elixir_lang(); + let mut retriever = CodeContextRetriever::new(); + + let text = r#" +defmodule File.Stream do + @moduledoc """ + Defines a `File.Stream` struct returned by `File.stream!/3`. + + The following fields are public: + + * `path` - the file path + * `modes` - the file modes + * `raw` - a boolean indicating if bin functions should be used + * `line_or_bytes` - if reading should read lines or a given number of bytes + * `node` - the node the file belongs to + + """ + + defstruct path: nil, modes: [], line_or_bytes: :line, raw: true, node: nil + + @type t :: %__MODULE__{} + + @doc false + def __build__(path, modes, line_or_bytes) do + raw = :lists.keyfind(:encoding, 1, modes) == false + + modes = + case raw do + true -> + case :lists.keyfind(:read_ahead, 1, modes) do + {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] + {:read_ahead, _} -> [:raw | modes] + false -> [:raw, :read_ahead | modes] + end + + false -> + modes + end + + %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} + + end +"# + .unindent(); + + let parsed_files = retriever + .parse_file(Path::new("foo.ex"), &text, language) + .unwrap(); + + let test_documents = &[ + Document{ + name: "defmodule File.Stream".into(), + range: 0..1132, + content: r#" + The below code snippet is from file 'foo.ex' + + ```elixir + defmodule File.Stream do + @moduledoc """ + Defines a `File.Stream` struct returned by `File.stream!/3`. + + The following fields are public: + + * `path` - the file path + * `modes` - the file modes + * `raw` - a boolean indicating if bin functions should be used + * `line_or_bytes` - if reading should read lines or a given number of bytes + * `node` - the node the file belongs to + + """ + + defstruct path: nil, modes: [], line_or_bytes: :line, raw: true, node: nil + + @type t :: %__MODULE__{} + + @doc false + def __build__(path, modes, line_or_bytes) do + raw = :lists.keyfind(:encoding, 1, modes) == false + + modes = + case raw do + true -> + case :lists.keyfind(:read_ahead, 1, modes) do + {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] + {:read_ahead, _} -> [:raw | modes] + false -> [:raw, :read_ahead | modes] + end + + false -> + modes + end + + %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} + + end + ```"#.unindent(), + embedding: vec![], + }, + Document { + name: "def __build__".into(), + range: 574..1132, + content: r#" +The below code snippet is from file 'foo.ex' + +```elixir +@doc false +def __build__(path, modes, line_or_bytes) do + raw = :lists.keyfind(:encoding, 1, modes) == false + + modes = + case raw do + true -> + case :lists.keyfind(:read_ahead, 1, modes) do + {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] + {:read_ahead, _} -> [:raw | modes] + false -> [:raw, :read_ahead | modes] + end + + false -> + modes + end + + %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} + + end +```"# + .unindent(), + embedding: vec![], + }]; + + for idx in 0..test_documents.len() { + assert_eq!(test_documents[idx], parsed_files[idx]); + } +} + #[gpui::test] async fn test_code_context_retrieval_cpp() { let language = cpp_lang(); @@ -850,3 +987,48 @@ fn cpp_lang() -> Arc { .unwrap(), ) } + +fn elixir_lang() -> Arc { + Arc::new( + Language::new( + LanguageConfig { + name: "Elixir".into(), + path_suffixes: vec!["rs".into()], + ..Default::default() + }, + Some(tree_sitter_elixir::language()), + ) + .with_embedding_query( + r#" + ( + (unary_operator + operator: "@" + operand: (call + target: (identifier) @unary + (#match? @unary "^(doc)$")) + ) @context + . + (call + target: (identifier) @name + (arguments + [ + (identifier) @name + (call + target: (identifier) @name) + (binary_operator + left: (call + target: (identifier) @name) + operator: "when") + ]) + (#match? @name "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item + ) + + (call + target: (identifier) @name + (arguments (alias) @name) + (#match? @name "^(defmodule|defprotocol)$")) @item + "#, + ) + .unwrap(), + ) +} diff --git a/crates/zed/src/languages/elixir/embedding.scm b/crates/zed/src/languages/elixir/embedding.scm new file mode 100644 index 0000000000000000000000000000000000000000..16ad20746d4b0c8697ff126fcc5150636cb8b794 --- /dev/null +++ b/crates/zed/src/languages/elixir/embedding.scm @@ -0,0 +1,27 @@ +( + (unary_operator + operator: "@" + operand: (call + target: (identifier) @unary + (#match? @unary "^(doc)$")) + ) @context + . + (call + target: (identifier) @name + (arguments + [ + (identifier) @name + (call + target: (identifier) @name) + (binary_operator + left: (call + target: (identifier) @name) + operator: "when") + ]) + (#match? @name "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item + ) + + (call + target: (identifier) @name + (arguments (alias) @name) + (#match? @name "^(defmodule|defprotocol)$")) @item From 8b42f5b1b379e175a599067654724b8d6ea48f35 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 17 Jul 2023 17:06:10 -0400 Subject: [PATCH 018/160] rename vector_store crate to semantic_index --- Cargo.lock | 274 +++++++++--------- Cargo.toml | 2 +- assets/settings/default.json | 4 +- .../Cargo.toml | 4 +- .../README.md | 0 .../src/db.rs | 16 +- .../src/embedding.rs | 0 .../src/modal.rs | 12 +- .../src/parsing.rs | 0 .../src/semantic_index.rs} | 33 ++- .../src/semantic_index_settings.rs} | 10 +- .../src/semantic_index_tests.rs} | 10 +- crates/zed/Cargo.toml | 2 +- crates/zed/src/main.rs | 2 +- 14 files changed, 186 insertions(+), 183 deletions(-) rename crates/{vector_store => semantic_index}/Cargo.toml (96%) rename crates/{vector_store => semantic_index}/README.md (100%) rename crates/{vector_store => semantic_index}/src/db.rs (95%) rename crates/{vector_store => semantic_index}/src/embedding.rs (100%) rename crates/{vector_store => semantic_index}/src/modal.rs (95%) rename crates/{vector_store => semantic_index}/src/parsing.rs (100%) rename crates/{vector_store/src/vector_store.rs => semantic_index/src/semantic_index.rs} (96%) rename crates/{vector_store/src/vector_store_settings.rs => semantic_index/src/semantic_index_settings.rs} (71%) rename crates/{vector_store/src/vector_store_tests.rs => semantic_index/src/semantic_index_tests.rs} (99%) diff --git a/Cargo.lock b/Cargo.lock index 8fcca507d1fa47309793843f2268a87ff59a2e49..430a665f98b2a7f353855b9645c2e148dd02fb4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -179,9 +179,9 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "allocator-api2" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "alsa" @@ -277,9 +277,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "arrayref" @@ -481,7 +481,7 @@ checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -529,7 +529,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -572,7 +572,7 @@ checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -680,7 +680,7 @@ dependencies = [ "http", "http-body", "hyper", - "itoa 1.0.8", + "itoa 1.0.9", "matchit", "memchr", "mime", @@ -830,7 +830,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.25", + "syn 2.0.26", "which", ] @@ -1243,20 +1243,20 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.11" +version = "4.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" +checksum = "98330784c494e49850cb23b8e2afcca13587d2500b2e3f1f78ae20248059c9be" dependencies = [ "clap_builder", - "clap_derive 4.3.2", + "clap_derive 4.3.12", "once_cell", ] [[package]] name = "clap_builder" -version = "4.3.11" +version = "4.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" +checksum = "e182eb5f2562a67dda37e2c57af64d720a9e010c5e860ed87c056586aeafa52e" dependencies = [ "anstream", "anstyle", @@ -1279,14 +1279,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -1357,7 +1357,7 @@ dependencies = [ "tiny_http", "url", "util", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -2204,9 +2204,9 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" +checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" [[package]] name = "editor" @@ -2319,9 +2319,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f94c0e13118e7d7533271f754a168ae8400e6a1cc043f2bfd53cc7290f1a1de3" +checksum = "da96524cc884f6558f1769b6c46686af2fe8e8b4cd253bd5a3cdba8181b8e070" dependencies = [ "serde", ] @@ -2789,7 +2789,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -3033,7 +3033,7 @@ dependencies = [ "tiny-skia", "usvg", "util", - "uuid 1.4.0", + "uuid 1.4.1", "waker-fn", ] @@ -3235,7 +3235,7 @@ checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes 1.4.0", "fnv", - "itoa 1.0.8", + "itoa 1.0.9", ] [[package]] @@ -3294,7 +3294,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 1.0.8", + "itoa 1.0.9", "pin-project-lite 0.2.10", "socket2", "tokio", @@ -3499,7 +3499,7 @@ dependencies = [ "rand 0.7.3", "serde", "tempfile", - "uuid 1.4.0", + "uuid 1.4.1", "winapi 0.3.9", ] @@ -3576,9 +3576,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "ittapi-rs" @@ -4722,7 +4722,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -4886,9 +4886,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pathfinder_color" @@ -4952,9 +4952,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73935e4d55e2abf7f130186537b19e7a4abc886a0252380b59248af473a3fc9" +checksum = "0d2d1d55045829d65aad9d389139882ad623b33b904e7c9f1b10c5b8927298e5" dependencies = [ "thiserror", "ucd-trie", @@ -5010,7 +5010,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -5163,7 +5163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92139198957b410250d43fad93e630d956499a625c527eda65175c8680f83387" dependencies = [ "proc-macro2", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -5211,9 +5211,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -5491,9 +5491,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.29" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" dependencies = [ "proc-macro2", ] @@ -5879,7 +5879,7 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -6034,7 +6034,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.25", + "syn 2.0.26", "walkdir", ] @@ -6097,7 +6097,7 @@ dependencies = [ "bitflags 1.3.2", "errno 0.2.8", "io-lifetimes 0.5.3", - "itoa 1.0.8", + "itoa 1.0.9", "libc", "linux-raw-sys 0.0.42", "once_cell", @@ -6167,9 +6167,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "rustybuzz" @@ -6189,9 +6189,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "safe_arch" @@ -6267,9 +6267,9 @@ checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scrypt" @@ -6329,7 +6329,7 @@ dependencies = [ "time 0.3.23", "tracing", "url", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -6355,7 +6355,7 @@ dependencies = [ "sea-query-derive", "serde_json", "time 0.3.23", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -6370,7 +6370,7 @@ dependencies = [ "serde_json", "sqlx", "time 0.3.23", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -6465,6 +6465,48 @@ dependencies = [ "libc", ] +[[package]] +name = "semantic_index" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "ctor", + "editor", + "env_logger 0.9.3", + "futures 0.3.28", + "gpui", + "isahc", + "language", + "lazy_static", + "log", + "matrixmultiply", + "parking_lot 0.11.2", + "picker", + "project", + "rand 0.8.5", + "rpc", + "rusqlite", + "schemars", + "serde", + "serde_json", + "settings", + "smol", + "tempdir", + "theme", + "tiktoken-rs 0.5.0", + "tree-sitter", + "tree-sitter-cpp", + "tree-sitter-elixir 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tree-sitter-rust", + "tree-sitter-toml 0.20.0", + "tree-sitter-typescript 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unindent", + "util", + "workspace", +] + [[package]] name = "semver" version = "0.11.0" @@ -6506,7 +6548,7 @@ checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -6531,12 +6573,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed" +checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" dependencies = [ "indexmap 2.0.0", - "itoa 1.0.8", + "itoa 1.0.9", "ryu", "serde", ] @@ -6561,7 +6603,7 @@ checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -6571,7 +6613,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.8", + "itoa 1.0.9", "ryu", "serde", ] @@ -6702,9 +6744,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "signal-hook" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +checksum = "b824b6e687aff278cdbf3b36f07aa52d4bd4099699324d5da86a2ebce3aa00b3" dependencies = [ "libc", "signal-hook-registry", @@ -6891,7 +6933,7 @@ dependencies = [ "parking_lot 0.11.2", "smol", "thread_local", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -6957,7 +6999,7 @@ dependencies = [ "hkdf", "hmac 0.12.1", "indexmap 1.9.3", - "itoa 1.0.8", + "itoa 1.0.9", "libc", "libsqlite3-sys", "log", @@ -6983,7 +7025,7 @@ dependencies = [ "time 0.3.23", "tokio-stream", "url", - "uuid 1.4.0", + "uuid 1.4.1", "webpki-roots 0.22.6", "whoami", ] @@ -7041,9 +7083,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stringprep" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +checksum = "db3737bde7edce97102e0e2b15365bf7a20bfdb5f60f4f9e8d7004258a51a8da" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -7103,7 +7145,7 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326" dependencies = [ - "itoa 1.0.8", + "itoa 1.0.9", "ryu", "sval", ] @@ -7114,7 +7156,7 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d" dependencies = [ - "itoa 1.0.8", + "itoa 1.0.9", "ryu", "sval", ] @@ -7229,9 +7271,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.25" +version = "2.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" dependencies = [ "proc-macro2", "quote", @@ -7485,7 +7527,7 @@ checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -7562,7 +7604,7 @@ version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ - "itoa 1.0.8", + "itoa 1.0.9", "serde", "time-core", "time-macros", @@ -7674,7 +7716,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -7767,9 +7809,9 @@ checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.19.12" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap 2.0.0", "toml_datetime", @@ -7879,7 +7921,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -8285,9 +8327,9 @@ checksum = "7f9af028e052a610d99e066b33304625dea9613170a2563314490a4e6ec5cf7f" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -8427,9 +8469,9 @@ checksum = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" [[package]] name = "uuid" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom 0.2.10", "serde", @@ -8496,48 +8538,6 @@ dependencies = [ "workspace", ] -[[package]] -name = "vector_store" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-trait", - "bincode", - "ctor", - "editor", - "env_logger 0.9.3", - "futures 0.3.28", - "gpui", - "isahc", - "language", - "lazy_static", - "log", - "matrixmultiply", - "parking_lot 0.11.2", - "picker", - "project", - "rand 0.8.5", - "rpc", - "rusqlite", - "schemars", - "serde", - "serde_json", - "settings", - "smol", - "tempdir", - "theme", - "tiktoken-rs 0.5.0", - "tree-sitter", - "tree-sitter-cpp", - "tree-sitter-elixir 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tree-sitter-rust", - "tree-sitter-toml 0.20.0", - "tree-sitter-typescript 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unindent", - "util", - "workspace", -] - [[package]] name = "version_check" version = "0.9.4" @@ -8698,7 +8698,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", "wasm-bindgen-shared", ] @@ -8732,7 +8732,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -8745,9 +8745,9 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-encoder" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2f8e9778e04cbf44f58acc301372577375a666b966c50b03ef46144f80436a8" +checksum = "06a3d1b4a575ffb873679402b2aedb3117555eb65c27b1b86c8a91e574bc2a2a" dependencies = [ "leb128", ] @@ -8969,9 +8969,9 @@ dependencies = [ [[package]] name = "wast" -version = "61.0.0" +version = "62.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6b347851b52fd500657d301155c79e8c67595501d179cef87b6f04ebd25ac4" +checksum = "c7f7ee878019d69436895f019b65f62c33da63595d8e857cbdc87c13ecb29a32" dependencies = [ "leb128", "memchr", @@ -8981,11 +8981,11 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459e764d27c3ab7beba1ebd617cc025c7e76dea6e7c5ce3189989a970aea3491" +checksum = "295572bf24aa5b685a971a83ad3e8b6e684aaad8a9be24bc7bf59bed84cc1c08" dependencies = [ - "wast 61.0.0", + "wast 62.0.0", ] [[package]] @@ -9315,9 +9315,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.9" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" +checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" dependencies = [ "memchr", ] @@ -9399,7 +9399,7 @@ dependencies = [ "terminal", "theme", "util", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -9447,7 +9447,7 @@ name = "xtask" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.3.11", + "clap 4.3.14", "schemars", "serde_json", "theme", @@ -9548,6 +9548,7 @@ dependencies = [ "rsa", "rust-embed", "search", + "semantic_index", "serde", "serde_derive", "serde_json", @@ -9589,8 +9590,7 @@ dependencies = [ "url", "urlencoding", "util", - "uuid 1.4.0", - "vector_store", + "uuid 1.4.1", "vim", "welcome", "workspace", @@ -9621,7 +9621,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 529f297f700d5006df3c169f3e663144bc24f9d1..ce3dd9c46221db7f189a66843162fbb483e68aa4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ members = [ "crates/theme", "crates/theme_selector", "crates/util", - "crates/vector_store", + "crates/semantic_index", "crates/vim", "crates/vcs_menu", "crates/workspace", diff --git a/assets/settings/default.json b/assets/settings/default.json index 1f8d12a3d9db82a87ca1788fe8369dbfb42b7596..b109b8d595a1e184a668ff2fa226d1ffa7ce2f70 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -291,8 +291,8 @@ // the terminal will default to matching the buffer's font family. // "font_family": "Zed Mono" }, - // Difference settings for vector_store - "vector_store": { + // Difference settings for semantic_index + "semantic_index": { "enabled": false, "reindexing_delay_seconds": 600 }, diff --git a/crates/vector_store/Cargo.toml b/crates/semantic_index/Cargo.toml similarity index 96% rename from crates/vector_store/Cargo.toml rename to crates/semantic_index/Cargo.toml index 6808f6c630ca8dda97fce819765995b78f3d2a9a..5c5af072c8f614e8eb8111d31c72bf9bbf905ada 100644 --- a/crates/vector_store/Cargo.toml +++ b/crates/semantic_index/Cargo.toml @@ -1,11 +1,11 @@ [package] -name = "vector_store" +name = "semantic_index" version = "0.1.0" edition = "2021" publish = false [lib] -path = "src/vector_store.rs" +path = "src/semantic_index.rs" doctest = false [dependencies] diff --git a/crates/vector_store/README.md b/crates/semantic_index/README.md similarity index 100% rename from crates/vector_store/README.md rename to crates/semantic_index/README.md diff --git a/crates/vector_store/src/db.rs b/crates/semantic_index/src/db.rs similarity index 95% rename from crates/vector_store/src/db.rs rename to crates/semantic_index/src/db.rs index d3d05f8c62c9d5639e641094204caa112e96c54f..1d5a9a475ea826cdb7baa91406b83b2189f95587 100644 --- a/crates/vector_store/src/db.rs +++ b/crates/semantic_index/src/db.rs @@ -1,4 +1,4 @@ -use crate::{parsing::Document, VECTOR_STORE_VERSION}; +use crate::{parsing::Document, SEMANTIC_INDEX_VERSION}; use anyhow::{anyhow, Result}; use project::Fs; use rpc::proto::Timestamp; @@ -55,7 +55,9 @@ impl VectorDatabase { } fn get_existing_version(&self) -> Result { - let mut version_query = self.db.prepare("SELECT version from vector_store_config")?; + let mut version_query = self + .db + .prepare("SELECT version from semantic_index_config")?; version_query .query_row([], |row| Ok(row.get::<_, i64>(0)?)) .map_err(|err| anyhow!("version query failed: {err}")) @@ -66,7 +68,7 @@ impl VectorDatabase { if self .get_existing_version() - .map_or(false, |version| version == VECTOR_STORE_VERSION as i64) + .map_or(false, |version| version == SEMANTIC_INDEX_VERSION as i64) { return Ok(()); } @@ -74,7 +76,7 @@ impl VectorDatabase { self.db .execute( " - DROP TABLE vector_store_config; + DROP TABLE semantic_index_config; DROP TABLE worktrees; DROP TABLE files; DROP TABLE documents; @@ -85,15 +87,15 @@ impl VectorDatabase { // Initialize Vector Databasing Tables self.db.execute( - "CREATE TABLE vector_store_config ( + "CREATE TABLE semantic_index_config ( version INTEGER NOT NULL )", [], )?; self.db.execute( - "INSERT INTO vector_store_config (version) VALUES (?1)", - params![VECTOR_STORE_VERSION], + "INSERT INTO semantic_index_config (version) VALUES (?1)", + params![SEMANTIC_INDEX_VERSION], )?; self.db.execute( diff --git a/crates/vector_store/src/embedding.rs b/crates/semantic_index/src/embedding.rs similarity index 100% rename from crates/vector_store/src/embedding.rs rename to crates/semantic_index/src/embedding.rs diff --git a/crates/vector_store/src/modal.rs b/crates/semantic_index/src/modal.rs similarity index 95% rename from crates/vector_store/src/modal.rs rename to crates/semantic_index/src/modal.rs index 2981fa4e73ef77ce3b54b68da9b177452f6d245e..ffc64a195ccfb23009922f71878c17ea90b1e375 100644 --- a/crates/vector_store/src/modal.rs +++ b/crates/semantic_index/src/modal.rs @@ -1,4 +1,4 @@ -use crate::{SearchResult, VectorStore}; +use crate::{SearchResult, SemanticIndex}; use editor::{scroll::autoscroll::Autoscroll, Editor}; use gpui::{ actions, elements::*, AnyElement, AppContext, ModelHandle, MouseState, Task, ViewContext, @@ -20,7 +20,7 @@ pub type SemanticSearch = Picker; pub struct SemanticSearchDelegate { workspace: WeakViewHandle, project: ModelHandle, - vector_store: ModelHandle, + semantic_index: ModelHandle, selected_match_index: usize, matches: Vec, history: HashMap>, @@ -33,12 +33,12 @@ impl SemanticSearchDelegate { pub fn new( workspace: WeakViewHandle, project: ModelHandle, - vector_store: ModelHandle, + semantic_index: ModelHandle, ) -> Self { Self { workspace, project, - vector_store, + semantic_index, selected_match_index: 0, matches: vec![], history: HashMap::new(), @@ -105,7 +105,7 @@ impl PickerDelegate for SemanticSearchDelegate { return Task::ready(()); } - let vector_store = self.vector_store.clone(); + let semantic_index = self.semantic_index.clone(); let project = self.project.clone(); cx.spawn(|this, mut cx| async move { cx.background().timer(EMBEDDING_DEBOUNCE_INTERVAL).await; @@ -123,7 +123,7 @@ impl PickerDelegate for SemanticSearchDelegate { if let Some(retrieved) = retrieved_cached.log_err() { if !retrieved { - let task = vector_store.update(&mut cx, |store, cx| { + let task = semantic_index.update(&mut cx, |store, cx| { store.search_project(project.clone(), query.to_string(), 10, cx) }); diff --git a/crates/vector_store/src/parsing.rs b/crates/semantic_index/src/parsing.rs similarity index 100% rename from crates/vector_store/src/parsing.rs rename to crates/semantic_index/src/parsing.rs diff --git a/crates/vector_store/src/vector_store.rs b/crates/semantic_index/src/semantic_index.rs similarity index 96% rename from crates/vector_store/src/vector_store.rs rename to crates/semantic_index/src/semantic_index.rs index 0f55bd9e63f3a95ce113478a406f485600348973..58ffa512ce6e6714cb2af2ea3593d1f7eb96c534 100644 --- a/crates/vector_store/src/vector_store.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -2,12 +2,12 @@ mod db; mod embedding; mod modal; mod parsing; -mod vector_store_settings; +mod semantic_index_settings; #[cfg(test)] -mod vector_store_tests; +mod semantic_index_tests; -use crate::vector_store_settings::VectorStoreSettings; +use crate::semantic_index_settings::SemanticIndexSettings; use anyhow::{anyhow, Result}; use db::VectorDatabase; use embedding::{EmbeddingProvider, OpenAIEmbeddings}; @@ -40,7 +40,7 @@ use util::{ }; use workspace::{Workspace, WorkspaceCreated}; -const VECTOR_STORE_VERSION: usize = 1; +const SEMANTIC_INDEX_VERSION: usize = 1; const EMBEDDINGS_BATCH_SIZE: usize = 150; pub fn init( @@ -49,7 +49,7 @@ pub fn init( language_registry: Arc, cx: &mut AppContext, ) { - settings::register::(cx); + settings::register::(cx); let db_file_path = EMBEDDINGS_DIR .join(Path::new(RELEASE_CHANNEL_NAME.as_str())) @@ -58,14 +58,14 @@ pub fn init( SemanticSearch::init(cx); cx.add_action( |workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext| { - if cx.has_global::>() { - let vector_store = cx.global::>().clone(); + if cx.has_global::>() { + let semantic_index = cx.global::>().clone(); workspace.toggle_modal(cx, |workspace, cx| { let project = workspace.project().clone(); let workspace = cx.weak_handle(); cx.add_view(|cx| { SemanticSearch::new( - SemanticSearchDelegate::new(workspace, project, vector_store), + SemanticSearchDelegate::new(workspace, project, semantic_index), cx, ) }) @@ -75,13 +75,14 @@ pub fn init( ); if *RELEASE_CHANNEL == ReleaseChannel::Stable - || !settings::get::(cx).enabled + || !settings::get::(cx).enabled { + log::info!("NOT ENABLED"); return; } cx.spawn(move |mut cx| async move { - let vector_store = VectorStore::new( + let semantic_index = SemanticIndex::new( fs, db_file_path, Arc::new(OpenAIEmbeddings { @@ -94,15 +95,15 @@ pub fn init( .await?; cx.update(|cx| { - cx.set_global(vector_store.clone()); + cx.set_global(semantic_index.clone()); cx.subscribe_global::({ - let vector_store = vector_store.clone(); + let semantic_index = semantic_index.clone(); move |event, cx| { let workspace = &event.0; if let Some(workspace) = workspace.upgrade(cx) { let project = workspace.read(cx).project().clone(); if project.read(cx).is_local() { - vector_store.update(cx, |store, cx| { + semantic_index.update(cx, |store, cx| { store.index_project(project, cx).detach(); }); } @@ -117,7 +118,7 @@ pub fn init( .detach(); } -pub struct VectorStore { +pub struct SemanticIndex { fs: Arc, database_url: Arc, embedding_provider: Arc, @@ -220,7 +221,7 @@ enum EmbeddingJob { Flush, } -impl VectorStore { +impl SemanticIndex { async fn new( fs: Arc, database_url: PathBuf, @@ -672,7 +673,7 @@ impl VectorStore { } } -impl Entity for VectorStore { +impl Entity for SemanticIndex { type Event = (); } diff --git a/crates/vector_store/src/vector_store_settings.rs b/crates/semantic_index/src/semantic_index_settings.rs similarity index 71% rename from crates/vector_store/src/vector_store_settings.rs rename to crates/semantic_index/src/semantic_index_settings.rs index e1fa7cc05a362829fae1a361097740d04b115b6c..86872457f841e1bfe1b601d1fb6d5d86a12911dc 100644 --- a/crates/vector_store/src/vector_store_settings.rs +++ b/crates/semantic_index/src/semantic_index_settings.rs @@ -4,21 +4,21 @@ use serde::{Deserialize, Serialize}; use settings::Setting; #[derive(Deserialize, Debug)] -pub struct VectorStoreSettings { +pub struct SemanticIndexSettings { pub enabled: bool, pub reindexing_delay_seconds: usize, } #[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)] -pub struct VectorStoreSettingsContent { +pub struct SemanticIndexSettingsContent { pub enabled: Option, pub reindexing_delay_seconds: Option, } -impl Setting for VectorStoreSettings { - const KEY: Option<&'static str> = Some("vector_store"); +impl Setting for SemanticIndexSettings { + const KEY: Option<&'static str> = Some("semantic_index"); - type FileContent = VectorStoreSettingsContent; + type FileContent = SemanticIndexSettingsContent; fn load( default_value: &Self::FileContent, diff --git a/crates/vector_store/src/vector_store_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs similarity index 99% rename from crates/vector_store/src/vector_store_tests.rs rename to crates/semantic_index/src/semantic_index_tests.rs index d55dfcfc7151eb04efb5a33b119ae33b0875d86d..ed48cf256bed1bce335c942b2508d486acf82ce0 100644 --- a/crates/vector_store/src/vector_store_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -2,8 +2,8 @@ use crate::{ db::dot, embedding::EmbeddingProvider, parsing::{CodeContextRetriever, Document}, - vector_store_settings::VectorStoreSettings, - VectorStore, + semantic_index_settings::SemanticIndexSettings, + SemanticIndex, }; use anyhow::Result; use async_trait::async_trait; @@ -30,10 +30,10 @@ fn init_logger() { } #[gpui::test] -async fn test_vector_store(cx: &mut TestAppContext) { +async fn test_semantic_index(cx: &mut TestAppContext) { cx.update(|cx| { cx.set_global(SettingsStore::test(cx)); - settings::register::(cx); + settings::register::(cx); settings::register::(cx); }); @@ -74,7 +74,7 @@ async fn test_vector_store(cx: &mut TestAppContext) { let db_path = db_dir.path().join("db.sqlite"); let embedding_provider = Arc::new(FakeEmbeddingProvider::default()); - let store = VectorStore::new( + let store = SemanticIndex::new( fs.clone(), db_path, embedding_provider.clone(), diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 597e40161fb029eee16cf53208ce0e20d0c0a603..265312bc9a9de5de76465fc2e7e737bc4cb52a4f 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -64,7 +64,7 @@ terminal_view = { path = "../terminal_view" } theme = { path = "../theme" } theme_selector = { path = "../theme_selector" } util = { path = "../util" } -vector_store = { path = "../vector_store" } +semantic_index = { path = "../semantic_index" } vim = { path = "../vim" } workspace = { path = "../workspace" } welcome = { path = "../welcome" } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 4c75d370d517423e395119d2ceb4f3c47b61a21b..3598da5dee2eb9c96b18474bcef5e8e763cbae14 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -157,7 +157,7 @@ fn main() { project_panel::init(cx); diagnostics::init(cx); search::init(cx); - vector_store::init(fs.clone(), http.clone(), languages.clone(), cx); + semantic_index::init(fs.clone(), http.clone(), languages.clone(), cx); vim::init(cx); terminal_view::init(cx); copilot::init(http.clone(), node_runtime, cx); From d83c4ffb072081d0b07f62f3c90f3bff5be48509 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 17 Jul 2023 17:09:51 -0400 Subject: [PATCH 019/160] remove debug logging for enabled settings --- crates/semantic_index/src/semantic_index.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 58ffa512ce6e6714cb2af2ea3593d1f7eb96c534..b59b20370aff967de5b2c805da5c693993e0c23e 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -77,7 +77,6 @@ pub fn init( if *RELEASE_CHANNEL == ReleaseChannel::Stable || !settings::get::(cx).enabled { - log::info!("NOT ENABLED"); return; } From afc4c10ec1162b151c33a9ffe051233dca10a5e5 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 17 Jul 2023 18:10:51 -0700 Subject: [PATCH 020/160] Start work on exposing semantic search via project search view Co-authored-by: Kyle --- Cargo.lock | 2 + crates/search/Cargo.toml | 1 + crates/search/src/project_search.rs | 156 +++++- crates/semantic_index/Cargo.toml | 1 + crates/semantic_index/src/db.rs | 12 +- crates/semantic_index/src/embedding.rs | 7 +- crates/semantic_index/src/modal.rs | 172 ------- crates/semantic_index/src/semantic_index.rs | 451 +++++++++--------- .../src/semantic_index_tests.rs | 18 +- 9 files changed, 397 insertions(+), 423 deletions(-) delete mode 100644 crates/semantic_index/src/modal.rs diff --git a/Cargo.lock b/Cargo.lock index 430a665f98b2a7f353855b9645c2e148dd02fb4b..484ef3644b1cdddab26755c4eaf293154bbbcb3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6430,6 +6430,7 @@ dependencies = [ "menu", "postage", "project", + "semantic_index", "serde", "serde_derive", "serde_json", @@ -6484,6 +6485,7 @@ dependencies = [ "matrixmultiply", "parking_lot 0.11.2", "picker", + "postage", "project", "rand 0.8.5", "rpc", diff --git a/crates/search/Cargo.toml b/crates/search/Cargo.toml index 7ef388f7c087638c1ee3f5c2002ab3d2c3371dc7..f6ed6c3fef4bf3a566e27cdd46b7169405a72c97 100644 --- a/crates/search/Cargo.toml +++ b/crates/search/Cargo.toml @@ -19,6 +19,7 @@ settings = { path = "../settings" } theme = { path = "../theme" } util = { path = "../util" } workspace = { path = "../workspace" } +semantic_index = { path = "../semantic_index" } anyhow.workspace = true futures.workspace = true log.workspace = true diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index ebd504d02c2334aa6876a478937718cb1aa4d496..91d2b142ae27c3b1579d99b04fe6cb8b6f745705 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -2,7 +2,7 @@ use crate::{ SearchOption, SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleRegex, ToggleWholeWord, }; -use anyhow::Result; +use anyhow::{Context, Result}; use collections::HashMap; use editor::{ items::active_match_index, scroll::autoscroll::Autoscroll, Anchor, Editor, MultiBuffer, @@ -18,7 +18,9 @@ use gpui::{ Task, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle, }; use menu::Confirm; +use postage::stream::Stream; use project::{search::SearchQuery, Project}; +use semantic_index::SemanticIndex; use smallvec::SmallVec; use std::{ any::{Any, TypeId}, @@ -36,7 +38,10 @@ use workspace::{ ItemNavHistory, Pane, ToolbarItemLocation, ToolbarItemView, Workspace, WorkspaceId, }; -actions!(project_search, [SearchInNew, ToggleFocus, NextField]); +actions!( + project_search, + [SearchInNew, ToggleFocus, NextField, ToggleSemanticSearch] +); #[derive(Default)] struct ActiveSearches(HashMap, WeakViewHandle>); @@ -92,6 +97,7 @@ pub struct ProjectSearchView { case_sensitive: bool, whole_word: bool, regex: bool, + semantic: Option, panels_with_errors: HashSet, active_match_index: Option, search_id: usize, @@ -100,6 +106,13 @@ pub struct ProjectSearchView { excluded_files_editor: ViewHandle, } +struct SemanticSearchState { + file_count: usize, + outstanding_file_count: usize, + _progress_task: Task<()>, + search_task: Option>>, +} + pub struct ProjectSearchBar { active_project_search: Option>, subscription: Option, @@ -198,12 +211,25 @@ impl View for ProjectSearchView { let theme = theme::current(cx).clone(); let text = if self.query_editor.read(cx).text(cx).is_empty() { - "" + Cow::Borrowed("") + } else if let Some(semantic) = &self.semantic { + if semantic.search_task.is_some() { + Cow::Borrowed("Searching...") + } else if semantic.outstanding_file_count > 0 { + Cow::Owned(format!( + "Indexing. {} of {}...", + semantic.file_count - semantic.outstanding_file_count, + semantic.file_count + )) + } else { + Cow::Borrowed("Indexing complete") + } } else if model.pending_search.is_some() { - "Searching..." + Cow::Borrowed("Searching...") } else { - "No results" + Cow::Borrowed("No results") }; + MouseEventHandler::::new(0, cx, |_, _| { Label::new(text, theme.search.results_status.clone()) .aligned() @@ -499,6 +525,7 @@ impl ProjectSearchView { case_sensitive, whole_word, regex, + semantic: None, panels_with_errors: HashSet::new(), active_match_index: None, query_editor_was_focused: false, @@ -563,6 +590,35 @@ impl ProjectSearchView { } fn search(&mut self, cx: &mut ViewContext) { + if let Some(semantic) = &mut self.semantic { + if semantic.outstanding_file_count > 0 { + return; + } + + let search_phrase = self.query_editor.read(cx).text(cx); + let project = self.model.read(cx).project.clone(); + if let Some(semantic_index) = SemanticIndex::global(cx) { + let search_task = semantic_index.update(cx, |semantic_index, cx| { + semantic_index.search_project(project, search_phrase, 10, cx) + }); + semantic.search_task = Some(cx.spawn(|this, mut cx| async move { + let results = search_task.await.context("search task")?; + + this.update(&mut cx, |this, cx| { + dbg!(&results); + // TODO: Update results + + if let Some(semantic) = &mut this.semantic { + semantic.search_task = None; + } + })?; + + anyhow::Ok(()) + })); + } + return; + } + if let Some(query) = self.build_search_query(cx) { self.model.update(cx, |model, cx| model.search(query, cx)); } @@ -876,6 +932,59 @@ impl ProjectSearchBar { } } + fn toggle_semantic_search(&mut self, cx: &mut ViewContext) -> bool { + if let Some(search_view) = self.active_project_search.as_ref() { + search_view.update(cx, |search_view, cx| { + if search_view.semantic.is_some() { + search_view.semantic = None; + } else if let Some(semantic_index) = SemanticIndex::global(cx) { + // TODO: confirm that it's ok to send this project + + let project = search_view.model.read(cx).project.clone(); + let index_task = semantic_index.update(cx, |semantic_index, cx| { + semantic_index.index_project(project, cx) + }); + + cx.spawn(|search_view, mut cx| async move { + let (files_to_index, mut files_remaining_rx) = index_task.await?; + + search_view.update(&mut cx, |search_view, cx| { + search_view.semantic = Some(SemanticSearchState { + file_count: files_to_index, + outstanding_file_count: files_to_index, + search_task: None, + _progress_task: cx.spawn(|search_view, mut cx| async move { + while let Some(count) = files_remaining_rx.recv().await { + search_view + .update(&mut cx, |search_view, cx| { + if let Some(semantic_search_state) = + &mut search_view.semantic + { + semantic_search_state.outstanding_file_count = + count; + cx.notify(); + if count == 0 { + return; + } + } + }) + .ok(); + } + }), + }); + })?; + anyhow::Ok(()) + }) + .detach_and_log_err(cx); + } + }); + cx.notify(); + true + } else { + false + } + } + fn render_nav_button( &self, icon: &'static str, @@ -953,6 +1062,42 @@ impl ProjectSearchBar { .into_any() } + fn render_semantic_search_button(&self, cx: &mut ViewContext) -> AnyElement { + let tooltip_style = theme::current(cx).tooltip.clone(); + let is_active = if let Some(search) = self.active_project_search.as_ref() { + let search = search.read(cx); + search.semantic.is_some() + } else { + false + }; + + let region_id = 3; + + MouseEventHandler::::new(region_id, cx, |state, cx| { + let theme = theme::current(cx); + let style = theme + .search + .option_button + .in_state(is_active) + .style_for(state); + Label::new("Semantic", style.text.clone()) + .contained() + .with_style(style.container) + }) + .on_click(MouseButton::Left, move |_, this, cx| { + this.toggle_semantic_search(cx); + }) + .with_cursor_style(CursorStyle::PointingHand) + .with_tooltip::( + region_id, + format!("Toggle Semantic Search"), + Some(Box::new(ToggleSemanticSearch)), + tooltip_style, + cx, + ) + .into_any() + } + fn is_option_enabled(&self, option: SearchOption, cx: &AppContext) -> bool { if let Some(search) = self.active_project_search.as_ref() { let search = search.read(cx); @@ -1049,6 +1194,7 @@ impl View for ProjectSearchBar { ) .with_child( Flex::row() + .with_child(self.render_semantic_search_button(cx)) .with_child(self.render_option_button( "Case", SearchOption::CaseSensitive, diff --git a/crates/semantic_index/Cargo.toml b/crates/semantic_index/Cargo.toml index 5c5af072c8f614e8eb8111d31c72bf9bbf905ada..2d21ff6c1c42710e597101cd024fdde9183bcbc5 100644 --- a/crates/semantic_index/Cargo.toml +++ b/crates/semantic_index/Cargo.toml @@ -20,6 +20,7 @@ editor = { path = "../editor" } rpc = { path = "../rpc" } settings = { path = "../settings" } anyhow.workspace = true +postage.workspace = true futures.workspace = true smol.workspace = true rusqlite = { version = "0.27.0", features = ["blob", "array", "modern_sqlite"] } diff --git a/crates/semantic_index/src/db.rs b/crates/semantic_index/src/db.rs index 1d5a9a475ea826cdb7baa91406b83b2189f95587..a667ff877c2e02c65e669e10b7fdbc07e319653b 100644 --- a/crates/semantic_index/src/db.rs +++ b/crates/semantic_index/src/db.rs @@ -1,5 +1,5 @@ use crate::{parsing::Document, SEMANTIC_INDEX_VERSION}; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context, Result}; use project::Fs; use rpc::proto::Timestamp; use rusqlite::{ @@ -76,14 +76,14 @@ impl VectorDatabase { self.db .execute( " - DROP TABLE semantic_index_config; - DROP TABLE worktrees; - DROP TABLE files; - DROP TABLE documents; + DROP TABLE IF EXISTS documents; + DROP TABLE IF EXISTS files; + DROP TABLE IF EXISTS worktrees; + DROP TABLE IF EXISTS semantic_index_config; ", [], ) - .ok(); + .context("failed to drop tables")?; // Initialize Vector Databasing Tables self.db.execute( diff --git a/crates/semantic_index/src/embedding.rs b/crates/semantic_index/src/embedding.rs index ea349c8afa4a8d908d60760f8ff1eb6839e3120b..4f49d66ce7eefeb70961fcaab936edf102b715b9 100644 --- a/crates/semantic_index/src/embedding.rs +++ b/crates/semantic_index/src/embedding.rs @@ -86,6 +86,7 @@ impl OpenAIEmbeddings { async fn send_request(&self, api_key: &str, spans: Vec<&str>) -> Result> { let request = Request::post("https://api.openai.com/v1/embeddings") .redirect_policy(isahc::config::RedirectPolicy::Follow) + .timeout(Duration::from_secs(4)) .header("Content-Type", "application/json") .header("Authorization", format!("Bearer {}", api_key)) .body( @@ -133,7 +134,11 @@ impl EmbeddingProvider for OpenAIEmbeddings { self.executor.timer(delay).await; } StatusCode::BAD_REQUEST => { - log::info!("BAD REQUEST: {:?}", &response.status()); + log::info!( + "BAD REQUEST: {:?} {:?}", + &response.status(), + response.body() + ); // Don't worry about delaying bad request, as we can assume // we haven't been rate limited yet. for span in spans.iter_mut() { diff --git a/crates/semantic_index/src/modal.rs b/crates/semantic_index/src/modal.rs deleted file mode 100644 index ffc64a195ccfb23009922f71878c17ea90b1e375..0000000000000000000000000000000000000000 --- a/crates/semantic_index/src/modal.rs +++ /dev/null @@ -1,172 +0,0 @@ -use crate::{SearchResult, SemanticIndex}; -use editor::{scroll::autoscroll::Autoscroll, Editor}; -use gpui::{ - actions, elements::*, AnyElement, AppContext, ModelHandle, MouseState, Task, ViewContext, - WeakViewHandle, -}; -use picker::{Picker, PickerDelegate, PickerEvent}; -use project::{Project, ProjectPath}; -use std::{collections::HashMap, sync::Arc, time::Duration}; -use util::ResultExt; -use workspace::Workspace; - -const MIN_QUERY_LEN: usize = 5; -const EMBEDDING_DEBOUNCE_INTERVAL: Duration = Duration::from_millis(500); - -actions!(semantic_search, [Toggle]); - -pub type SemanticSearch = Picker; - -pub struct SemanticSearchDelegate { - workspace: WeakViewHandle, - project: ModelHandle, - semantic_index: ModelHandle, - selected_match_index: usize, - matches: Vec, - history: HashMap>, -} - -impl SemanticSearchDelegate { - // This is currently searching on every keystroke, - // This is wildly overkill, and has the potential to get expensive - // We will need to update this to throttle searching - pub fn new( - workspace: WeakViewHandle, - project: ModelHandle, - semantic_index: ModelHandle, - ) -> Self { - Self { - workspace, - project, - semantic_index, - selected_match_index: 0, - matches: vec![], - history: HashMap::new(), - } - } -} - -impl PickerDelegate for SemanticSearchDelegate { - fn placeholder_text(&self) -> Arc { - "Search repository in natural language...".into() - } - - fn confirm(&mut self, cx: &mut ViewContext) { - if let Some(search_result) = self.matches.get(self.selected_match_index) { - // Open Buffer - let search_result = search_result.clone(); - let buffer = self.project.update(cx, |project, cx| { - project.open_buffer( - ProjectPath { - worktree_id: search_result.worktree_id, - path: search_result.file_path.clone().into(), - }, - cx, - ) - }); - - let workspace = self.workspace.clone(); - let position = search_result.clone().byte_range.start; - cx.spawn(|_, mut cx| async move { - let buffer = buffer.await?; - workspace.update(&mut cx, |workspace, cx| { - let editor = workspace.open_project_item::(buffer, cx); - editor.update(cx, |editor, cx| { - editor.change_selections(Some(Autoscroll::center()), cx, |s| { - s.select_ranges([position..position]) - }); - }); - })?; - Ok::<_, anyhow::Error>(()) - }) - .detach_and_log_err(cx); - cx.emit(PickerEvent::Dismiss); - } - } - - fn dismissed(&mut self, _cx: &mut ViewContext) {} - - fn match_count(&self) -> usize { - self.matches.len() - } - - fn selected_index(&self) -> usize { - self.selected_match_index - } - - fn set_selected_index(&mut self, ix: usize, _cx: &mut ViewContext) { - self.selected_match_index = ix; - } - - fn update_matches(&mut self, query: String, cx: &mut ViewContext) -> Task<()> { - log::info!("Searching for {:?}...", query); - if query.len() < MIN_QUERY_LEN { - log::info!("Query below minimum length"); - return Task::ready(()); - } - - let semantic_index = self.semantic_index.clone(); - let project = self.project.clone(); - cx.spawn(|this, mut cx| async move { - cx.background().timer(EMBEDDING_DEBOUNCE_INTERVAL).await; - - let retrieved_cached = this.update(&mut cx, |this, _| { - let delegate = this.delegate_mut(); - if delegate.history.contains_key(&query) { - let historic_results = delegate.history.get(&query).unwrap().to_owned(); - delegate.matches = historic_results.clone(); - true - } else { - false - } - }); - - if let Some(retrieved) = retrieved_cached.log_err() { - if !retrieved { - let task = semantic_index.update(&mut cx, |store, cx| { - store.search_project(project.clone(), query.to_string(), 10, cx) - }); - - if let Some(results) = task.await.log_err() { - log::info!("Not queried previously, searching..."); - this.update(&mut cx, |this, _| { - let delegate = this.delegate_mut(); - delegate.matches = results.clone(); - delegate.history.insert(query, results); - }) - .ok(); - } - } else { - log::info!("Already queried, retrieved directly from cached history"); - } - } - }) - } - - fn render_match( - &self, - ix: usize, - mouse_state: &mut MouseState, - selected: bool, - cx: &AppContext, - ) -> AnyElement> { - let theme = theme::current(cx); - let style = &theme.picker.item; - let current_style = style.in_state(selected).style_for(mouse_state); - - let search_result = &self.matches[ix]; - - let path = search_result.file_path.to_string_lossy(); - let name = search_result.name.clone(); - - Flex::column() - .with_child(Text::new(name, current_style.label.text.clone()).with_soft_wrap(false)) - .with_child(Label::new( - path.to_string(), - style.inactive_state().default.label.clone(), - )) - .contained() - .with_style(current_style.container) - .into_any() - } -} diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index b59b20370aff967de5b2c805da5c693993e0c23e..e6443870aa5312b4a7ea4ecfe72c134841923c66 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -1,6 +1,5 @@ mod db; mod embedding; -mod modal; mod parsing; mod semantic_index_settings; @@ -12,25 +11,20 @@ use anyhow::{anyhow, Result}; use db::VectorDatabase; use embedding::{EmbeddingProvider, OpenAIEmbeddings}; use futures::{channel::oneshot, Future}; -use gpui::{ - AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task, ViewContext, - WeakModelHandle, -}; +use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task, WeakModelHandle}; use language::{Language, LanguageRegistry}; -use modal::{SemanticSearch, SemanticSearchDelegate, Toggle}; use parking_lot::Mutex; use parsing::{CodeContextRetriever, Document, PARSEABLE_ENTIRE_FILE_TYPES}; +use postage::watch; use project::{Fs, Project, WorktreeId}; use smol::channel; use std::{ - collections::{HashMap, HashSet}, + collections::HashMap, + mem, ops::Range, path::{Path, PathBuf}, - sync::{ - atomic::{self, AtomicUsize}, - Arc, Weak, - }, - time::{Instant, SystemTime}, + sync::{Arc, Weak}, + time::SystemTime, }; use util::{ channel::{ReleaseChannel, RELEASE_CHANNEL, RELEASE_CHANNEL_NAME}, @@ -38,9 +32,8 @@ use util::{ paths::EMBEDDINGS_DIR, ResultExt, }; -use workspace::{Workspace, WorkspaceCreated}; -const SEMANTIC_INDEX_VERSION: usize = 1; +const SEMANTIC_INDEX_VERSION: usize = 3; const EMBEDDINGS_BATCH_SIZE: usize = 150; pub fn init( @@ -55,25 +48,6 @@ pub fn init( .join(Path::new(RELEASE_CHANNEL_NAME.as_str())) .join("embeddings_db"); - SemanticSearch::init(cx); - cx.add_action( - |workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext| { - if cx.has_global::>() { - let semantic_index = cx.global::>().clone(); - workspace.toggle_modal(cx, |workspace, cx| { - let project = workspace.project().clone(); - let workspace = cx.weak_handle(); - cx.add_view(|cx| { - SemanticSearch::new( - SemanticSearchDelegate::new(workspace, project, semantic_index), - cx, - ) - }) - }); - } - }, - ); - if *RELEASE_CHANNEL == ReleaseChannel::Stable || !settings::get::(cx).enabled { @@ -95,21 +69,6 @@ pub fn init( cx.update(|cx| { cx.set_global(semantic_index.clone()); - cx.subscribe_global::({ - let semantic_index = semantic_index.clone(); - move |event, cx| { - let workspace = &event.0; - if let Some(workspace) = workspace.upgrade(cx) { - let project = workspace.read(cx).project().clone(); - if project.read(cx).is_local() { - semantic_index.update(cx, |store, cx| { - store.index_project(project, cx).detach(); - }); - } - } - } - }) - .detach(); }); anyhow::Ok(()) @@ -128,20 +87,17 @@ pub struct SemanticIndex { _embed_batch_task: Task<()>, _batch_files_task: Task<()>, _parsing_files_tasks: Vec>, - next_job_id: Arc, projects: HashMap, ProjectState>, } struct ProjectState { worktree_db_ids: Vec<(WorktreeId, i64)>, - outstanding_jobs: Arc>>, + outstanding_job_count_rx: watch::Receiver, + outstanding_job_count_tx: Arc>>, } -type JobId = usize; - struct JobHandle { - id: JobId, - set: Weak>>, + tx: Weak>>, } impl ProjectState { @@ -221,6 +177,14 @@ enum EmbeddingJob { } impl SemanticIndex { + pub fn global(cx: &AppContext) -> Option> { + if cx.has_global::>() { + Some(cx.global::>().clone()) + } else { + None + } + } + async fn new( fs: Arc, database_url: PathBuf, @@ -236,184 +200,69 @@ impl SemanticIndex { .await?; Ok(cx.add_model(|cx| { - // paths_tx -> embeddings_tx -> db_update_tx - - //db_update_tx/rx: Updating Database + // Perform database operations let (db_update_tx, db_update_rx) = channel::unbounded(); - let _db_update_task = cx.background().spawn(async move { - while let Ok(job) = db_update_rx.recv().await { - match job { - DbOperation::InsertFile { - worktree_id, - documents, - path, - mtime, - job_handle, - } => { - db.insert_file(worktree_id, path, mtime, documents) - .log_err(); - drop(job_handle) - } - DbOperation::Delete { worktree_id, path } => { - db.delete_file(worktree_id, path).log_err(); - } - DbOperation::FindOrCreateWorktree { path, sender } => { - let id = db.find_or_create_worktree(&path); - sender.send(id).ok(); - } - DbOperation::FileMTimes { - worktree_id: worktree_db_id, - sender, - } => { - let file_mtimes = db.get_file_mtimes(worktree_db_id); - sender.send(file_mtimes).ok(); - } + let _db_update_task = cx.background().spawn({ + async move { + while let Ok(job) = db_update_rx.recv().await { + Self::run_db_operation(&db, job) } } }); - // embed_tx/rx: Embed Batch and Send to Database + // Group documents into batches and send them to the embedding provider. let (embed_batch_tx, embed_batch_rx) = channel::unbounded::, PathBuf, SystemTime, JobHandle)>>(); let _embed_batch_task = cx.background().spawn({ let db_update_tx = db_update_tx.clone(); let embedding_provider = embedding_provider.clone(); async move { - while let Ok(mut embeddings_queue) = embed_batch_rx.recv().await { - // Construct Batch - let mut batch_documents = vec![]; - for (_, documents, _, _, _) in embeddings_queue.iter() { - batch_documents - .extend(documents.iter().map(|document| document.content.as_str())); - } - - if let Ok(embeddings) = - embedding_provider.embed_batch(batch_documents).await - { - log::trace!( - "created {} embeddings for {} files", - embeddings.len(), - embeddings_queue.len(), - ); - - let mut i = 0; - let mut j = 0; - - for embedding in embeddings.iter() { - while embeddings_queue[i].1.len() == j { - i += 1; - j = 0; - } - - embeddings_queue[i].1[j].embedding = embedding.to_owned(); - j += 1; - } - - for (worktree_id, documents, path, mtime, job_handle) in - embeddings_queue.into_iter() - { - for document in documents.iter() { - // TODO: Update this so it doesn't panic - assert!( - document.embedding.len() > 0, - "Document Embedding Not Complete" - ); - } - - db_update_tx - .send(DbOperation::InsertFile { - worktree_id, - documents, - path, - mtime, - job_handle, - }) - .await - .unwrap(); - } - } + while let Ok(embeddings_queue) = embed_batch_rx.recv().await { + Self::compute_embeddings_for_batch( + embeddings_queue, + &embedding_provider, + &db_update_tx, + ) + .await; } } }); - // batch_tx/rx: Batch Files to Send for Embeddings + // Group documents into batches and send them to the embedding provider. let (batch_files_tx, batch_files_rx) = channel::unbounded::(); let _batch_files_task = cx.background().spawn(async move { let mut queue_len = 0; let mut embeddings_queue = vec![]; - while let Ok(job) = batch_files_rx.recv().await { - let should_flush = match job { - EmbeddingJob::Enqueue { - documents, - worktree_id, - path, - mtime, - job_handle, - } => { - queue_len += &documents.len(); - embeddings_queue.push(( - worktree_id, - documents, - path, - mtime, - job_handle, - )); - queue_len >= EMBEDDINGS_BATCH_SIZE - } - EmbeddingJob::Flush => true, - }; - - if should_flush { - embed_batch_tx.try_send(embeddings_queue).unwrap(); - embeddings_queue = vec![]; - queue_len = 0; - } + Self::enqueue_documents_to_embed( + job, + &mut queue_len, + &mut embeddings_queue, + &embed_batch_tx, + ); } }); - // parsing_files_tx/rx: Parsing Files to Embeddable Documents + // Parse files into embeddable documents. let (parsing_files_tx, parsing_files_rx) = channel::unbounded::(); - let mut _parsing_files_tasks = Vec::new(); for _ in 0..cx.background().num_cpus() { let fs = fs.clone(); let parsing_files_rx = parsing_files_rx.clone(); let batch_files_tx = batch_files_tx.clone(); + let db_update_tx = db_update_tx.clone(); _parsing_files_tasks.push(cx.background().spawn(async move { let mut retriever = CodeContextRetriever::new(); while let Ok(pending_file) = parsing_files_rx.recv().await { - if let Some(content) = fs.load(&pending_file.absolute_path).await.log_err() - { - if let Some(documents) = retriever - .parse_file( - &pending_file.relative_path, - &content, - pending_file.language, - ) - .log_err() - { - log::trace!( - "parsed path {:?}: {} documents", - pending_file.relative_path, - documents.len() - ); - - batch_files_tx - .try_send(EmbeddingJob::Enqueue { - worktree_id: pending_file.worktree_db_id, - path: pending_file.relative_path, - mtime: pending_file.modified_time, - job_handle: pending_file.job_handle, - documents, - }) - .unwrap(); - } - } - - if parsing_files_rx.len() == 0 { - batch_files_tx.try_send(EmbeddingJob::Flush).unwrap(); - } + Self::parse_file( + &fs, + pending_file, + &mut retriever, + &batch_files_tx, + &parsing_files_rx, + &db_update_tx, + ) + .await; } })); } @@ -424,7 +273,6 @@ impl SemanticIndex { embedding_provider, language_registry, db_update_tx, - next_job_id: Default::default(), parsing_files_tx, _db_update_task, _embed_batch_task, @@ -435,6 +283,167 @@ impl SemanticIndex { })) } + fn run_db_operation(db: &VectorDatabase, job: DbOperation) { + match job { + DbOperation::InsertFile { + worktree_id, + documents, + path, + mtime, + job_handle, + } => { + db.insert_file(worktree_id, path, mtime, documents) + .log_err(); + drop(job_handle) + } + DbOperation::Delete { worktree_id, path } => { + db.delete_file(worktree_id, path).log_err(); + } + DbOperation::FindOrCreateWorktree { path, sender } => { + let id = db.find_or_create_worktree(&path); + sender.send(id).ok(); + } + DbOperation::FileMTimes { + worktree_id: worktree_db_id, + sender, + } => { + let file_mtimes = db.get_file_mtimes(worktree_db_id); + sender.send(file_mtimes).ok(); + } + } + } + + async fn compute_embeddings_for_batch( + mut embeddings_queue: Vec<(i64, Vec, PathBuf, SystemTime, JobHandle)>, + embedding_provider: &Arc, + db_update_tx: &channel::Sender, + ) { + let mut batch_documents = vec![]; + for (_, documents, _, _, _) in embeddings_queue.iter() { + batch_documents.extend(documents.iter().map(|document| document.content.as_str())); + } + + if let Ok(embeddings) = embedding_provider.embed_batch(batch_documents).await { + log::trace!( + "created {} embeddings for {} files", + embeddings.len(), + embeddings_queue.len(), + ); + + let mut i = 0; + let mut j = 0; + + for embedding in embeddings.iter() { + while embeddings_queue[i].1.len() == j { + i += 1; + j = 0; + } + + embeddings_queue[i].1[j].embedding = embedding.to_owned(); + j += 1; + } + + for (worktree_id, documents, path, mtime, job_handle) in embeddings_queue.into_iter() { + // for document in documents.iter() { + // // TODO: Update this so it doesn't panic + // assert!( + // document.embedding.len() > 0, + // "Document Embedding Not Complete" + // ); + // } + + db_update_tx + .send(DbOperation::InsertFile { + worktree_id, + documents, + path, + mtime, + job_handle, + }) + .await + .unwrap(); + } + } + } + + fn enqueue_documents_to_embed( + job: EmbeddingJob, + queue_len: &mut usize, + embeddings_queue: &mut Vec<(i64, Vec, PathBuf, SystemTime, JobHandle)>, + embed_batch_tx: &channel::Sender, PathBuf, SystemTime, JobHandle)>>, + ) { + let should_flush = match job { + EmbeddingJob::Enqueue { + documents, + worktree_id, + path, + mtime, + job_handle, + } => { + *queue_len += &documents.len(); + embeddings_queue.push((worktree_id, documents, path, mtime, job_handle)); + *queue_len >= EMBEDDINGS_BATCH_SIZE + } + EmbeddingJob::Flush => true, + }; + + if should_flush { + embed_batch_tx + .try_send(mem::take(embeddings_queue)) + .unwrap(); + *queue_len = 0; + } + } + + async fn parse_file( + fs: &Arc, + pending_file: PendingFile, + retriever: &mut CodeContextRetriever, + batch_files_tx: &channel::Sender, + parsing_files_rx: &channel::Receiver, + db_update_tx: &channel::Sender, + ) { + if let Some(content) = fs.load(&pending_file.absolute_path).await.log_err() { + if let Some(documents) = retriever + .parse_file(&pending_file.relative_path, &content, pending_file.language) + .log_err() + { + log::trace!( + "parsed path {:?}: {} documents", + pending_file.relative_path, + documents.len() + ); + + if documents.len() == 0 { + db_update_tx + .send(DbOperation::InsertFile { + worktree_id: pending_file.worktree_db_id, + documents, + path: pending_file.relative_path, + mtime: pending_file.modified_time, + job_handle: pending_file.job_handle, + }) + .await + .unwrap(); + } else { + batch_files_tx + .try_send(EmbeddingJob::Enqueue { + worktree_id: pending_file.worktree_db_id, + path: pending_file.relative_path, + mtime: pending_file.modified_time, + job_handle: pending_file.job_handle, + documents, + }) + .unwrap(); + } + } + } + + if parsing_files_rx.len() == 0 { + batch_files_tx.try_send(EmbeddingJob::Flush).unwrap(); + } + } + fn find_or_create_worktree(&self, path: PathBuf) -> impl Future> { let (tx, rx) = oneshot::channel(); self.db_update_tx @@ -457,11 +466,11 @@ impl SemanticIndex { async move { rx.await? } } - fn index_project( + pub fn index_project( &mut self, project: ModelHandle, cx: &mut ModelContext, - ) -> Task> { + ) -> Task)>> { let worktree_scans_complete = project .read(cx) .worktrees(cx) @@ -483,7 +492,6 @@ impl SemanticIndex { let language_registry = self.language_registry.clone(); let db_update_tx = self.db_update_tx.clone(); let parsing_files_tx = self.parsing_files_tx.clone(); - let next_job_id = self.next_job_id.clone(); cx.spawn(|this, mut cx| async move { futures::future::join_all(worktree_scans_complete).await; @@ -509,8 +517,8 @@ impl SemanticIndex { ); } - // let mut pending_files: Vec<(PathBuf, ((i64, PathBuf, Arc, SystemTime), SystemTime))> = vec![]; - let outstanding_jobs = Arc::new(Mutex::new(HashSet::new())); + let (job_count_tx, job_count_rx) = watch::channel_with(0); + let job_count_tx = Arc::new(Mutex::new(job_count_tx)); this.update(&mut cx, |this, _| { this.projects.insert( project.downgrade(), @@ -519,7 +527,8 @@ impl SemanticIndex { .iter() .map(|(a, b)| (*a, *b)) .collect(), - outstanding_jobs: outstanding_jobs.clone(), + outstanding_job_count_rx: job_count_rx.clone(), + outstanding_job_count_tx: job_count_tx.clone(), }, ); }); @@ -527,7 +536,6 @@ impl SemanticIndex { cx.background() .spawn(async move { let mut count = 0; - let t0 = Instant::now(); for worktree in worktrees.into_iter() { let mut file_mtimes = worktree_file_mtimes.remove(&worktree.id()).unwrap(); for file in worktree.files(false, 0) { @@ -552,14 +560,11 @@ impl SemanticIndex { .map_or(false, |existing_mtime| existing_mtime == file.mtime); if !already_stored { - log::trace!("sending for parsing: {:?}", path_buf); count += 1; - let job_id = next_job_id.fetch_add(1, atomic::Ordering::SeqCst); + *job_count_tx.lock().borrow_mut() += 1; let job_handle = JobHandle { - id: job_id, - set: Arc::downgrade(&outstanding_jobs), + tx: Arc::downgrade(&job_count_tx), }; - outstanding_jobs.lock().insert(job_id); parsing_files_tx .try_send(PendingFile { worktree_db_id: db_ids_by_worktree_id[&worktree.id()], @@ -582,27 +587,22 @@ impl SemanticIndex { .unwrap(); } } - log::trace!( - "parsing worktree completed in {:?}", - t0.elapsed().as_millis() - ); - Ok(count) + anyhow::Ok((count, job_count_rx)) }) .await }) } - pub fn remaining_files_to_index_for_project( + pub fn outstanding_job_count_rx( &self, project: &ModelHandle, - ) -> Option { + ) -> Option> { Some( self.projects .get(&project.downgrade())? - .outstanding_jobs - .lock() - .len(), + .outstanding_job_count_rx + .clone(), ) } @@ -678,8 +678,9 @@ impl Entity for SemanticIndex { impl Drop for JobHandle { fn drop(&mut self) { - if let Some(set) = self.set.upgrade() { - set.lock().remove(&self.id); + if let Some(tx) = self.tx.upgrade() { + let mut tx = tx.lock(); + *tx.borrow_mut() -= 1; } } } diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index ed48cf256bed1bce335c942b2508d486acf82ce0..2ccc52d64b598e56be41a0aae5284517c9f0b36b 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -88,18 +88,13 @@ async fn test_semantic_index(cx: &mut TestAppContext) { let worktree_id = project.read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() }); - let file_count = store + let (file_count, outstanding_file_count) = store .update(cx, |store, cx| store.index_project(project.clone(), cx)) .await .unwrap(); assert_eq!(file_count, 3); cx.foreground().run_until_parked(); - store.update(cx, |store, _cx| { - assert_eq!( - store.remaining_files_to_index_for_project(&project), - Some(0) - ); - }); + assert_eq!(*outstanding_file_count.borrow(), 0); let search_results = store .update(cx, |store, cx| { @@ -128,19 +123,14 @@ async fn test_semantic_index(cx: &mut TestAppContext) { cx.foreground().run_until_parked(); let prev_embedding_count = embedding_provider.embedding_count(); - let file_count = store + let (file_count, outstanding_file_count) = store .update(cx, |store, cx| store.index_project(project.clone(), cx)) .await .unwrap(); assert_eq!(file_count, 1); cx.foreground().run_until_parked(); - store.update(cx, |store, _cx| { - assert_eq!( - store.remaining_files_to_index_for_project(&project), - Some(0) - ); - }); + assert_eq!(*outstanding_file_count.borrow(), 0); assert_eq!( embedding_provider.embedding_count() - prev_embedding_count, From ed1b1a5ccd58610111eba38373b6ff42a1e05792 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Tue, 18 Jul 2023 11:00:21 -0400 Subject: [PATCH 021/160] update logging for open ai embedding and remove redundant truncation --- crates/semantic_index/src/embedding.rs | 34 ++++++++++++++++---------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/crates/semantic_index/src/embedding.rs b/crates/semantic_index/src/embedding.rs index 5e2025b644c5be8e7089955a80819f7b71229f3e..d41350f321d3b13aea217b322163cf73cca07269 100644 --- a/crates/semantic_index/src/embedding.rs +++ b/crates/semantic_index/src/embedding.rs @@ -67,13 +67,17 @@ impl EmbeddingProvider for DummyEmbeddings { } } -const INPUT_LIMIT: usize = 8190; +const OPENAI_INPUT_LIMIT: usize = 8190; impl OpenAIEmbeddings { + pub fn new(client: Arc, executor: Arc) -> Self { + Self { client, executor } + } + fn truncate(span: String) -> String { let mut tokens = OPENAI_BPE_TOKENIZER.encode_with_special_tokens(span.as_ref()); - if tokens.len() > INPUT_LIMIT { - tokens.truncate(INPUT_LIMIT); + if tokens.len() > OPENAI_INPUT_LIMIT { + tokens.truncate(OPENAI_INPUT_LIMIT); let result = OPENAI_BPE_TOKENIZER.decode(tokens.clone()); if result.is_ok() { let transformed = result.unwrap(); @@ -115,6 +119,7 @@ impl EmbeddingProvider for OpenAIEmbeddings { .ok_or_else(|| anyhow!("no api key"))?; let mut request_number = 0; + let mut truncated = false; let mut response: Response; let mut spans: Vec = spans.iter().map(|x| x.to_string()).collect(); while request_number < MAX_RETRIES { @@ -136,15 +141,18 @@ impl EmbeddingProvider for OpenAIEmbeddings { self.executor.timer(delay).await; } StatusCode::BAD_REQUEST => { - log::info!( - "BAD REQUEST: {:?} {:?}", - &response.status(), - response.body() - ); - // Don't worry about delaying bad request, as we can assume - // we haven't been rate limited yet. - for span in spans.iter_mut() { - *span = Self::truncate(span.to_string()); + // Only truncate if it hasnt been truncated before + if !truncated { + for span in spans.iter_mut() { + *span = Self::truncate(span.clone()); + } + truncated = true; + } else { + // If failing once already truncated, log the error and break the loop + let mut body = String::new(); + response.body_mut().read_to_string(&mut body).await?; + log::trace!("open ai bad request: {:?} {:?}", &response.status(), body); + break; } } StatusCode::OK => { @@ -152,7 +160,7 @@ impl EmbeddingProvider for OpenAIEmbeddings { response.body_mut().read_to_string(&mut body).await?; let response: OpenAIEmbeddingResponse = serde_json::from_str(&body)?; - log::info!( + log::trace!( "openai embedding completed. tokens: {:?}", response.usage.total_tokens ); From 80ef92a3e158618d9dcc255fe8689b8597aacb4d Mon Sep 17 00:00:00 2001 From: KCaverly Date: Tue, 18 Jul 2023 11:14:13 -0400 Subject: [PATCH 022/160] fix db schema update process to ensure all tables are dropped --- crates/semantic_index/src/db.rs | 25 ++++++++++++--------- crates/semantic_index/src/semantic_index.rs | 10 +-------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/crates/semantic_index/src/db.rs b/crates/semantic_index/src/db.rs index a667ff877c2e02c65e669e10b7fdbc07e319653b..74e1021b152f4bdaf36e3b780d9288bed374466b 100644 --- a/crates/semantic_index/src/db.rs +++ b/crates/semantic_index/src/db.rs @@ -66,24 +66,28 @@ impl VectorDatabase { fn initialize_database(&self) -> Result<()> { rusqlite::vtab::array::load_module(&self.db)?; + // Delete existing tables, if SEMANTIC_INDEX_VERSION is bumped if self .get_existing_version() .map_or(false, |version| version == SEMANTIC_INDEX_VERSION as i64) { + log::trace!("vector database schema up to date"); return Ok(()); } + log::trace!("vector database schema out of date. updating..."); self.db - .execute( - " - DROP TABLE IF EXISTS documents; - DROP TABLE IF EXISTS files; - DROP TABLE IF EXISTS worktrees; - DROP TABLE IF EXISTS semantic_index_config; - ", - [], - ) - .context("failed to drop tables")?; + .execute("DROP TABLE IF EXISTS documents", []) + .context("failed to drop 'documents' table")?; + self.db + .execute("DROP TABLE IF EXISTS files", []) + .context("failed to drop 'files' table")?; + self.db + .execute("DROP TABLE IF EXISTS worktrees", []) + .context("failed to drop 'worktrees' table")?; + self.db + .execute("DROP TABLE IF EXISTS semantic_index_config", []) + .context("failed to drop 'semantic_index_config' table")?; // Initialize Vector Databasing Tables self.db.execute( @@ -133,6 +137,7 @@ impl VectorDatabase { [], )?; + log::trace!("vector database initialized with updated schema."); Ok(()) } diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index e6443870aa5312b4a7ea4ecfe72c134841923c66..f6575f6ad7188dbaf7ba56160d72cc12f678de10 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -33,7 +33,7 @@ use util::{ ResultExt, }; -const SEMANTIC_INDEX_VERSION: usize = 3; +const SEMANTIC_INDEX_VERSION: usize = 4; const EMBEDDINGS_BATCH_SIZE: usize = 150; pub fn init( @@ -344,14 +344,6 @@ impl SemanticIndex { } for (worktree_id, documents, path, mtime, job_handle) in embeddings_queue.into_iter() { - // for document in documents.iter() { - // // TODO: Update this so it doesn't panic - // assert!( - // document.embedding.len() > 0, - // "Document Embedding Not Complete" - // ); - // } - db_update_tx .send(DbOperation::InsertFile { worktree_id, From 8d0614ce741a7cd279777bd16dcff6349105f077 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 18 Jul 2023 11:44:58 -0700 Subject: [PATCH 023/160] Populate project search results multi-buffer from semantic search Co-authored-by: Kyle --- crates/search/src/project_search.rs | 73 +++++++++++++------ crates/semantic_index/src/db.rs | 16 ++-- crates/semantic_index/src/embedding.rs | 5 -- crates/semantic_index/src/semantic_index.rs | 68 +++++++++-------- .../src/semantic_index_tests.rs | 15 ++-- 5 files changed, 104 insertions(+), 73 deletions(-) diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 91d2b142ae27c3b1579d99b04fe6cb8b6f745705..1097969c00efca6c025da6193251e480b943d7aa 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -2,7 +2,7 @@ use crate::{ SearchOption, SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleRegex, ToggleWholeWord, }; -use anyhow::{Context, Result}; +use anyhow::Result; use collections::HashMap; use editor::{ items::active_match_index, scroll::autoscroll::Autoscroll, Anchor, Editor, MultiBuffer, @@ -187,6 +187,53 @@ impl ProjectSearch { })); cx.notify(); } + + fn semantic_search(&mut self, query: String, cx: &mut ModelContext) -> Option<()> { + let project = self.project.clone(); + let semantic_index = SemanticIndex::global(cx)?; + let search_task = semantic_index.update(cx, |semantic_index, cx| { + semantic_index.search_project(project, query.clone(), 10, cx) + }); + + self.search_id += 1; + // self.active_query = Some(query); + self.match_ranges.clear(); + self.pending_search = Some(cx.spawn(|this, mut cx| async move { + let results = search_task.await.log_err()?; + + let (_task, mut match_ranges) = this.update(&mut cx, |this, cx| { + this.excerpts.update(cx, |excerpts, cx| { + excerpts.clear(cx); + + let matches = results + .into_iter() + .map(|result| (result.buffer, vec![result.range])) + .collect(); + + excerpts.stream_excerpts_with_context_lines(matches, 3, cx) + }) + }); + + while let Some(match_range) = match_ranges.next().await { + this.update(&mut cx, |this, cx| { + this.match_ranges.push(match_range); + while let Ok(Some(match_range)) = match_ranges.try_next() { + this.match_ranges.push(match_range); + } + cx.notify(); + }); + } + + this.update(&mut cx, |this, cx| { + this.pending_search.take(); + cx.notify(); + }); + + None + })); + + Some(()) + } } pub enum ViewEvent { @@ -595,27 +642,9 @@ impl ProjectSearchView { return; } - let search_phrase = self.query_editor.read(cx).text(cx); - let project = self.model.read(cx).project.clone(); - if let Some(semantic_index) = SemanticIndex::global(cx) { - let search_task = semantic_index.update(cx, |semantic_index, cx| { - semantic_index.search_project(project, search_phrase, 10, cx) - }); - semantic.search_task = Some(cx.spawn(|this, mut cx| async move { - let results = search_task.await.context("search task")?; - - this.update(&mut cx, |this, cx| { - dbg!(&results); - // TODO: Update results - - if let Some(semantic) = &mut this.semantic { - semantic.search_task = None; - } - })?; - - anyhow::Ok(()) - })); - } + let query = self.query_editor.read(cx).text(cx); + self.model + .update(cx, |model, cx| model.semantic_search(query, cx)); return; } diff --git a/crates/semantic_index/src/db.rs b/crates/semantic_index/src/db.rs index 74e1021b152f4bdaf36e3b780d9288bed374466b..fd99594aab578919f80bd8236270b352a8540993 100644 --- a/crates/semantic_index/src/db.rs +++ b/crates/semantic_index/src/db.rs @@ -252,7 +252,7 @@ impl VectorDatabase { worktree_ids: &[i64], query_embedding: &Vec, limit: usize, - ) -> Result, String)>> { + ) -> Result)>> { let mut results = Vec::<(i64, f32)>::with_capacity(limit + 1); self.for_each_document(&worktree_ids, |id, embedding| { let similarity = dot(&embedding, &query_embedding); @@ -296,10 +296,7 @@ impl VectorDatabase { Ok(()) } - fn get_documents_by_ids( - &self, - ids: &[i64], - ) -> Result, String)>> { + fn get_documents_by_ids(&self, ids: &[i64]) -> Result)>> { let mut statement = self.db.prepare( " SELECT @@ -307,7 +304,7 @@ impl VectorDatabase { files.worktree_id, files.relative_path, documents.start_byte, - documents.end_byte, documents.name + documents.end_byte FROM documents, files WHERE @@ -322,14 +319,13 @@ impl VectorDatabase { row.get::<_, i64>(1)?, row.get::<_, String>(2)?.into(), row.get(3)?..row.get(4)?, - row.get(5)?, )) })?; - let mut values_by_id = HashMap::, String)>::default(); + let mut values_by_id = HashMap::)>::default(); for row in result_iter { - let (id, worktree_id, path, range, name) = row?; - values_by_id.insert(id, (worktree_id, path, range, name)); + let (id, worktree_id, path, range) = row?; + values_by_id.insert(id, (worktree_id, path, range)); } let mut results = Vec::with_capacity(ids.len()); diff --git a/crates/semantic_index/src/embedding.rs b/crates/semantic_index/src/embedding.rs index d41350f321d3b13aea217b322163cf73cca07269..728fc9283a1ebcaf13bd035ac3fd0766c9112913 100644 --- a/crates/semantic_index/src/embedding.rs +++ b/crates/semantic_index/src/embedding.rs @@ -70,10 +70,6 @@ impl EmbeddingProvider for DummyEmbeddings { const OPENAI_INPUT_LIMIT: usize = 8190; impl OpenAIEmbeddings { - pub fn new(client: Arc, executor: Arc) -> Self { - Self { client, executor } - } - fn truncate(span: String) -> String { let mut tokens = OPENAI_BPE_TOKENIZER.encode_with_special_tokens(span.as_ref()); if tokens.len() > OPENAI_INPUT_LIMIT { @@ -81,7 +77,6 @@ impl OpenAIEmbeddings { let result = OPENAI_BPE_TOKENIZER.decode(tokens.clone()); if result.is_ok() { let transformed = result.unwrap(); - // assert_ne!(transformed, span); return transformed; } } diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index f6575f6ad7188dbaf7ba56160d72cc12f678de10..5c6919d4fd46ee80d2e82515a3710cff044a4e10 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -12,7 +12,7 @@ use db::VectorDatabase; use embedding::{EmbeddingProvider, OpenAIEmbeddings}; use futures::{channel::oneshot, Future}; use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task, WeakModelHandle}; -use language::{Language, LanguageRegistry}; +use language::{Anchor, Buffer, Language, LanguageRegistry}; use parking_lot::Mutex; use parsing::{CodeContextRetriever, Document, PARSEABLE_ENTIRE_FILE_TYPES}; use postage::watch; @@ -93,7 +93,7 @@ pub struct SemanticIndex { struct ProjectState { worktree_db_ids: Vec<(WorktreeId, i64)>, outstanding_job_count_rx: watch::Receiver, - outstanding_job_count_tx: Arc>>, + _outstanding_job_count_tx: Arc>>, } struct JobHandle { @@ -135,12 +135,9 @@ pub struct PendingFile { job_handle: JobHandle, } -#[derive(Debug, Clone)] pub struct SearchResult { - pub worktree_id: WorktreeId, - pub name: String, - pub byte_range: Range, - pub file_path: PathBuf, + pub buffer: ModelHandle, + pub range: Range, } enum DbOperation { @@ -520,7 +517,7 @@ impl SemanticIndex { .map(|(a, b)| (*a, *b)) .collect(), outstanding_job_count_rx: job_count_rx.clone(), - outstanding_job_count_tx: job_count_tx.clone(), + _outstanding_job_count_tx: job_count_tx.clone(), }, ); }); @@ -623,7 +620,7 @@ impl SemanticIndex { let embedding_provider = self.embedding_provider.clone(); let database_url = self.database_url.clone(); let fs = self.fs.clone(); - cx.spawn(|this, cx| async move { + cx.spawn(|this, mut cx| async move { let documents = cx .background() .spawn(async move { @@ -640,26 +637,39 @@ impl SemanticIndex { }) .await?; - this.read_with(&cx, |this, _| { - let project_state = if let Some(state) = this.projects.get(&project.downgrade()) { - state - } else { - return Err(anyhow!("project not added")); - }; - - Ok(documents - .into_iter() - .filter_map(|(worktree_db_id, file_path, byte_range, name)| { - let worktree_id = project_state.worktree_id_for_db_id(worktree_db_id)?; - Some(SearchResult { - worktree_id, - name, - byte_range, - file_path, - }) - }) - .collect()) - }) + let mut tasks = Vec::new(); + let mut ranges = Vec::new(); + let weak_project = project.downgrade(); + project.update(&mut cx, |project, cx| { + for (worktree_db_id, file_path, byte_range) in documents { + let project_state = + if let Some(state) = this.read(cx).projects.get(&weak_project) { + state + } else { + return Err(anyhow!("project not added")); + }; + if let Some(worktree_id) = project_state.worktree_id_for_db_id(worktree_db_id) { + tasks.push(project.open_buffer((worktree_id, file_path), cx)); + ranges.push(byte_range); + } + } + + Ok(()) + })?; + + let buffers = futures::future::join_all(tasks).await; + + Ok(buffers + .into_iter() + .zip(ranges) + .filter_map(|(buffer, range)| { + let buffer = buffer.log_err()?; + let range = buffer.read_with(&cx, |buffer, _| { + buffer.anchor_before(range.start)..buffer.anchor_after(range.end) + }); + Some(SearchResult { buffer, range }) + }) + .collect::>()) }) } } diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index 2ccc52d64b598e56be41a0aae5284517c9f0b36b..63b28798ad91d67d6786b4b420900135050dfe5b 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -8,7 +8,7 @@ use crate::{ use anyhow::Result; use async_trait::async_trait; use gpui::{Task, TestAppContext}; -use language::{Language, LanguageConfig, LanguageRegistry}; +use language::{Language, LanguageConfig, LanguageRegistry, ToOffset}; use project::{project_settings::ProjectSettings, FakeFs, Fs, Project}; use rand::{rngs::StdRng, Rng}; use serde_json::json; @@ -85,9 +85,6 @@ async fn test_semantic_index(cx: &mut TestAppContext) { .unwrap(); let project = Project::test(fs.clone(), ["/the-root".as_ref()], cx).await; - let worktree_id = project.read_with(cx, |project, cx| { - project.worktrees(cx).next().unwrap().read(cx).id() - }); let (file_count, outstanding_file_count) = store .update(cx, |store, cx| store.index_project(project.clone(), cx)) .await @@ -103,9 +100,13 @@ async fn test_semantic_index(cx: &mut TestAppContext) { .await .unwrap(); - assert_eq!(search_results[0].byte_range.start, 0); - assert_eq!(search_results[0].name, "aaa"); - assert_eq!(search_results[0].worktree_id, worktree_id); + search_results[0].buffer.read_with(cx, |buffer, _cx| { + assert_eq!(search_results[0].range.start.to_offset(buffer), 0); + assert_eq!( + buffer.file().unwrap().path().as_ref(), + Path::new("file1.rs") + ); + }); fs.save( "/the-root/src/file2.rs".as_ref(), From 342dbc69459d771f802d7e77fdd7fb20f7445d1f Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 18 Jul 2023 12:01:42 -0700 Subject: [PATCH 024/160] Fix rendering of project search while semantic index is indexing or running Co-authored-by: Kyle --- crates/search/src/project_search.rs | 32 +++++++++++++---------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 1097969c00efca6c025da6193251e480b943d7aa..5feb94426eb60c67a756c564982a826699bd20a1 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -110,7 +110,6 @@ struct SemanticSearchState { file_count: usize, outstanding_file_count: usize, _progress_task: Task<()>, - search_task: Option>>, } pub struct ProjectSearchBar { @@ -188,18 +187,17 @@ impl ProjectSearch { cx.notify(); } - fn semantic_search(&mut self, query: String, cx: &mut ModelContext) -> Option<()> { - let project = self.project.clone(); - let semantic_index = SemanticIndex::global(cx)?; - let search_task = semantic_index.update(cx, |semantic_index, cx| { - semantic_index.search_project(project, query.clone(), 10, cx) + fn semantic_search(&mut self, query: String, cx: &mut ModelContext) { + let search = SemanticIndex::global(cx).map(|index| { + index.update(cx, |semantic_index, cx| { + semantic_index.search_project(self.project.clone(), query.clone(), 10, cx) + }) }); - self.search_id += 1; // self.active_query = Some(query); self.match_ranges.clear(); self.pending_search = Some(cx.spawn(|this, mut cx| async move { - let results = search_task.await.log_err()?; + let results = search?.await.log_err()?; let (_task, mut match_ranges) = this.update(&mut cx, |this, cx| { this.excerpts.update(cx, |excerpts, cx| { @@ -231,8 +229,7 @@ impl ProjectSearch { None })); - - Some(()) + cx.notify(); } } @@ -257,12 +254,10 @@ impl View for ProjectSearchView { enum Status {} let theme = theme::current(cx).clone(); - let text = if self.query_editor.read(cx).text(cx).is_empty() { - Cow::Borrowed("") + let text = if model.pending_search.is_some() { + Cow::Borrowed("Searching...") } else if let Some(semantic) = &self.semantic { - if semantic.search_task.is_some() { - Cow::Borrowed("Searching...") - } else if semantic.outstanding_file_count > 0 { + if semantic.outstanding_file_count > 0 { Cow::Owned(format!( "Indexing. {} of {}...", semantic.file_count - semantic.outstanding_file_count, @@ -271,8 +266,8 @@ impl View for ProjectSearchView { } else { Cow::Borrowed("Indexing complete") } - } else if model.pending_search.is_some() { - Cow::Borrowed("Searching...") + } else if self.query_editor.read(cx).text(cx).is_empty() { + Cow::Borrowed("") } else { Cow::Borrowed("No results") }; @@ -978,10 +973,10 @@ impl ProjectSearchBar { let (files_to_index, mut files_remaining_rx) = index_task.await?; search_view.update(&mut cx, |search_view, cx| { + cx.notify(); search_view.semantic = Some(SemanticSearchState { file_count: files_to_index, outstanding_file_count: files_to_index, - search_task: None, _progress_task: cx.spawn(|search_view, mut cx| async move { while let Some(count) = files_remaining_rx.recv().await { search_view @@ -1006,6 +1001,7 @@ impl ProjectSearchBar { }) .detach_and_log_err(cx); } + cx.notify(); }); cx.notify(); true From 0e071919a07967f781f87c060c5c94168a844ba6 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Tue, 18 Jul 2023 16:09:44 -0400 Subject: [PATCH 025/160] parellelize embedding api calls --- crates/semantic_index/src/embedding.rs | 6 ++- crates/semantic_index/src/semantic_index.rs | 54 ++++++++++++++------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/crates/semantic_index/src/embedding.rs b/crates/semantic_index/src/embedding.rs index 728fc9283a1ebcaf13bd035ac3fd0766c9112913..77457ec7f6e34961ab2a784ef6f0d8068c4c1dbb 100644 --- a/crates/semantic_index/src/embedding.rs +++ b/crates/semantic_index/src/embedding.rs @@ -106,7 +106,7 @@ impl OpenAIEmbeddings { #[async_trait] impl EmbeddingProvider for OpenAIEmbeddings { async fn embed_batch(&self, spans: Vec<&str>) -> Result>> { - const BACKOFF_SECONDS: [usize; 3] = [65, 180, 360]; + const BACKOFF_SECONDS: [usize; 3] = [45, 75, 125]; const MAX_RETRIES: usize = 3; let api_key = OPENAI_API_KEY @@ -133,6 +133,10 @@ impl EmbeddingProvider for OpenAIEmbeddings { match response.status() { StatusCode::TOO_MANY_REQUESTS => { let delay = Duration::from_secs(BACKOFF_SECONDS[request_number - 1] as u64); + log::trace!( + "open ai rate limiting, delaying request by {:?} seconds", + delay.as_secs() + ); self.executor.timer(delay).await; } StatusCode::BAD_REQUEST => { diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 5c6919d4fd46ee80d2e82515a3710cff044a4e10..44ce45f457004c7167f8c61501c2b03ca239d199 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -24,7 +24,7 @@ use std::{ ops::Range, path::{Path, PathBuf}, sync::{Arc, Weak}, - time::SystemTime, + time::{Instant, SystemTime}, }; use util::{ channel::{ReleaseChannel, RELEASE_CHANNEL, RELEASE_CHANNEL_NAME}, @@ -34,7 +34,7 @@ use util::{ }; const SEMANTIC_INDEX_VERSION: usize = 4; -const EMBEDDINGS_BATCH_SIZE: usize = 150; +const EMBEDDINGS_BATCH_SIZE: usize = 80; pub fn init( fs: Arc, @@ -84,7 +84,7 @@ pub struct SemanticIndex { db_update_tx: channel::Sender, parsing_files_tx: channel::Sender, _db_update_task: Task<()>, - _embed_batch_task: Task<()>, + _embed_batch_tasks: Vec>, _batch_files_task: Task<()>, _parsing_files_tasks: Vec>, projects: HashMap, ProjectState>, @@ -189,6 +189,7 @@ impl SemanticIndex { language_registry: Arc, mut cx: AsyncAppContext, ) -> Result> { + let t0 = Instant::now(); let database_url = Arc::new(database_url); let db = cx @@ -196,7 +197,13 @@ impl SemanticIndex { .spawn(VectorDatabase::new(fs.clone(), database_url.clone())) .await?; + log::trace!( + "db initialization took {:?} milliseconds", + t0.elapsed().as_millis() + ); + Ok(cx.add_model(|cx| { + let t0 = Instant::now(); // Perform database operations let (db_update_tx, db_update_rx) = channel::unbounded(); let _db_update_task = cx.background().spawn({ @@ -210,20 +217,24 @@ impl SemanticIndex { // Group documents into batches and send them to the embedding provider. let (embed_batch_tx, embed_batch_rx) = channel::unbounded::, PathBuf, SystemTime, JobHandle)>>(); - let _embed_batch_task = cx.background().spawn({ - let db_update_tx = db_update_tx.clone(); - let embedding_provider = embedding_provider.clone(); - async move { - while let Ok(embeddings_queue) = embed_batch_rx.recv().await { - Self::compute_embeddings_for_batch( - embeddings_queue, - &embedding_provider, - &db_update_tx, - ) - .await; + let mut _embed_batch_tasks = Vec::new(); + for _ in 0..cx.background().num_cpus() { + let embed_batch_rx = embed_batch_rx.clone(); + _embed_batch_tasks.push(cx.background().spawn({ + let db_update_tx = db_update_tx.clone(); + let embedding_provider = embedding_provider.clone(); + async move { + while let Ok(embeddings_queue) = embed_batch_rx.recv().await { + Self::compute_embeddings_for_batch( + embeddings_queue, + &embedding_provider, + &db_update_tx, + ) + .await; + } } - } - }); + })); + } // Group documents into batches and send them to the embedding provider. let (batch_files_tx, batch_files_rx) = channel::unbounded::(); @@ -264,6 +275,10 @@ impl SemanticIndex { })); } + log::trace!( + "semantic index task initialization took {:?} milliseconds", + t0.elapsed().as_millis() + ); Self { fs, database_url, @@ -272,7 +287,7 @@ impl SemanticIndex { db_update_tx, parsing_files_tx, _db_update_task, - _embed_batch_task, + _embed_batch_tasks, _batch_files_task, _parsing_files_tasks, projects: HashMap::new(), @@ -460,6 +475,7 @@ impl SemanticIndex { project: ModelHandle, cx: &mut ModelContext, ) -> Task)>> { + let t0 = Instant::now(); let worktree_scans_complete = project .read(cx) .worktrees(cx) @@ -577,6 +593,10 @@ impl SemanticIndex { } } + log::trace!( + "walking worktree took {:?} milliseconds", + t0.elapsed().as_millis() + ); anyhow::Ok((count, job_count_rx)) }) .await From 9809ec3d706a19cd409a8a7494fabc06803e0ed7 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Wed, 19 Jul 2023 15:47:05 -0400 Subject: [PATCH 026/160] update treesitter parsing to accomodate for collapsed nested functions Co-authored-by: maxbrunsfeld --- Cargo.lock | 3 +- Cargo.toml | 2 +- crates/language/src/language.rs | 22 + crates/semantic_index/Cargo.toml | 1 + crates/semantic_index/src/parsing.rs | 257 +++- crates/semantic_index/src/semantic_index.rs | 8 +- .../src/semantic_index_tests.rs | 1079 +++++++++-------- crates/zed/src/languages/rust/config.toml | 1 + crates/zed/src/languages/rust/embedding.scm | 64 +- 9 files changed, 813 insertions(+), 624 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7719eb24c228613114bf999f207629ba0c6d4664..8ea6f61da04f215b91b31941ccce795be778a204 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6486,6 +6486,7 @@ dependencies = [ "parking_lot 0.11.2", "picker", "postage", + "pretty_assertions", "project", "rand 0.8.5", "rpc", @@ -7991,7 +7992,7 @@ dependencies = [ [[package]] name = "tree-sitter" version = "0.20.10" -source = "git+https://github.com/tree-sitter/tree-sitter?rev=49226023693107fba9a1191136a4f47f38cdca73#49226023693107fba9a1191136a4f47f38cdca73" +source = "git+https://github.com/tree-sitter/tree-sitter?rev=1c65ca24bc9a734ab70115188f465e12eecf224e#1c65ca24bc9a734ab70115188f465e12eecf224e" dependencies = [ "cc", "regex", diff --git a/Cargo.toml b/Cargo.toml index 4b6574534845456623d8c1a6510c15817c2b6151..04f2147431ffe183de21e250885ce16b28166ec9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -130,7 +130,7 @@ tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml", tree-sitter-lua = "0.0.14" [patch.crates-io] -tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "49226023693107fba9a1191136a4f47f38cdca73" } +tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "1c65ca24bc9a734ab70115188f465e12eecf224e" } async-task = { git = "https://github.com/zed-industries/async-task", rev = "341b57d6de98cdfd7b418567b8de2022ca993a6e" } # TODO - Remove when a version is released with this PR: https://github.com/servo/core-foundation-rs/pull/457 diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 8c6d6e9c09f17f48c58c42e3d67d144ceb7e56cb..ec233716d6ce5345515600b14e00a212b3dcb3a5 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -339,6 +339,8 @@ pub struct LanguageConfig { #[serde(default)] pub line_comment: Option>, #[serde(default)] + pub collapsed_placeholder: String, + #[serde(default)] pub block_comment: Option<(Arc, Arc)>, #[serde(default)] pub overrides: HashMap, @@ -408,6 +410,7 @@ impl Default for LanguageConfig { line_comment: Default::default(), block_comment: Default::default(), overrides: Default::default(), + collapsed_placeholder: Default::default(), } } } @@ -525,6 +528,8 @@ pub struct EmbeddingConfig { pub item_capture_ix: u32, pub name_capture_ix: u32, pub context_capture_ix: Option, + pub collapse_capture_ix: Option, + pub keep_capture_ix: Option, } struct InjectionConfig { @@ -1246,12 +1251,16 @@ impl Language { let mut item_capture_ix = None; let mut name_capture_ix = None; let mut context_capture_ix = None; + let mut collapse_capture_ix = None; + let mut keep_capture_ix = None; get_capture_indices( &query, &mut [ ("item", &mut item_capture_ix), ("name", &mut name_capture_ix), ("context", &mut context_capture_ix), + ("keep", &mut keep_capture_ix), + ("collapse", &mut collapse_capture_ix), ], ); if let Some((item_capture_ix, name_capture_ix)) = item_capture_ix.zip(name_capture_ix) { @@ -1260,6 +1269,8 @@ impl Language { item_capture_ix, name_capture_ix, context_capture_ix, + collapse_capture_ix, + keep_capture_ix, }); } Ok(self) @@ -1544,9 +1555,20 @@ impl Language { pub fn grammar(&self) -> Option<&Arc> { self.grammar.as_ref() } + + pub fn default_scope(self: &Arc) -> LanguageScope { + LanguageScope { + language: self.clone(), + override_id: None, + } + } } impl LanguageScope { + pub fn collapsed_placeholder(&self) -> &str { + self.language.config.collapsed_placeholder.as_ref() + } + pub fn line_comment_prefix(&self) -> Option<&Arc> { Override::as_option( self.config_override().map(|o| &o.line_comment), diff --git a/crates/semantic_index/Cargo.toml b/crates/semantic_index/Cargo.toml index 2d21ff6c1c42710e597101cd024fdde9183bcbc5..1b3169bfe41940eef5c863901c560e106acf4816 100644 --- a/crates/semantic_index/Cargo.toml +++ b/crates/semantic_index/Cargo.toml @@ -46,6 +46,7 @@ rpc = { path = "../rpc", features = ["test-support"] } workspace = { path = "../workspace", features = ["test-support"] } settings = { path = "../settings", features = ["test-support"]} +pretty_assertions.workspace = true rand.workspace = true unindent.workspace = true tempdir.workspace = true diff --git a/crates/semantic_index/src/parsing.rs b/crates/semantic_index/src/parsing.rs index 663f0f473b63358496c8dcbc337aa7ccbe452c76..0d2aeb60fb24dcb347c3a0f870ef6e348e08a88a 100644 --- a/crates/semantic_index/src/parsing.rs +++ b/crates/semantic_index/src/parsing.rs @@ -1,6 +1,6 @@ use anyhow::{anyhow, Ok, Result}; -use language::Language; -use std::{ops::Range, path::Path, sync::Arc}; +use language::{Grammar, Language}; +use std::{cmp, collections::HashSet, ops::Range, path::Path, sync::Arc}; use tree_sitter::{Parser, QueryCursor}; #[derive(Debug, PartialEq, Clone)] @@ -22,6 +22,20 @@ pub struct CodeContextRetriever { pub cursor: QueryCursor, } +// Every match has an item, this represents the fundamental treesitter symbol and anchors the search +// Every match has one or more 'name' captures. These indicate the display range of the item for deduplication. +// If there are preceeding comments, we track this with a context capture +// If there is a piece that should be collapsed in hierarchical queries, we capture it with a collapse capture +// If there is a piece that should be kept inside a collapsed node, we capture it with a keep capture +#[derive(Debug, Clone)] +pub struct CodeContextMatch { + pub start_col: usize, + pub item_range: Range, + pub name_range: Range, + pub context_ranges: Vec>, + pub collapse_ranges: Vec>, +} + impl CodeContextRetriever { pub fn new() -> Self { Self { @@ -49,24 +63,15 @@ impl CodeContextRetriever { }]) } - pub fn parse_file( + fn get_matches_in_file( &mut self, - relative_path: &Path, content: &str, - language: Arc, - ) -> Result> { - if PARSEABLE_ENTIRE_FILE_TYPES.contains(&language.name().as_ref()) { - return self._parse_entire_file(relative_path, language.name(), &content); - } - - let grammar = language - .grammar() - .ok_or_else(|| anyhow!("no grammar for language"))?; + grammar: &Arc, + ) -> Result> { let embedding_config = grammar .embedding_config .as_ref() .ok_or_else(|| anyhow!("no embedding queries"))?; - self.parser.set_language(grammar.ts_language).unwrap(); let tree = self @@ -74,66 +79,204 @@ impl CodeContextRetriever { .parse(&content, None) .ok_or_else(|| anyhow!("parsing failed"))?; - let mut documents = Vec::new(); - - // Iterate through query matches - let mut name_ranges: Vec> = vec![]; + let mut captures: Vec = Vec::new(); + let mut collapse_ranges: Vec> = Vec::new(); + let mut keep_ranges: Vec> = Vec::new(); for mat in self.cursor.matches( &embedding_config.query, tree.root_node(), content.as_bytes(), ) { - let mut name: Vec<&str> = vec![]; - let mut item: Option<&str> = None; - let mut byte_range: Option> = None; - let mut context_spans: Vec<&str> = vec![]; + let mut start_col = 0; + let mut item_range: Option> = None; + let mut name_range: Option> = None; + let mut context_ranges: Vec> = Vec::new(); + collapse_ranges.clear(); + keep_ranges.clear(); for capture in mat.captures { if capture.index == embedding_config.item_capture_ix { - byte_range = Some(capture.node.byte_range()); - item = content.get(capture.node.byte_range()); + item_range = Some(capture.node.byte_range()); + start_col = capture.node.start_position().column; } else if capture.index == embedding_config.name_capture_ix { - let name_range = capture.node.byte_range(); - if name_ranges.contains(&name_range) { - continue; - } - name_ranges.push(name_range.clone()); - if let Some(name_content) = content.get(name_range.clone()) { - name.push(name_content); - } + name_range = Some(capture.node.byte_range()); + } else if Some(capture.index) == embedding_config.context_capture_ix { + context_ranges.push(capture.node.byte_range()); + } else if Some(capture.index) == embedding_config.collapse_capture_ix { + collapse_ranges.push(capture.node.byte_range()); + } else if Some(capture.index) == embedding_config.keep_capture_ix { + keep_ranges.push(capture.node.byte_range()); } + } - if let Some(context_capture_ix) = embedding_config.context_capture_ix { - if capture.index == context_capture_ix { - if let Some(context) = content.get(capture.node.byte_range()) { - context_spans.push(context); - } - } + if item_range.is_some() && name_range.is_some() { + let item_range = item_range.unwrap(); + captures.push(CodeContextMatch { + start_col, + item_range, + name_range: name_range.unwrap(), + context_ranges, + collapse_ranges: subtract_ranges(&collapse_ranges, &keep_ranges), + }); + } + } + Ok(captures) + } + + pub fn parse_file_with_template( + &mut self, + relative_path: &Path, + content: &str, + language: Arc, + ) -> Result> { + let language_name = language.name(); + let mut documents = self.parse_file(relative_path, content, language)?; + for document in &mut documents { + document.content = CODE_CONTEXT_TEMPLATE + .replace("", relative_path.to_string_lossy().as_ref()) + .replace("", language_name.as_ref()) + .replace("item", &document.content); + } + Ok(documents) + } + + pub fn parse_file( + &mut self, + relative_path: &Path, + content: &str, + language: Arc, + ) -> Result> { + if PARSEABLE_ENTIRE_FILE_TYPES.contains(&language.name().as_ref()) { + return self._parse_entire_file(relative_path, language.name(), &content); + } + + let grammar = language + .grammar() + .ok_or_else(|| anyhow!("no grammar for language"))?; + + // Iterate through query matches + let matches = self.get_matches_in_file(content, grammar)?; + + let language_scope = language.default_scope(); + let placeholder = language_scope.collapsed_placeholder(); + + let mut documents = Vec::new(); + let mut collapsed_ranges_within = Vec::new(); + let mut parsed_name_ranges = HashSet::new(); + for (i, context_match) in matches.iter().enumerate() { + if parsed_name_ranges.contains(&context_match.name_range) { + continue; + } + + collapsed_ranges_within.clear(); + for remaining_match in &matches[(i + 1)..] { + if context_match + .item_range + .contains(&remaining_match.item_range.start) + && context_match + .item_range + .contains(&remaining_match.item_range.end) + { + collapsed_ranges_within.extend(remaining_match.collapse_ranges.iter().cloned()); + } else { + break; } } - if let Some((item, byte_range)) = item.zip(byte_range) { - if !name.is_empty() { - let item = if context_spans.is_empty() { - item.to_string() - } else { - format!("{}\n{}", context_spans.join("\n"), item) - }; - - let document_text = CODE_CONTEXT_TEMPLATE - .replace("", relative_path.to_str().unwrap()) - .replace("", &language.name().to_lowercase()) - .replace("", item.as_str()); - - documents.push(Document { - range: byte_range, - content: document_text, - embedding: Vec::new(), - name: name.join(" ").to_string(), - }); + let mut document_content = String::new(); + for context_range in &context_match.context_ranges { + document_content.push_str(&content[context_range.clone()]); + document_content.push_str("\n"); + } + + let mut offset = context_match.item_range.start; + for collapsed_range in &collapsed_ranges_within { + if collapsed_range.start > offset { + add_content_from_range( + &mut document_content, + content, + offset..collapsed_range.start, + context_match.start_col, + ); } + document_content.push_str(placeholder); + offset = collapsed_range.end; + } + + if offset < context_match.item_range.end { + add_content_from_range( + &mut document_content, + content, + offset..context_match.item_range.end, + context_match.start_col, + ); + } + + if let Some(name) = content.get(context_match.name_range.clone()) { + parsed_name_ranges.insert(context_match.name_range.clone()); + documents.push(Document { + name: name.to_string(), + content: document_content, + range: context_match.item_range.clone(), + embedding: vec![], + }) } } return Ok(documents); } } + +pub(crate) fn subtract_ranges( + ranges: &[Range], + ranges_to_subtract: &[Range], +) -> Vec> { + let mut result = Vec::new(); + + let mut ranges_to_subtract = ranges_to_subtract.iter().peekable(); + + for range in ranges { + let mut offset = range.start; + + while offset < range.end { + if let Some(range_to_subtract) = ranges_to_subtract.peek() { + if offset < range_to_subtract.start { + let next_offset = cmp::min(range_to_subtract.start, range.end); + result.push(offset..next_offset); + offset = next_offset; + } else { + let next_offset = cmp::min(range_to_subtract.end, range.end); + offset = next_offset; + } + + if offset >= range_to_subtract.end { + ranges_to_subtract.next(); + } + } else { + result.push(offset..range.end); + offset = range.end; + } + } + } + + result +} + +fn add_content_from_range( + output: &mut String, + content: &str, + range: Range, + start_col: usize, +) { + for mut line in content.get(range.clone()).unwrap_or("").lines() { + for _ in 0..start_col { + if line.starts_with(' ') { + line = &line[1..]; + } else { + break; + } + } + output.push_str(line); + output.push('\n'); + } + output.pop(); +} diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 44ce45f457004c7167f8c61501c2b03ca239d199..271fd741a643d1e04d5afe57a50b70b6e391cbf7 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -409,7 +409,11 @@ impl SemanticIndex { ) { if let Some(content) = fs.load(&pending_file.absolute_path).await.log_err() { if let Some(documents) = retriever - .parse_file(&pending_file.relative_path, &content, pending_file.language) + .parse_file_with_template( + &pending_file.relative_path, + &content, + pending_file.language, + ) .log_err() { log::trace!( @@ -657,6 +661,8 @@ impl SemanticIndex { }) .await?; + dbg!(&documents); + let mut tasks = Vec::new(); let mut ranges = Vec::new(); let weak_project = project.downgrade(); diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index 63b28798ad91d67d6786b4b420900135050dfe5b..c54d5079d37f3b8ad5ce4dbb788f5eb5f68b02c8 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -1,7 +1,7 @@ use crate::{ db::dot, embedding::EmbeddingProvider, - parsing::{CodeContextRetriever, Document}, + parsing::{subtract_ranges, CodeContextRetriever, Document}, semantic_index_settings::SemanticIndexSettings, SemanticIndex, }; @@ -9,6 +9,7 @@ use anyhow::Result; use async_trait::async_trait; use gpui::{Task, TestAppContext}; use language::{Language, LanguageConfig, LanguageRegistry, ToOffset}; +use pretty_assertions::assert_eq; use project::{project_settings::ProjectSettings, FakeFs, Fs, Project}; use rand::{rngs::StdRng, Rng}; use serde_json::json; @@ -104,7 +105,7 @@ async fn test_semantic_index(cx: &mut TestAppContext) { assert_eq!(search_results[0].range.start.to_offset(buffer), 0); assert_eq!( buffer.file().unwrap().path().as_ref(), - Path::new("file1.rs") + Path::new("src/file1.rs") ); }); @@ -147,503 +148,548 @@ async fn test_code_context_retrieval_rust() { let text = " /// A doc comment /// that spans multiple lines + #[gpui::test] fn a() { b } impl C for D { } + + impl E { + // This is also a preceding comment + pub fn function_1() -> Option<()> { + todo!(); + } + + // This is a preceding comment + fn function_2() -> Result<()> { + todo!(); + } + } " .unindent(); - let parsed_files = retriever + let documents = retriever .parse_file(Path::new("foo.rs"), &text, language) .unwrap(); - assert_eq!( - parsed_files, + assert_documents_eq( + &documents, &[ - Document { - name: "a".into(), - range: text.find("fn a").unwrap()..(text.find("}").unwrap() + 1), - content: " - The below code snippet is from file 'foo.rs' - - ```rust - /// A doc comment - /// that spans multiple lines - fn a() { - b - } - ```" + ( + " + /// A doc comment + /// that spans multiple lines + #[gpui::test] + fn a() { + b + }" .unindent(), - embedding: vec![], - }, - Document { - name: "C for D".into(), - range: text.find("impl C").unwrap()..(text.rfind("}").unwrap() + 1), - content: " - The below code snippet is from file 'foo.rs' - - ```rust - impl C for D { - } - ```" + text.find("fn a").unwrap(), + ), + ( + " + impl C for D { + }" .unindent(), - embedding: vec![], - } - ] + text.find("impl C").unwrap(), + ), + ( + " + impl E { + // This is also a preceding comment + pub fn function_1() -> Option<()> { /* ... */ } + + // This is a preceding comment + fn function_2() -> Result<()> { /* ... */ } + }" + .unindent(), + text.find("impl E").unwrap(), + ), + ( + " + // This is also a preceding comment + pub fn function_1() -> Option<()> { + todo!(); + }" + .unindent(), + text.find("pub fn function_1").unwrap(), + ), + ( + " + // This is a preceding comment + fn function_2() -> Result<()> { + todo!(); + }" + .unindent(), + text.find("fn function_2").unwrap(), + ), + ], ); } -#[gpui::test] -async fn test_code_context_retrieval_javascript() { - let language = js_lang(); - let mut retriever = CodeContextRetriever::new(); - - let text = " - /* globals importScripts, backend */ - function _authorize() {} - - /** - * Sometimes the frontend build is way faster than backend. - */ - export async function authorizeBank() { - _authorize(pushModal, upgradingAccountId, {}); - } - - export class SettingsPage { - /* This is a test setting */ - constructor(page) { - this.page = page; - } - } - - /* This is a test comment */ - class TestClass {} - - /* Schema for editor_events in Clickhouse. */ - export interface ClickhouseEditorEvent { - installation_id: string - operation: string - } - " - .unindent(); - - let parsed_files = retriever - .parse_file(Path::new("foo.js"), &text, language) - .unwrap(); - - let test_documents = &[ - Document { - name: "function _authorize".into(), - range: text.find("function _authorize").unwrap()..(text.find("}").unwrap() + 1), - content: " - The below code snippet is from file 'foo.js' - - ```javascript - /* globals importScripts, backend */ - function _authorize() {} - ```" - .unindent(), - embedding: vec![], - }, - Document { - name: "async function authorizeBank".into(), - range: text.find("export async").unwrap()..223, - content: " - The below code snippet is from file 'foo.js' - - ```javascript - /** - * Sometimes the frontend build is way faster than backend. - */ - export async function authorizeBank() { - _authorize(pushModal, upgradingAccountId, {}); - } - ```" - .unindent(), - embedding: vec![], - }, - Document { - name: "class SettingsPage".into(), - range: 225..343, - content: " - The below code snippet is from file 'foo.js' - - ```javascript - export class SettingsPage { - /* This is a test setting */ - constructor(page) { - this.page = page; - } - } - ```" - .unindent(), - embedding: vec![], - }, - Document { - name: "constructor".into(), - range: 290..341, - content: " - The below code snippet is from file 'foo.js' - - ```javascript - /* This is a test setting */ - constructor(page) { - this.page = page; - } - ```" - .unindent(), - embedding: vec![], - }, - Document { - name: "class TestClass".into(), - range: 374..392, - content: " - The below code snippet is from file 'foo.js' - - ```javascript - /* This is a test comment */ - class TestClass {} - ```" - .unindent(), - embedding: vec![], - }, - Document { - name: "interface ClickhouseEditorEvent".into(), - range: 440..532, - content: " - The below code snippet is from file 'foo.js' - - ```javascript - /* Schema for editor_events in Clickhouse. */ - export interface ClickhouseEditorEvent { - installation_id: string - operation: string - } - ```" - .unindent(), - embedding: vec![], - }, - ]; - - for idx in 0..test_documents.len() { - assert_eq!(test_documents[idx], parsed_files[idx]); - } -} - -#[gpui::test] -async fn test_code_context_retrieval_elixir() { - let language = elixir_lang(); - let mut retriever = CodeContextRetriever::new(); - - let text = r#" -defmodule File.Stream do - @moduledoc """ - Defines a `File.Stream` struct returned by `File.stream!/3`. - - The following fields are public: - - * `path` - the file path - * `modes` - the file modes - * `raw` - a boolean indicating if bin functions should be used - * `line_or_bytes` - if reading should read lines or a given number of bytes - * `node` - the node the file belongs to - - """ - - defstruct path: nil, modes: [], line_or_bytes: :line, raw: true, node: nil - - @type t :: %__MODULE__{} - - @doc false - def __build__(path, modes, line_or_bytes) do - raw = :lists.keyfind(:encoding, 1, modes) == false - - modes = - case raw do - true -> - case :lists.keyfind(:read_ahead, 1, modes) do - {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] - {:read_ahead, _} -> [:raw | modes] - false -> [:raw, :read_ahead | modes] - end - - false -> - modes - end - - %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} - - end -"# - .unindent(); - - let parsed_files = retriever - .parse_file(Path::new("foo.ex"), &text, language) - .unwrap(); - - let test_documents = &[ - Document{ - name: "defmodule File.Stream".into(), - range: 0..1132, - content: r#" - The below code snippet is from file 'foo.ex' - - ```elixir - defmodule File.Stream do - @moduledoc """ - Defines a `File.Stream` struct returned by `File.stream!/3`. - - The following fields are public: - - * `path` - the file path - * `modes` - the file modes - * `raw` - a boolean indicating if bin functions should be used - * `line_or_bytes` - if reading should read lines or a given number of bytes - * `node` - the node the file belongs to - - """ - - defstruct path: nil, modes: [], line_or_bytes: :line, raw: true, node: nil - - @type t :: %__MODULE__{} - - @doc false - def __build__(path, modes, line_or_bytes) do - raw = :lists.keyfind(:encoding, 1, modes) == false - - modes = - case raw do - true -> - case :lists.keyfind(:read_ahead, 1, modes) do - {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] - {:read_ahead, _} -> [:raw | modes] - false -> [:raw, :read_ahead | modes] - end - - false -> - modes - end - - %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} - - end - ```"#.unindent(), - embedding: vec![], - }, - Document { - name: "def __build__".into(), - range: 574..1132, - content: r#" -The below code snippet is from file 'foo.ex' - -```elixir -@doc false -def __build__(path, modes, line_or_bytes) do - raw = :lists.keyfind(:encoding, 1, modes) == false - - modes = - case raw do - true -> - case :lists.keyfind(:read_ahead, 1, modes) do - {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] - {:read_ahead, _} -> [:raw | modes] - false -> [:raw, :read_ahead | modes] - end - - false -> - modes - end - - %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} - - end -```"# - .unindent(), - embedding: vec![], - }]; - - for idx in 0..test_documents.len() { - assert_eq!(test_documents[idx], parsed_files[idx]); - } +fn assert_documents_eq( + documents: &[Document], + expected_contents_and_start_offsets: &[(String, usize)], +) { + assert_eq!( + documents + .iter() + .map(|document| (document.content.clone(), document.range.start)) + .collect::>(), + expected_contents_and_start_offsets + ); } -#[gpui::test] -async fn test_code_context_retrieval_cpp() { - let language = cpp_lang(); - let mut retriever = CodeContextRetriever::new(); - - let text = " - /** - * @brief Main function - * @returns 0 on exit - */ - int main() { return 0; } - - /** - * This is a test comment - */ - class MyClass { // The class - public: // Access specifier - int myNum; // Attribute (int variable) - string myString; // Attribute (string variable) - }; - - // This is a test comment - enum Color { red, green, blue }; - - /** This is a preceeding block comment - * This is the second line - */ - struct { // Structure declaration - int myNum; // Member (int variable) - string myString; // Member (string variable) - } myStructure; - - /** - * @brief Matrix class. - */ - template ::value || std::is_floating_point::value, - bool>::type> - class Matrix2 { - std::vector> _mat; - - public: - /** - * @brief Constructor - * @tparam Integer ensuring integers are being evaluated and not other - * data types. - * @param size denoting the size of Matrix as size x size - */ - template ::value, - Integer>::type> - explicit Matrix(const Integer size) { - for (size_t i = 0; i < size; ++i) { - _mat.emplace_back(std::vector(size, 0)); - } - } - }" - .unindent(); - - let parsed_files = retriever - .parse_file(Path::new("foo.cpp"), &text, language) - .unwrap(); - - let test_documents = &[ - Document { - name: "int main".into(), - range: 54..78, - content: " - The below code snippet is from file 'foo.cpp' - - ```cpp - /** - * @brief Main function - * @returns 0 on exit - */ - int main() { return 0; } - ```" - .unindent(), - embedding: vec![], - }, - Document { - name: "class MyClass".into(), - range: 112..295, - content: " - The below code snippet is from file 'foo.cpp' - - ```cpp - /** - * This is a test comment - */ - class MyClass { // The class - public: // Access specifier - int myNum; // Attribute (int variable) - string myString; // Attribute (string variable) - } - ```" - .unindent(), - embedding: vec![], - }, - Document { - name: "enum Color".into(), - range: 324..355, - content: " - The below code snippet is from file 'foo.cpp' - - ```cpp - // This is a test comment - enum Color { red, green, blue } - ```" - .unindent(), - embedding: vec![], - }, - Document { - name: "struct myStructure".into(), - range: 428..581, - content: " - The below code snippet is from file 'foo.cpp' - - ```cpp - /** This is a preceeding block comment - * This is the second line - */ - struct { // Structure declaration - int myNum; // Member (int variable) - string myString; // Member (string variable) - } myStructure; - ```" - .unindent(), - embedding: vec![], - }, - Document { - name: "class Matrix2".into(), - range: 613..1342, - content: " - The below code snippet is from file 'foo.cpp' - - ```cpp - /** - * @brief Matrix class. - */ - template ::value || std::is_floating_point::value, - bool>::type> - class Matrix2 { - std::vector> _mat; - - public: - /** - * @brief Constructor - * @tparam Integer ensuring integers are being evaluated and not other - * data types. - * @param size denoting the size of Matrix as size x size - */ - template ::value, - Integer>::type> - explicit Matrix(const Integer size) { - for (size_t i = 0; i < size; ++i) { - _mat.emplace_back(std::vector(size, 0)); - } - } - } - ```" - .unindent(), - embedding: vec![], - }, - ]; - - for idx in 0..test_documents.len() { - assert_eq!(test_documents[idx], parsed_files[idx]); - } -} +// #[gpui::test] +// async fn test_code_context_retrieval_javascript() { +// let language = js_lang(); +// let mut retriever = CodeContextRetriever::new(); + +// let text = " +// /* globals importScripts, backend */ +// function _authorize() {} + +// /** +// * Sometimes the frontend build is way faster than backend. +// */ +// export async function authorizeBank() { +// _authorize(pushModal, upgradingAccountId, {}); +// } + +// export class SettingsPage { +// /* This is a test setting */ +// constructor(page) { +// this.page = page; +// } +// } + +// /* This is a test comment */ +// class TestClass {} + +// /* Schema for editor_events in Clickhouse. */ +// export interface ClickhouseEditorEvent { +// installation_id: string +// operation: string +// } +// " +// .unindent(); + +// let parsed_files = retriever +// .parse_file(Path::new("foo.js"), &text, language) +// .unwrap(); + +// let test_documents = &[ +// Document { +// name: "function _authorize".into(), +// range: text.find("function _authorize").unwrap()..(text.find("}").unwrap() + 1), +// content: " +// The below code snippet is from file 'foo.js' + +// ```javascript +// /* globals importScripts, backend */ +// function _authorize() {} +// ```" +// .unindent(), +// embedding: vec![], +// }, +// Document { +// name: "async function authorizeBank".into(), +// range: text.find("export async").unwrap()..223, +// content: " +// The below code snippet is from file 'foo.js' + +// ```javascript +// /** +// * Sometimes the frontend build is way faster than backend. +// */ +// export async function authorizeBank() { +// _authorize(pushModal, upgradingAccountId, {}); +// } +// ```" +// .unindent(), +// embedding: vec![], +// }, +// Document { +// name: "class SettingsPage".into(), +// range: 225..343, +// content: " +// The below code snippet is from file 'foo.js' + +// ```javascript +// export class SettingsPage { +// /* This is a test setting */ +// constructor(page) { +// this.page = page; +// } +// } +// ```" +// .unindent(), +// embedding: vec![], +// }, +// Document { +// name: "constructor".into(), +// range: 290..341, +// content: " +// The below code snippet is from file 'foo.js' + +// ```javascript +// /* This is a test setting */ +// constructor(page) { +// this.page = page; +// } +// ```" +// .unindent(), +// embedding: vec![], +// }, +// Document { +// name: "class TestClass".into(), +// range: 374..392, +// content: " +// The below code snippet is from file 'foo.js' + +// ```javascript +// /* This is a test comment */ +// class TestClass {} +// ```" +// .unindent(), +// embedding: vec![], +// }, +// Document { +// name: "interface ClickhouseEditorEvent".into(), +// range: 440..532, +// content: " +// The below code snippet is from file 'foo.js' + +// ```javascript +// /* Schema for editor_events in Clickhouse. */ +// export interface ClickhouseEditorEvent { +// installation_id: string +// operation: string +// } +// ```" +// .unindent(), +// embedding: vec![], +// }, +// ]; + +// for idx in 0..test_documents.len() { +// assert_eq!(test_documents[idx], parsed_files[idx]); +// } +// } + +// #[gpui::test] +// async fn test_code_context_retrieval_elixir() { +// let language = elixir_lang(); +// let mut retriever = CodeContextRetriever::new(); + +// let text = r#" +// defmodule File.Stream do +// @moduledoc """ +// Defines a `File.Stream` struct returned by `File.stream!/3`. + +// The following fields are public: + +// * `path` - the file path +// * `modes` - the file modes +// * `raw` - a boolean indicating if bin functions should be used +// * `line_or_bytes` - if reading should read lines or a given number of bytes +// * `node` - the node the file belongs to + +// """ + +// defstruct path: nil, modes: [], line_or_bytes: :line, raw: true, node: nil + +// @type t :: %__MODULE__{} + +// @doc false +// def __build__(path, modes, line_or_bytes) do +// raw = :lists.keyfind(:encoding, 1, modes) == false + +// modes = +// case raw do +// true -> +// case :lists.keyfind(:read_ahead, 1, modes) do +// {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] +// {:read_ahead, _} -> [:raw | modes] +// false -> [:raw, :read_ahead | modes] +// end + +// false -> +// modes +// end + +// %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} + +// end +// "# +// .unindent(); + +// let parsed_files = retriever +// .parse_file(Path::new("foo.ex"), &text, language) +// .unwrap(); + +// let test_documents = &[ +// Document{ +// name: "defmodule File.Stream".into(), +// range: 0..1132, +// content: r#" +// The below code snippet is from file 'foo.ex' + +// ```elixir +// defmodule File.Stream do +// @moduledoc """ +// Defines a `File.Stream` struct returned by `File.stream!/3`. + +// The following fields are public: + +// * `path` - the file path +// * `modes` - the file modes +// * `raw` - a boolean indicating if bin functions should be used +// * `line_or_bytes` - if reading should read lines or a given number of bytes +// * `node` - the node the file belongs to + +// """ + +// defstruct path: nil, modes: [], line_or_bytes: :line, raw: true, node: nil + +// @type t :: %__MODULE__{} + +// @doc false +// def __build__(path, modes, line_or_bytes) do +// raw = :lists.keyfind(:encoding, 1, modes) == false + +// modes = +// case raw do +// true -> +// case :lists.keyfind(:read_ahead, 1, modes) do +// {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] +// {:read_ahead, _} -> [:raw | modes] +// false -> [:raw, :read_ahead | modes] +// end + +// false -> +// modes +// end + +// %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} + +// end +// ```"#.unindent(), +// embedding: vec![], +// }, +// Document { +// name: "def __build__".into(), +// range: 574..1132, +// content: r#" +// The below code snippet is from file 'foo.ex' + +// ```elixir +// @doc false +// def __build__(path, modes, line_or_bytes) do +// raw = :lists.keyfind(:encoding, 1, modes) == false + +// modes = +// case raw do +// true -> +// case :lists.keyfind(:read_ahead, 1, modes) do +// {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] +// {:read_ahead, _} -> [:raw | modes] +// false -> [:raw, :read_ahead | modes] +// end + +// false -> +// modes +// end + +// %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} + +// end +// ```"# +// .unindent(), +// embedding: vec![], +// }]; + +// for idx in 0..test_documents.len() { +// assert_eq!(test_documents[idx], parsed_files[idx]); +// } +// } + +// #[gpui::test] +// async fn test_code_context_retrieval_cpp() { +// let language = cpp_lang(); +// let mut retriever = CodeContextRetriever::new(); + +// let text = " +// /** +// * @brief Main function +// * @returns 0 on exit +// */ +// int main() { return 0; } + +// /** +// * This is a test comment +// */ +// class MyClass { // The class +// public: // Access specifier +// int myNum; // Attribute (int variable) +// string myString; // Attribute (string variable) +// }; + +// // This is a test comment +// enum Color { red, green, blue }; + +// /** This is a preceding block comment +// * This is the second line +// */ +// struct { // Structure declaration +// int myNum; // Member (int variable) +// string myString; // Member (string variable) +// } myStructure; + +// /** +// * @brief Matrix class. +// */ +// template ::value || std::is_floating_point::value, +// bool>::type> +// class Matrix2 { +// std::vector> _mat; + +// public: +// /** +// * @brief Constructor +// * @tparam Integer ensuring integers are being evaluated and not other +// * data types. +// * @param size denoting the size of Matrix as size x size +// */ +// template ::value, +// Integer>::type> +// explicit Matrix(const Integer size) { +// for (size_t i = 0; i < size; ++i) { +// _mat.emplace_back(std::vector(size, 0)); +// } +// } +// }" +// .unindent(); + +// let parsed_files = retriever +// .parse_file(Path::new("foo.cpp"), &text, language) +// .unwrap(); + +// let test_documents = &[ +// Document { +// name: "int main".into(), +// range: 54..78, +// content: " +// The below code snippet is from file 'foo.cpp' + +// ```cpp +// /** +// * @brief Main function +// * @returns 0 on exit +// */ +// int main() { return 0; } +// ```" +// .unindent(), +// embedding: vec![], +// }, +// Document { +// name: "class MyClass".into(), +// range: 112..295, +// content: " +// The below code snippet is from file 'foo.cpp' + +// ```cpp +// /** +// * This is a test comment +// */ +// class MyClass { // The class +// public: // Access specifier +// int myNum; // Attribute (int variable) +// string myString; // Attribute (string variable) +// } +// ```" +// .unindent(), +// embedding: vec![], +// }, +// Document { +// name: "enum Color".into(), +// range: 324..355, +// content: " +// The below code snippet is from file 'foo.cpp' + +// ```cpp +// // This is a test comment +// enum Color { red, green, blue } +// ```" +// .unindent(), +// embedding: vec![], +// }, +// Document { +// name: "struct myStructure".into(), +// range: 428..581, +// content: " +// The below code snippet is from file 'foo.cpp' + +// ```cpp +// /** This is a preceding block comment +// * This is the second line +// */ +// struct { // Structure declaration +// int myNum; // Member (int variable) +// string myString; // Member (string variable) +// } myStructure; +// ```" +// .unindent(), +// embedding: vec![], +// }, +// Document { +// name: "class Matrix2".into(), +// range: 613..1342, +// content: " +// The below code snippet is from file 'foo.cpp' + +// ```cpp +// /** +// * @brief Matrix class. +// */ +// template ::value || std::is_floating_point::value, +// bool>::type> +// class Matrix2 { +// std::vector> _mat; + +// public: +// /** +// * @brief Constructor +// * @tparam Integer ensuring integers are being evaluated and not other +// * data types. +// * @param size denoting the size of Matrix as size x size +// */ +// template ::value, +// Integer>::type> +// explicit Matrix(const Integer size) { +// for (size_t i = 0; i < size; ++i) { +// _mat.emplace_back(std::vector(size, 0)); +// } +// } +// } +// ```" +// .unindent(), +// embedding: vec![], +// }, +// ]; + +// for idx in 0..test_documents.len() { +// assert_eq!(test_documents[idx], parsed_files[idx]); +// } +// } #[gpui::test] fn test_dot_product(mut rng: StdRng) { @@ -826,6 +872,7 @@ fn rust_lang() -> Arc { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".into()], + collapsed_placeholder: " /* ... */ ".to_string(), ..Default::default() }, Some(tree_sitter_rust::language()), @@ -833,54 +880,32 @@ fn rust_lang() -> Arc { .with_embedding_query( r#" ( - (line_comment)* @context - . - (enum_item - name: (_) @name) @item - ) - - ( - (line_comment)* @context + [(line_comment) (attribute_item)]* @context . - (struct_item - name: (_) @name) @item - ) + [ + (struct_item + name: (_) @name) - ( - (line_comment)* @context - . - (impl_item - trait: (_)? @name - "for"? @name - type: (_) @name) @item - ) + (enum_item + name: (_) @name) - ( - (line_comment)* @context - . - (trait_item - name: (_) @name) @item - ) + (impl_item + trait: (_)? @name + "for"? @name + type: (_) @name) - ( - (line_comment)* @context - . - (function_item - name: (_) @name) @item - ) + (trait_item + name: (_) @name) - ( - (line_comment)* @context - . - (macro_definition - name: (_) @name) @item - ) + (function_item + name: (_) @name + body: (block + "{" @keep + "}" @keep) @collapse) - ( - (line_comment)* @context - . - (function_signature_item - name: (_) @name) @item + (macro_definition + name: (_) @name) + ] @item ) "#, ) @@ -1023,3 +1048,15 @@ fn elixir_lang() -> Arc { .unwrap(), ) } + +#[gpui::test] +fn test_subtract_ranges() { + // collapsed_ranges: Vec>, keep_ranges: Vec> + + assert_eq!( + subtract_ranges(&[0..5, 10..21], &[0..1, 4..5]), + vec![1..4, 10..21] + ); + + assert_eq!(subtract_ranges(&[0..5], &[1..2]), &[0..1, 2..5]); +} diff --git a/crates/zed/src/languages/rust/config.toml b/crates/zed/src/languages/rust/config.toml index 705287f0a758045ce8179bfc8a6bf18e564970b8..8216ba0a74a90a16f2e29be77021f56530649c52 100644 --- a/crates/zed/src/languages/rust/config.toml +++ b/crates/zed/src/languages/rust/config.toml @@ -10,3 +10,4 @@ brackets = [ { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] }, { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] }, ] +collapsed_placeholder = " /* ... */ " diff --git a/crates/zed/src/languages/rust/embedding.scm b/crates/zed/src/languages/rust/embedding.scm index 66e4083de5f0fe8b1adfa2ea657668e4453e4b61..e4218382a9b1ceb7e087b0d9247d5a4e66b77236 100644 --- a/crates/zed/src/languages/rust/embedding.scm +++ b/crates/zed/src/languages/rust/embedding.scm @@ -1,50 +1,28 @@ ( - (line_comment)* @context + [(line_comment) (attribute_item)]* @context . - (enum_item - name: (_) @name) @item -) + [ + (struct_item + name: (_) @name) -( - (line_comment)* @context - . - (struct_item - name: (_) @name) @item -) + (enum_item + name: (_) @name) -( - (line_comment)* @context - . - (impl_item - trait: (_)? @name - "for"? @name - type: (_) @name) @item -) + (impl_item + trait: (_)? @name + "for"? @name + type: (_) @name) -( - (line_comment)* @context - . - (trait_item - name: (_) @name) @item -) + (trait_item + name: (_) @name) -( - (line_comment)* @context - . - (function_item - name: (_) @name) @item -) - -( - (line_comment)* @context - . - (macro_definition - name: (_) @name) @item -) + (function_item + name: (_) @name + body: (block + "{" @keep + "}" @keep) @collapse) -( - (line_comment)* @context - . - (function_signature_item - name: (_) @name) @item -) + (macro_definition + name: (_) @name) + ] @item + ) From efe973ebe2f6c4c92159542eb4d8e1bc12455df4 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Wed, 19 Jul 2023 16:52:44 -0400 Subject: [PATCH 027/160] add embedding query for json with nested arrays and strings Co-authored-by: maxbrunsfeld --- Cargo.lock | 1 + crates/language/src/language.rs | 4 +- crates/semantic_index/Cargo.toml | 1 + crates/semantic_index/src/parsing.rs | 123 ++++++++++-------- crates/semantic_index/src/semantic_index.rs | 2 +- .../src/semantic_index_tests.rs | 103 ++++++++++++++- crates/zed/src/languages/json/embedding.scm | 14 ++ 7 files changed, 189 insertions(+), 59 deletions(-) create mode 100644 crates/zed/src/languages/json/embedding.scm diff --git a/Cargo.lock b/Cargo.lock index 8ea6f61da04f215b91b31941ccce795be778a204..75f66163e3fbf5048b01cbf5079f00f2e9c5ce46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6502,6 +6502,7 @@ dependencies = [ "tree-sitter", "tree-sitter-cpp", "tree-sitter-elixir 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tree-sitter-json 0.19.0", "tree-sitter-rust", "tree-sitter-toml 0.20.0", "tree-sitter-typescript 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index ec233716d6ce5345515600b14e00a212b3dcb3a5..e34358c7c5def79e8141e86e54693bcc99188da0 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -526,7 +526,7 @@ pub struct OutlineConfig { pub struct EmbeddingConfig { pub query: Query, pub item_capture_ix: u32, - pub name_capture_ix: u32, + pub name_capture_ix: Option, pub context_capture_ix: Option, pub collapse_capture_ix: Option, pub keep_capture_ix: Option, @@ -1263,7 +1263,7 @@ impl Language { ("collapse", &mut collapse_capture_ix), ], ); - if let Some((item_capture_ix, name_capture_ix)) = item_capture_ix.zip(name_capture_ix) { + if let Some(item_capture_ix) = item_capture_ix { grammar.embedding_config = Some(EmbeddingConfig { query, item_capture_ix, diff --git a/crates/semantic_index/Cargo.toml b/crates/semantic_index/Cargo.toml index 1b3169bfe41940eef5c863901c560e106acf4816..35b97245124e8922d5e7a46a369e26c71af7731a 100644 --- a/crates/semantic_index/Cargo.toml +++ b/crates/semantic_index/Cargo.toml @@ -54,6 +54,7 @@ ctor.workspace = true env_logger.workspace = true tree-sitter-typescript = "*" +tree-sitter-json = "*" tree-sitter-rust = "*" tree-sitter-toml = "*" tree-sitter-cpp = "*" diff --git a/crates/semantic_index/src/parsing.rs b/crates/semantic_index/src/parsing.rs index 0d2aeb60fb24dcb347c3a0f870ef6e348e08a88a..c952ef3a4edf939ddc8ad17c9bab6e17ec5e0cce 100644 --- a/crates/semantic_index/src/parsing.rs +++ b/crates/semantic_index/src/parsing.rs @@ -1,6 +1,12 @@ use anyhow::{anyhow, Ok, Result}; use language::{Grammar, Language}; -use std::{cmp, collections::HashSet, ops::Range, path::Path, sync::Arc}; +use std::{ + cmp::{self, Reverse}, + collections::HashSet, + ops::Range, + path::Path, + sync::Arc, +}; use tree_sitter::{Parser, QueryCursor}; #[derive(Debug, PartialEq, Clone)] @@ -15,7 +21,7 @@ const CODE_CONTEXT_TEMPLATE: &str = "The below code snippet is from file ''\n\n```\n\n```"; const ENTIRE_FILE_TEMPLATE: &str = "The below snippet is from file ''\n\n```\n\n```"; -pub const PARSEABLE_ENTIRE_FILE_TYPES: [&str; 4] = ["TOML", "YAML", "JSON", "CSS"]; +pub const PARSEABLE_ENTIRE_FILE_TYPES: &[&str] = &["TOML", "YAML", "CSS"]; pub struct CodeContextRetriever { pub parser: Parser, @@ -30,8 +36,8 @@ pub struct CodeContextRetriever { #[derive(Debug, Clone)] pub struct CodeContextMatch { pub start_col: usize, - pub item_range: Range, - pub name_range: Range, + pub item_range: Option>, + pub name_range: Option>, pub context_ranges: Vec>, pub collapse_ranges: Vec>, } @@ -44,7 +50,7 @@ impl CodeContextRetriever { } } - fn _parse_entire_file( + fn parse_entire_file( &self, relative_path: &Path, language_name: Arc, @@ -97,7 +103,7 @@ impl CodeContextRetriever { if capture.index == embedding_config.item_capture_ix { item_range = Some(capture.node.byte_range()); start_col = capture.node.start_position().column; - } else if capture.index == embedding_config.name_capture_ix { + } else if Some(capture.index) == embedding_config.name_capture_ix { name_range = Some(capture.node.byte_range()); } else if Some(capture.index) == embedding_config.context_capture_ix { context_ranges.push(capture.node.byte_range()); @@ -108,16 +114,13 @@ impl CodeContextRetriever { } } - if item_range.is_some() && name_range.is_some() { - let item_range = item_range.unwrap(); - captures.push(CodeContextMatch { - start_col, - item_range, - name_range: name_range.unwrap(), - context_ranges, - collapse_ranges: subtract_ranges(&collapse_ranges, &keep_ranges), - }); - } + captures.push(CodeContextMatch { + start_col, + item_range, + name_range, + context_ranges, + collapse_ranges: subtract_ranges(&collapse_ranges, &keep_ranges), + }); } Ok(captures) } @@ -129,7 +132,12 @@ impl CodeContextRetriever { language: Arc, ) -> Result> { let language_name = language.name(); - let mut documents = self.parse_file(relative_path, content, language)?; + + if PARSEABLE_ENTIRE_FILE_TYPES.contains(&language_name.as_ref()) { + return self.parse_entire_file(relative_path, language_name, &content); + } + + let mut documents = self.parse_file(content, language)?; for document in &mut documents { document.content = CODE_CONTEXT_TEMPLATE .replace("", relative_path.to_string_lossy().as_ref()) @@ -139,16 +147,7 @@ impl CodeContextRetriever { Ok(documents) } - pub fn parse_file( - &mut self, - relative_path: &Path, - content: &str, - language: Arc, - ) -> Result> { - if PARSEABLE_ENTIRE_FILE_TYPES.contains(&language.name().as_ref()) { - return self._parse_entire_file(relative_path, language.name(), &content); - } - + pub fn parse_file(&mut self, content: &str, language: Arc) -> Result> { let grammar = language .grammar() .ok_or_else(|| anyhow!("no grammar for language"))?; @@ -163,32 +162,49 @@ impl CodeContextRetriever { let mut collapsed_ranges_within = Vec::new(); let mut parsed_name_ranges = HashSet::new(); for (i, context_match) in matches.iter().enumerate() { - if parsed_name_ranges.contains(&context_match.name_range) { + // Items which are collapsible but not embeddable have no item range + let item_range = if let Some(item_range) = context_match.item_range.clone() { + item_range + } else { continue; + }; + + // Checks for deduplication + let name; + if let Some(name_range) = context_match.name_range.clone() { + name = content + .get(name_range.clone()) + .map_or(String::new(), |s| s.to_string()); + if parsed_name_ranges.contains(&name_range) { + continue; + } + parsed_name_ranges.insert(name_range); + } else { + name = String::new(); } collapsed_ranges_within.clear(); - for remaining_match in &matches[(i + 1)..] { - if context_match - .item_range - .contains(&remaining_match.item_range.start) - && context_match - .item_range - .contains(&remaining_match.item_range.end) - { - collapsed_ranges_within.extend(remaining_match.collapse_ranges.iter().cloned()); - } else { - break; + 'outer: for remaining_match in &matches[(i + 1)..] { + for collapsed_range in &remaining_match.collapse_ranges { + if item_range.start <= collapsed_range.start + && item_range.end >= collapsed_range.end + { + collapsed_ranges_within.push(collapsed_range.clone()); + } else { + break 'outer; + } } } + collapsed_ranges_within.sort_by_key(|r| (r.start, Reverse(r.end))); + let mut document_content = String::new(); for context_range in &context_match.context_ranges { document_content.push_str(&content[context_range.clone()]); document_content.push_str("\n"); } - let mut offset = context_match.item_range.start; + let mut offset = item_range.start; for collapsed_range in &collapsed_ranges_within { if collapsed_range.start > offset { add_content_from_range( @@ -197,29 +213,30 @@ impl CodeContextRetriever { offset..collapsed_range.start, context_match.start_col, ); + offset = collapsed_range.start; + } + + if collapsed_range.end > offset { + document_content.push_str(placeholder); + offset = collapsed_range.end; } - document_content.push_str(placeholder); - offset = collapsed_range.end; } - if offset < context_match.item_range.end { + if offset < item_range.end { add_content_from_range( &mut document_content, content, - offset..context_match.item_range.end, + offset..item_range.end, context_match.start_col, ); } - if let Some(name) = content.get(context_match.name_range.clone()) { - parsed_name_ranges.insert(context_match.name_range.clone()); - documents.push(Document { - name: name.to_string(), - content: document_content, - range: context_match.item_range.clone(), - embedding: vec![], - }) - } + documents.push(Document { + name, + content: document_content, + range: item_range.clone(), + embedding: vec![], + }) } return Ok(documents); diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 271fd741a643d1e04d5afe57a50b70b6e391cbf7..6e0477491518a0c4a18ebfa1c24ddaf51eaf1948 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -33,7 +33,7 @@ use util::{ ResultExt, }; -const SEMANTIC_INDEX_VERSION: usize = 4; +const SEMANTIC_INDEX_VERSION: usize = 5; const EMBEDDINGS_BATCH_SIZE: usize = 80; pub fn init( diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index c54d5079d37f3b8ad5ce4dbb788f5eb5f68b02c8..31c96ca207bb3da1ace202bd81df461f27ba229b 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -170,9 +170,7 @@ async fn test_code_context_retrieval_rust() { " .unindent(); - let documents = retriever - .parse_file(Path::new("foo.rs"), &text, language) - .unwrap(); + let documents = retriever.parse_file(&text, language).unwrap(); assert_documents_eq( &documents, @@ -229,6 +227,76 @@ async fn test_code_context_retrieval_rust() { ); } +#[gpui::test] +async fn test_code_context_retrieval_json() { + let language = json_lang(); + let mut retriever = CodeContextRetriever::new(); + + let text = r#" + { + "array": [1, 2, 3, 4], + "string": "abcdefg", + "nested_object": { + "array_2": [5, 6, 7, 8], + "string_2": "hijklmnop", + "boolean": true, + "none": null + } + } + "# + .unindent(); + + let documents = retriever.parse_file(&text, language.clone()).unwrap(); + + assert_documents_eq( + &documents, + &[( + r#" + { + "array": [], + "string": "", + "nested_object": { + "array_2": [], + "string_2": "", + "boolean": true, + "none": null + } + }"# + .unindent(), + text.find("{").unwrap(), + )], + ); + + let text = r#" + [ + { + "name": "somebody", + "age": 42 + }, + { + "name": "somebody else", + "age": 43 + } + ] + "# + .unindent(); + + let documents = retriever.parse_file(&text, language.clone()).unwrap(); + + assert_documents_eq( + &documents, + &[( + r#" + [{ + "name": "", + "age": 42 + }]"# + .unindent(), + text.find("[").unwrap(), + )], + ); +} + fn assert_documents_eq( documents: &[Document], expected_contents_and_start_offsets: &[(String, usize)], @@ -913,6 +981,35 @@ fn rust_lang() -> Arc { ) } +fn json_lang() -> Arc { + Arc::new( + Language::new( + LanguageConfig { + name: "JSON".into(), + path_suffixes: vec!["json".into()], + ..Default::default() + }, + Some(tree_sitter_json::language()), + ) + .with_embedding_query( + r#" + (document) @item + + (array + "[" @keep + . + (object)? @keep + "]" @keep) @collapse + + (pair value: (string + "\"" @keep + "\"" @keep) @collapse) + "#, + ) + .unwrap(), + ) +} + fn toml_lang() -> Arc { Arc::new(Language::new( LanguageConfig { diff --git a/crates/zed/src/languages/json/embedding.scm b/crates/zed/src/languages/json/embedding.scm new file mode 100644 index 0000000000000000000000000000000000000000..fa286e3880aa67d49f710f991d6839ebbd306104 --- /dev/null +++ b/crates/zed/src/languages/json/embedding.scm @@ -0,0 +1,14 @@ +; Only produce one embedding for the entire file. +(document) @item + +; Collapse arrays, except for the first object. +(array + "[" @keep + . + (object)? @keep + "]" @keep) @collapse + +; Collapse string values (but not keys). +(pair value: (string + "\"" @keep + "\"" @keep) @collapse) From e02d6bc0d41fe5006307833f5e4c2cd62ba7add1 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Thu, 20 Jul 2023 13:46:27 -0400 Subject: [PATCH 028/160] add glob filtering functionality to semantic search --- Cargo.lock | 1 + crates/search/src/project_search.rs | 60 +++++++++++++++++-- crates/semantic_index/Cargo.toml | 1 + crates/semantic_index/src/db.rs | 39 ++++++++---- crates/semantic_index/src/semantic_index.rs | 13 +++- .../src/semantic_index_tests.rs | 57 +++++++++++++++++- 6 files changed, 149 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75f66163e3fbf5048b01cbf5079f00f2e9c5ce46..f534a4fe7d68a362fd910f0bd02cbf72b24955fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6477,6 +6477,7 @@ dependencies = [ "editor", "env_logger 0.9.3", "futures 0.3.28", + "globset", "gpui", "isahc", "language", diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 5feb94426eb60c67a756c564982a826699bd20a1..25fc897707af6be8b97b277a2d65b8d4cf1eeb17 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -187,14 +187,26 @@ impl ProjectSearch { cx.notify(); } - fn semantic_search(&mut self, query: String, cx: &mut ModelContext) { + fn semantic_search( + &mut self, + query: String, + include_files: Vec, + exclude_files: Vec, + cx: &mut ModelContext, + ) { let search = SemanticIndex::global(cx).map(|index| { index.update(cx, |semantic_index, cx| { - semantic_index.search_project(self.project.clone(), query.clone(), 10, cx) + semantic_index.search_project( + self.project.clone(), + query.clone(), + 10, + include_files, + exclude_files, + cx, + ) }) }); self.search_id += 1; - // self.active_query = Some(query); self.match_ranges.clear(); self.pending_search = Some(cx.spawn(|this, mut cx| async move { let results = search?.await.log_err()?; @@ -638,8 +650,13 @@ impl ProjectSearchView { } let query = self.query_editor.read(cx).text(cx); - self.model - .update(cx, |model, cx| model.semantic_search(query, cx)); + if let Some((included_files, exclude_files)) = + self.get_included_and_excluded_globsets(cx) + { + self.model.update(cx, |model, cx| { + model.semantic_search(query, included_files, exclude_files, cx) + }); + } return; } @@ -648,6 +665,39 @@ impl ProjectSearchView { } } + fn get_included_and_excluded_globsets( + &mut self, + cx: &mut ViewContext, + ) -> Option<(Vec, Vec)> { + let text = self.query_editor.read(cx).text(cx); + let included_files = + match Self::load_glob_set(&self.included_files_editor.read(cx).text(cx)) { + Ok(included_files) => { + self.panels_with_errors.remove(&InputPanel::Include); + included_files + } + Err(_e) => { + self.panels_with_errors.insert(InputPanel::Include); + cx.notify(); + return None; + } + }; + let excluded_files = + match Self::load_glob_set(&self.excluded_files_editor.read(cx).text(cx)) { + Ok(excluded_files) => { + self.panels_with_errors.remove(&InputPanel::Exclude); + excluded_files + } + Err(_e) => { + self.panels_with_errors.insert(InputPanel::Exclude); + cx.notify(); + return None; + } + }; + + Some((included_files, excluded_files)) + } + fn build_search_query(&mut self, cx: &mut ViewContext) -> Option { let text = self.query_editor.read(cx).text(cx); let included_files = diff --git a/crates/semantic_index/Cargo.toml b/crates/semantic_index/Cargo.toml index 35b97245124e8922d5e7a46a369e26c71af7731a..a1f126bfb841ecb8334aeca391ac4959ef9f57b0 100644 --- a/crates/semantic_index/Cargo.toml +++ b/crates/semantic_index/Cargo.toml @@ -37,6 +37,7 @@ tiktoken-rs = "0.5.0" parking_lot.workspace = true rand.workspace = true schemars.workspace = true +globset.workspace = true [dev-dependencies] gpui = { path = "../gpui", features = ["test-support"] } diff --git a/crates/semantic_index/src/db.rs b/crates/semantic_index/src/db.rs index fd99594aab578919f80bd8236270b352a8540993..3ba85a275d0a0d6b197bbad22d5ad5bd792a2fbf 100644 --- a/crates/semantic_index/src/db.rs +++ b/crates/semantic_index/src/db.rs @@ -1,5 +1,6 @@ use crate::{parsing::Document, SEMANTIC_INDEX_VERSION}; use anyhow::{anyhow, Context, Result}; +use globset::{Glob, GlobMatcher}; use project::Fs; use rpc::proto::Timestamp; use rusqlite::{ @@ -252,18 +253,30 @@ impl VectorDatabase { worktree_ids: &[i64], query_embedding: &Vec, limit: usize, + include_globs: Vec, + exclude_globs: Vec, ) -> Result)>> { let mut results = Vec::<(i64, f32)>::with_capacity(limit + 1); - self.for_each_document(&worktree_ids, |id, embedding| { - let similarity = dot(&embedding, &query_embedding); - let ix = match results - .binary_search_by(|(_, s)| similarity.partial_cmp(&s).unwrap_or(Ordering::Equal)) + self.for_each_document(&worktree_ids, |relative_path, id, embedding| { + if (include_globs.is_empty() + || include_globs + .iter() + .any(|include_glob| include_glob.is_match(relative_path.clone()))) + && (exclude_globs.is_empty() + || !exclude_globs + .iter() + .any(|exclude_glob| exclude_glob.is_match(relative_path.clone()))) { - Ok(ix) => ix, - Err(ix) => ix, - }; - results.insert(ix, (id, similarity)); - results.truncate(limit); + let similarity = dot(&embedding, &query_embedding); + let ix = match results.binary_search_by(|(_, s)| { + similarity.partial_cmp(&s).unwrap_or(Ordering::Equal) + }) { + Ok(ix) => ix, + Err(ix) => ix, + }; + results.insert(ix, (id, similarity)); + results.truncate(limit); + } })?; let ids = results.into_iter().map(|(id, _)| id).collect::>(); @@ -273,12 +286,12 @@ impl VectorDatabase { fn for_each_document( &self, worktree_ids: &[i64], - mut f: impl FnMut(i64, Vec), + mut f: impl FnMut(String, i64, Vec), ) -> Result<()> { let mut query_statement = self.db.prepare( " SELECT - documents.id, documents.embedding + files.relative_path, documents.id, documents.embedding FROM documents, files WHERE @@ -289,10 +302,10 @@ impl VectorDatabase { query_statement .query_map(params![ids_to_sql(worktree_ids)], |row| { - Ok((row.get(0)?, row.get::<_, Embedding>(1)?)) + Ok((row.get(0)?, row.get(1)?, row.get::<_, Embedding>(2)?)) })? .filter_map(|row| row.ok()) - .for_each(|(id, embedding)| f(id, embedding.0)); + .for_each(|(relative_path, id, embedding)| f(relative_path, id, embedding.0)); Ok(()) } diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 6e0477491518a0c4a18ebfa1c24ddaf51eaf1948..32a11a42ebdcb01205869bcb273784582e291dcf 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -11,6 +11,7 @@ use anyhow::{anyhow, Result}; use db::VectorDatabase; use embedding::{EmbeddingProvider, OpenAIEmbeddings}; use futures::{channel::oneshot, Future}; +use globset::{Glob, GlobMatcher}; use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task, WeakModelHandle}; use language::{Anchor, Buffer, Language, LanguageRegistry}; use parking_lot::Mutex; @@ -624,6 +625,8 @@ impl SemanticIndex { project: ModelHandle, phrase: String, limit: usize, + include_globs: Vec, + exclude_globs: Vec, cx: &mut ModelContext, ) -> Task>> { let project_state = if let Some(state) = self.projects.get(&project.downgrade()) { @@ -657,12 +660,16 @@ impl SemanticIndex { .next() .unwrap(); - database.top_k_search(&worktree_db_ids, &phrase_embedding, limit) + database.top_k_search( + &worktree_db_ids, + &phrase_embedding, + limit, + include_globs, + exclude_globs, + ) }) .await?; - dbg!(&documents); - let mut tasks = Vec::new(); let mut ranges = Vec::new(); let weak_project = project.downgrade(); diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index 31c96ca207bb3da1ace202bd81df461f27ba229b..366d634ddb68df629832b23c3777d6f5cc775b7c 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -7,6 +7,7 @@ use crate::{ }; use anyhow::Result; use async_trait::async_trait; +use globset::Glob; use gpui::{Task, TestAppContext}; use language::{Language, LanguageConfig, LanguageRegistry, ToOffset}; use pretty_assertions::assert_eq; @@ -96,7 +97,7 @@ async fn test_semantic_index(cx: &mut TestAppContext) { let search_results = store .update(cx, |store, cx| { - store.search_project(project.clone(), "aaaa".to_string(), 5, cx) + store.search_project(project.clone(), "aaaa".to_string(), 5, vec![], vec![], cx) }) .await .unwrap(); @@ -109,6 +110,60 @@ async fn test_semantic_index(cx: &mut TestAppContext) { ); }); + // Test Include Files Functonality + let include_files = vec![Glob::new("*.rs").unwrap().compile_matcher()]; + let exclude_files = vec![Glob::new("*.rs").unwrap().compile_matcher()]; + let search_results = store + .update(cx, |store, cx| { + store.search_project( + project.clone(), + "aaaa".to_string(), + 5, + include_files, + vec![], + cx, + ) + }) + .await + .unwrap(); + + for res in &search_results { + res.buffer.read_with(cx, |buffer, _cx| { + assert!(buffer + .file() + .unwrap() + .path() + .to_str() + .unwrap() + .ends_with("rs")); + }); + } + + let search_results = store + .update(cx, |store, cx| { + store.search_project( + project.clone(), + "aaaa".to_string(), + 5, + vec![], + exclude_files, + cx, + ) + }) + .await + .unwrap(); + + for res in &search_results { + res.buffer.read_with(cx, |buffer, _cx| { + assert!(!buffer + .file() + .unwrap() + .path() + .to_str() + .unwrap() + .ends_with("rs")); + }); + } fs.save( "/the-root/src/file2.rs".as_ref(), &" From 81b05f2a083e999751646f53b72212ceedf3b6d9 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 20 Jul 2023 14:23:11 -0700 Subject: [PATCH 029/160] Optimize glob filtering of semantic search Co-authored-by: Kyle --- crates/search/src/project_search.rs | 1 - crates/semantic_index/src/db.rs | 66 +++++++---- crates/semantic_index/src/semantic_index.rs | 2 +- .../src/semantic_index_tests.rs | 103 +++++++++++------- 4 files changed, 109 insertions(+), 63 deletions(-) diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 25fc897707af6be8b97b277a2d65b8d4cf1eeb17..28085f59feb16bd9158ee766ba752f4d2cd72340 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -669,7 +669,6 @@ impl ProjectSearchView { &mut self, cx: &mut ViewContext, ) -> Option<(Vec, Vec)> { - let text = self.query_editor.read(cx).text(cx); let included_files = match Self::load_glob_set(&self.included_files_editor.read(cx).text(cx)) { Ok(included_files) => { diff --git a/crates/semantic_index/src/db.rs b/crates/semantic_index/src/db.rs index 3ba85a275d0a0d6b197bbad22d5ad5bd792a2fbf..b1e78b7aff994ca977fbbea41d595f08fb65766a 100644 --- a/crates/semantic_index/src/db.rs +++ b/crates/semantic_index/src/db.rs @@ -1,6 +1,6 @@ use crate::{parsing::Document, SEMANTIC_INDEX_VERSION}; use anyhow::{anyhow, Context, Result}; -use globset::{Glob, GlobMatcher}; +use globset::GlobMatcher; use project::Fs; use rpc::proto::Timestamp; use rusqlite::{ @@ -257,16 +257,11 @@ impl VectorDatabase { exclude_globs: Vec, ) -> Result)>> { let mut results = Vec::<(i64, f32)>::with_capacity(limit + 1); - self.for_each_document(&worktree_ids, |relative_path, id, embedding| { - if (include_globs.is_empty() - || include_globs - .iter() - .any(|include_glob| include_glob.is_match(relative_path.clone()))) - && (exclude_globs.is_empty() - || !exclude_globs - .iter() - .any(|exclude_glob| exclude_glob.is_match(relative_path.clone()))) - { + self.for_each_document( + &worktree_ids, + include_globs, + exclude_globs, + |id, embedding| { let similarity = dot(&embedding, &query_embedding); let ix = match results.binary_search_by(|(_, s)| { similarity.partial_cmp(&s).unwrap_or(Ordering::Equal) @@ -276,8 +271,8 @@ impl VectorDatabase { }; results.insert(ix, (id, similarity)); results.truncate(limit); - } - })?; + }, + )?; let ids = results.into_iter().map(|(id, _)| id).collect::>(); self.get_documents_by_ids(&ids) @@ -286,26 +281,55 @@ impl VectorDatabase { fn for_each_document( &self, worktree_ids: &[i64], - mut f: impl FnMut(String, i64, Vec), + include_globs: Vec, + exclude_globs: Vec, + mut f: impl FnMut(i64, Vec), ) -> Result<()> { + let mut file_query = self.db.prepare( + " + SELECT + id, relative_path + FROM + files + WHERE + worktree_id IN rarray(?) + ", + )?; + + let mut file_ids = Vec::::new(); + let mut rows = file_query.query([ids_to_sql(worktree_ids)])?; + while let Some(row) = rows.next()? { + let file_id = row.get(0)?; + let relative_path = row.get_ref(1)?.as_str()?; + let included = include_globs.is_empty() + || include_globs + .iter() + .any(|glob| glob.is_match(relative_path)); + let excluded = exclude_globs + .iter() + .any(|glob| glob.is_match(relative_path)); + if included && !excluded { + file_ids.push(file_id); + } + } + let mut query_statement = self.db.prepare( " SELECT - files.relative_path, documents.id, documents.embedding + id, embedding FROM - documents, files + documents WHERE - documents.file_id = files.id AND - files.worktree_id IN rarray(?) + file_id IN rarray(?) ", )?; query_statement - .query_map(params![ids_to_sql(worktree_ids)], |row| { - Ok((row.get(0)?, row.get(1)?, row.get::<_, Embedding>(2)?)) + .query_map(params![ids_to_sql(&file_ids)], |row| { + Ok((row.get(0)?, row.get::<_, Embedding>(1)?)) })? .filter_map(|row| row.ok()) - .for_each(|(relative_path, id, embedding)| f(relative_path, id, embedding.0)); + .for_each(|(id, embedding)| f(id, embedding.0)); Ok(()) } diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 32a11a42ebdcb01205869bcb273784582e291dcf..215ca38a28845fdf8b24d8c5d0a5d1249a03bcec 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -11,7 +11,7 @@ use anyhow::{anyhow, Result}; use db::VectorDatabase; use embedding::{EmbeddingProvider, OpenAIEmbeddings}; use futures::{channel::oneshot, Future}; -use globset::{Glob, GlobMatcher}; +use globset::GlobMatcher; use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task, WeakModelHandle}; use language::{Anchor, Buffer, Language, LanguageRegistry}; use parking_lot::Mutex; diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index 366d634ddb68df629832b23c3777d6f5cc775b7c..432f6b5b5328ed7bf72c52a34a762de0baacb7de 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -3,7 +3,7 @@ use crate::{ embedding::EmbeddingProvider, parsing::{subtract_ranges, CodeContextRetriever, Document}, semantic_index_settings::SemanticIndexSettings, - SemanticIndex, + SearchResult, SemanticIndex, }; use anyhow::Result; use async_trait::async_trait; @@ -46,21 +46,21 @@ async fn test_semantic_index(cx: &mut TestAppContext) { "src": { "file1.rs": " fn aaa() { - println!(\"aaaa!\"); + println!(\"aaaaaaaaaaaa!\"); } - fn zzzzzzzzz() { + fn zzzzz() { println!(\"SLEEPING\"); } ".unindent(), "file2.rs": " fn bbb() { - println!(\"bbbb!\"); + println!(\"bbbbbbbbbbbbb!\"); } ".unindent(), "file3.toml": " - ZZZZZZZ = 5 - ".unindent(), + ZZZZZZZZZZZZZZZZZZ = 5 + ".unindent(), } }), ) @@ -97,27 +97,37 @@ async fn test_semantic_index(cx: &mut TestAppContext) { let search_results = store .update(cx, |store, cx| { - store.search_project(project.clone(), "aaaa".to_string(), 5, vec![], vec![], cx) + store.search_project( + project.clone(), + "aaaaaabbbbzz".to_string(), + 5, + vec![], + vec![], + cx, + ) }) .await .unwrap(); - search_results[0].buffer.read_with(cx, |buffer, _cx| { - assert_eq!(search_results[0].range.start.to_offset(buffer), 0); - assert_eq!( - buffer.file().unwrap().path().as_ref(), - Path::new("src/file1.rs") - ); - }); + assert_search_results( + &search_results, + &[ + (Path::new("src/file1.rs").into(), 0), + (Path::new("src/file2.rs").into(), 0), + (Path::new("src/file3.toml").into(), 0), + (Path::new("src/file1.rs").into(), 45), + ], + cx, + ); // Test Include Files Functonality let include_files = vec![Glob::new("*.rs").unwrap().compile_matcher()]; let exclude_files = vec![Glob::new("*.rs").unwrap().compile_matcher()]; - let search_results = store + let rust_only_search_results = store .update(cx, |store, cx| { store.search_project( project.clone(), - "aaaa".to_string(), + "aaaaaabbbbzz".to_string(), 5, include_files, vec![], @@ -127,23 +137,21 @@ async fn test_semantic_index(cx: &mut TestAppContext) { .await .unwrap(); - for res in &search_results { - res.buffer.read_with(cx, |buffer, _cx| { - assert!(buffer - .file() - .unwrap() - .path() - .to_str() - .unwrap() - .ends_with("rs")); - }); - } + assert_search_results( + &rust_only_search_results, + &[ + (Path::new("src/file1.rs").into(), 0), + (Path::new("src/file2.rs").into(), 0), + (Path::new("src/file1.rs").into(), 45), + ], + cx, + ); - let search_results = store + let no_rust_search_results = store .update(cx, |store, cx| { store.search_project( project.clone(), - "aaaa".to_string(), + "aaaaaabbbbzz".to_string(), 5, vec![], exclude_files, @@ -153,17 +161,12 @@ async fn test_semantic_index(cx: &mut TestAppContext) { .await .unwrap(); - for res in &search_results { - res.buffer.read_with(cx, |buffer, _cx| { - assert!(!buffer - .file() - .unwrap() - .path() - .to_str() - .unwrap() - .ends_with("rs")); - }); - } + assert_search_results( + &no_rust_search_results, + &[(Path::new("src/file3.toml").into(), 0)], + cx, + ); + fs.save( "/the-root/src/file2.rs".as_ref(), &" @@ -195,6 +198,26 @@ async fn test_semantic_index(cx: &mut TestAppContext) { ); } +#[track_caller] +fn assert_search_results( + actual: &[SearchResult], + expected: &[(Arc, usize)], + cx: &TestAppContext, +) { + let actual = actual + .iter() + .map(|search_result| { + search_result.buffer.read_with(cx, |buffer, _cx| { + ( + buffer.file().unwrap().path().clone(), + search_result.range.start.to_offset(buffer), + ) + }) + }) + .collect::>(); + assert_eq!(actual, expected); +} + #[gpui::test] async fn test_code_context_retrieval_rust() { let language = rust_lang(); From 1610e270d6422271bd39006214c2a5410bc320c9 Mon Sep 17 00:00:00 2001 From: Alex Viscreanu Date: Fri, 21 Jul 2023 13:16:00 +0200 Subject: [PATCH 030/160] feat(workspace): add action for closing inactive editors on all panes --- assets/keymaps/default.json | 1 + crates/workspace/src/workspace.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 883b0c1872a47ea9242716cfbd39298ccdfacb94..5c841d19b2ca1b5bf54e5ca93c5f7d10341876b5 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -22,6 +22,7 @@ "alt-cmd-right": "pane::ActivateNextItem", "cmd-w": "pane::CloseActiveItem", "alt-cmd-t": "pane::CloseInactiveItems", + "ctrl-alt-cmd-w": "workspace::CloseInactiveEditors", "cmd-k u": "pane::CloseCleanItems", "cmd-k cmd-w": "pane::CloseAllItems", "cmd-shift-w": "workspace::CloseWindow", diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 0ebd01e1f7a706e1e2baf3b15ff1f35a51a3fb7f..6694cc06a32ff416323cea047539759a8ee62e39 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -122,6 +122,7 @@ actions!( NewFile, NewWindow, CloseWindow, + CloseInactiveEditors, AddFolderToProject, Unfollow, Save, @@ -239,6 +240,7 @@ pub fn init(app_state: Arc, cx: &mut AppContext) { cx.add_async_action(Workspace::follow_next_collaborator); cx.add_async_action(Workspace::close); + cx.add_async_action(Workspace::close_inactive_editors); cx.add_global_action(Workspace::close_global); cx.add_global_action(restart); cx.add_async_action(Workspace::save_all); @@ -1633,6 +1635,34 @@ impl Workspace { } } + pub fn close_inactive_editors( + &mut self, + _: &CloseInactiveEditors, + cx: &mut ViewContext, + ) -> Option>> { + let current_pane = self.active_pane(); + + // let mut tasks: Vec>> = Vec::new(); + current_pane + .update(cx, |pane, cx| { + pane.close_inactive_items(&CloseInactiveItems, cx).unwrap() + }) + .detach_and_log_err(cx); + + for pane in self.panes() { + if pane.id() == current_pane.id() { + continue; + } + + pane.update(cx, |pane: &mut Pane, cx| { + pane.close_all_items(&CloseAllItems, cx).unwrap() + }) + .detach_and_log_err(cx); + } + + Some(Task::ready(Ok(()))) + } + pub fn toggle_dock(&mut self, dock_side: DockPosition, cx: &mut ViewContext) { let dock = match dock_side { DockPosition::Left => &self.left_dock, From 458916409c5455a0b6df6494aa235e1d03e15bde Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Thu, 20 Jul 2023 12:32:27 -0600 Subject: [PATCH 031/160] Add a mode indicator for vim This is the second most common remaining complaint (after :w not working). Fixes: zed-industries/community#409 --- Cargo.lock | 1 + crates/theme/src/theme.rs | 1 + crates/vim/Cargo.toml | 2 + crates/vim/src/mode_indicator.rs | 68 +++++++++++++++++++++++++++++ crates/vim/src/vim.rs | 2 + crates/zed/src/zed.rs | 2 + styles/src/style_tree/status_bar.ts | 1 + 7 files changed, 77 insertions(+) create mode 100644 crates/vim/src/mode_indicator.rs diff --git a/Cargo.lock b/Cargo.lock index f0c8917aa28d300e1aea521f7c936c3ce918a984..e805a87230f1a4551b361fac825dc6b3556e3c19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8523,6 +8523,7 @@ dependencies = [ "serde_derive", "serde_json", "settings", + "theme", "tokio", "util", "workspace", diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 81ae7a65cab6e83e4d97901e786140e2e8304887..de0701a343c47df81ef58f51d92ca5877428108e 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -402,6 +402,7 @@ pub struct StatusBar { pub height: f32, pub item_spacing: f32, pub cursor_position: TextStyle, + pub vim_mode: TextStyle, pub active_language: Interactive, pub auto_update_progress_message: TextStyle, pub auto_update_done_message: TextStyle, diff --git a/crates/vim/Cargo.toml b/crates/vim/Cargo.toml index 47a85f4ed314f4b20dd7fe39eda0b1814bf9bc67..3a5974d6c92afec181426c1a35e49ddf787d9eae 100644 --- a/crates/vim/Cargo.toml +++ b/crates/vim/Cargo.toml @@ -32,6 +32,7 @@ language = { path = "../language" } search = { path = "../search" } settings = { path = "../settings" } workspace = { path = "../workspace" } +theme = { path = "../theme" } [dev-dependencies] indoc.workspace = true @@ -44,3 +45,4 @@ project = { path = "../project", features = ["test-support"] } util = { path = "../util", features = ["test-support"] } settings = { path = "../settings" } workspace = { path = "../workspace", features = ["test-support"] } +theme = { path = "../theme", features = ["test-support"] } diff --git a/crates/vim/src/mode_indicator.rs b/crates/vim/src/mode_indicator.rs new file mode 100644 index 0000000000000000000000000000000000000000..ef8d1590180c395696d894e1846af6226d016064 --- /dev/null +++ b/crates/vim/src/mode_indicator.rs @@ -0,0 +1,68 @@ +use gpui::{ + elements::{Empty, Label}, + AnyElement, Element, Entity, View, ViewContext, +}; +use workspace::{item::ItemHandle, StatusItemView}; + +use crate::{state::Mode, Vim}; + +pub struct ModeIndicator { + mode: Option, +} + +impl ModeIndicator { + pub fn new(cx: &mut ViewContext) -> Self { + cx.observe_global::(|this, cx| { + let vim = Vim::read(cx); + if vim.enabled { + this.set_mode(Some(Vim::read(cx).state.mode), cx) + } else { + this.set_mode(None, cx) + } + }) + .detach(); + Self { mode: None } + } + + pub fn set_mode(&mut self, mode: Option, cx: &mut ViewContext) { + if mode != self.mode { + self.mode = mode; + cx.notify(); + } + } +} + +impl Entity for ModeIndicator { + type Event = (); +} + +impl View for ModeIndicator { + fn ui_name() -> &'static str { + "ModeIndicator" + } + + fn render(&mut self, cx: &mut ViewContext) -> AnyElement { + if let Some(mode) = self.mode { + let theme = &theme::current(cx).workspace.status_bar; + let text = match mode { + Mode::Normal => "", + Mode::Insert => "--- INSERT ---", + Mode::Visual { line: false } => "--- VISUAL ---", + Mode::Visual { line: true } => "--- VISUAL LINE ---", + }; + Label::new(text, theme.vim_mode.clone()).into_any() + } else { + Empty::new().into_any() + } + } +} + +impl StatusItemView for ModeIndicator { + fn set_active_pane_item( + &mut self, + _active_pane_item: Option<&dyn ItemHandle>, + _cx: &mut ViewContext, + ) { + // nothing to do. + } +} diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 69b94428ddad7a3f4f96cf4ad40abcbecd5a3124..8ab110ba1e761ffbb506fb7b43ec6679a241d7a6 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -3,6 +3,7 @@ mod test; mod editor_events; mod insert; +mod mode_indicator; mod motion; mod normal; mod object; @@ -18,6 +19,7 @@ use gpui::{ ViewHandle, WeakViewHandle, WindowContext, }; use language::CursorShape; +pub use mode_indicator::ModeIndicator; use motion::Motion; use normal::normal_replace; use serde::Deserialize; diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 6bbba0bd02b7da005c9711d00591952baf2594ae..645371d4195f27b9ec51e41a5482ac54c1532737 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -312,8 +312,10 @@ pub fn initialize_workspace( feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace) }); let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new()); + let vim_mode = cx.add_view(|cx| vim::ModeIndicator::new(cx)); workspace.status_bar().update(cx, |status_bar, cx| { status_bar.add_left_item(diagnostic_summary, cx); + status_bar.add_left_item(vim_mode, cx); status_bar.add_left_item(activity_indicator, cx); status_bar.add_right_item(feedback_button, cx); status_bar.add_right_item(copilot, cx); diff --git a/styles/src/style_tree/status_bar.ts b/styles/src/style_tree/status_bar.ts index 9aeea866f3b33c738e6630c54ce92b21408cb6f2..b4273cbf993b73d64a52561ac4a6981ff646bb3f 100644 --- a/styles/src/style_tree/status_bar.ts +++ b/styles/src/style_tree/status_bar.ts @@ -27,6 +27,7 @@ export default function status_bar(): any { }, border: border(layer, { top: true, overlay: true }), cursor_position: text(layer, "sans", "variant"), + vim_mode: text(layer, "sans", "variant"), active_language: interactive({ base: { padding: { left: 6, right: 6 }, From d14a484a20d731511db502a7eacad4dcfbab9383 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 21 Jul 2023 13:19:26 -0600 Subject: [PATCH 032/160] Add support for adding/removing status items --- crates/workspace/src/status_bar.rs | 55 ++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/crates/workspace/src/status_bar.rs b/crates/workspace/src/status_bar.rs index 6fc1467566bec3a3c93ff6807a15bf1fec988e67..6fd3bd53108962ebe983b7d5a31d76ff64a3d0ee 100644 --- a/crates/workspace/src/status_bar.rs +++ b/crates/workspace/src/status_bar.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use std::{any::TypeId, ops::Range}; use crate::{ItemHandle, Pane}; use gpui::{ @@ -27,6 +27,7 @@ trait StatusItemViewHandle { active_pane_item: Option<&dyn ItemHandle>, cx: &mut WindowContext, ); + fn ui_name(&self) -> &'static str; } pub struct StatusBar { @@ -57,7 +58,6 @@ impl View for StatusBar { .with_margin_right(theme.item_spacing) })) .into_any(), - right: Flex::row() .with_children(self.right_items.iter().rev().map(|i| { ChildView::new(i.as_any(), cx) @@ -96,6 +96,53 @@ impl StatusBar { cx.notify(); } + pub fn position_of_item(&mut self) -> Option + where + T: StatusItemView, + { + self.position_of_named_item(T::ui_name()) + } + + pub fn position_of_named_item(&mut self, name: &str) -> Option { + for (index, item) in self.left_items.iter().enumerate() { + if item.as_ref().ui_name() == name { + return Some(index); + } + } + for (index, item) in self.right_items.iter().enumerate() { + if item.as_ref().ui_name() == name { + return Some(index + self.left_items.len()); + } + } + return None; + } + + pub fn insert_item_after( + &mut self, + position: usize, + item: ViewHandle, + cx: &mut ViewContext, + ) where + T: 'static + StatusItemView, + { + if position < self.left_items.len() { + self.left_items.insert(position, Box::new(item)) + } else { + self.right_items + .insert(position - self.left_items.len(), Box::new(item)) + } + cx.notify() + } + + pub fn remove_item_at(&mut self, position: usize, cx: &mut ViewContext) { + if position < self.left_items.len() { + self.left_items.remove(position); + } else { + self.right_items.remove(position - self.left_items.len()); + } + cx.notify(); + } + pub fn add_right_item(&mut self, item: ViewHandle, cx: &mut ViewContext) where T: 'static + StatusItemView, @@ -133,6 +180,10 @@ impl StatusItemViewHandle for ViewHandle { this.set_active_pane_item(active_pane_item, cx) }); } + + fn ui_name(&self) -> &'static str { + T::ui_name() + } } impl From<&dyn StatusItemViewHandle> for AnyViewHandle { From b4b53eb5f19a49fa2659b41e3c10d48bbbf73447 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Sat, 22 Jul 2023 21:48:45 -0700 Subject: [PATCH 033/160] Refactor resize handle code to be amenable to cascading resizes --- crates/workspace/src/pane_group.rs | 72 ++++++++++++++++++------------ 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index e60f6deb2ff2663918c7fa3dd8c2722a69dbb2e9..8d95465388723e36b14845e6e8573bb0bdbe33c1 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -780,6 +780,11 @@ mod element { let mut bounding_boxes = self.bounding_boxes.borrow_mut(); bounding_boxes.clear(); + let sizes = self + .children + .iter() + .map(|child| child.size()) + .collect::>(); let mut children_iter = self.children.iter_mut().enumerate().peekable(); while let Some((ix, child)) = children_iter.next() { let child_start = child_origin.clone(); @@ -792,8 +797,7 @@ mod element { Axis::Vertical => child_origin += vec2f(0.0, child.size().y()), } - if let Some(Some((next_ix, next_child))) = can_resize.then(|| children_iter.peek()) - { + if can_resize && children_iter.peek().is_some() { scene.push_stacking_context(None, None); let handle_origin = match self.axis { @@ -823,14 +827,7 @@ mod element { }); let axis = self.axis; - let child_size = child.size(); - let next_child_size = next_child.size(); let drag_bounds = visible_bounds.clone(); - let flexes = self.flexes.borrow(); - let current_flex = flexes[ix]; - let next_ix = *next_ix; - let next_flex = flexes[next_ix]; - drop(flexes); enum ResizeHandle {} let mut mouse_region = MouseRegion::new::( cx.view_id(), @@ -840,49 +837,68 @@ mod element { mouse_region = mouse_region .on_drag(MouseButton::Left, { let flexes = self.flexes.clone(); + let sizes = sizes.clone(); move |drag, workspace: &mut Workspace, cx| { let min_size = match axis { Axis::Horizontal => HORIZONTAL_MIN_SIZE, Axis::Vertical => VERTICAL_MIN_SIZE, }; // Don't allow resizing to less than the minimum size, if elements are already too small - if min_size - 1. > child_size.along(axis) - || min_size - 1. > next_child_size.along(axis) - { + if min_size - 1. > sizes[ix].along(axis) { return; } + let mut flexes = flexes.borrow_mut(); + let mut current_target_size = (drag.position - child_start).along(axis); - let proposed_current_pixel_change = - current_target_size - child_size.along(axis); + let mut proposed_current_pixel_change = + current_target_size - sizes[ix].along(axis); + + let flex_changes = |target_size, target_ix| { + let current_pixel_change = target_size - sizes[ix].along(axis); + let flex_change = + current_pixel_change / drag_bounds.length_along(axis); + let current_target_flex = flexes[target_ix] + flex_change; + let next_target_flex = flexes[target_ix + 1] - flex_change; + (current_target_flex, next_target_flex) + }; if proposed_current_pixel_change < 0. { current_target_size = f32::max(current_target_size, min_size); + let (current_target_flex, next_target_flex) = + flex_changes(current_target_size, ix); + + *flexes.get_mut(ix).unwrap() = current_target_flex; + *flexes.get_mut(ix + 1).unwrap() = next_target_flex; } else if proposed_current_pixel_change > 0. { - // TODO: cascade this change to other children if current item is at min size - let next_target_size = f32::max( - next_child_size.along(axis) - proposed_current_pixel_change, + let mut next_target_size = f32::max( + sizes[ix + 1].along(axis) - proposed_current_pixel_change, min_size, ); + current_target_size = f32::min( current_target_size, - child_size.along(axis) + next_child_size.along(axis) + sizes[ix].along(axis) + sizes[ix + 1].along(axis) - next_target_size, ); - } - let current_pixel_change = - current_target_size - child_size.along(axis); - let flex_change = - current_pixel_change / drag_bounds.length_along(axis); - let current_target_flex = current_flex + flex_change; - let next_target_flex = next_flex - flex_change; + let (current_target_flex, next_target_flex) = + flex_changes(current_target_size, ix); + + // TODO: make this into a loop + *flexes.get_mut(ix).unwrap() = current_target_flex; + *flexes.get_mut(ix + 1).unwrap() = next_target_flex; + + // let mut ix_offset = 0; - let mut borrow = flexes.borrow_mut(); - *borrow.get_mut(ix).unwrap() = current_target_flex; - *borrow.get_mut(next_ix).unwrap() = next_target_flex; + // while proposed_current_pixel_change > 0. + // && ix + 1 + ix_offset < flexes.len() + // { + + // } + } workspace.schedule_serialize(cx); cx.notify(); From 28ee05b3240bc27eb951187fcff00e727dbb7a18 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Sun, 23 Jul 2023 01:00:52 -0700 Subject: [PATCH 034/160] WIP: cascade split resizes --- crates/workspace/src/pane_group.rs | 176 ++++++++++++++++------------- 1 file changed, 98 insertions(+), 78 deletions(-) diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index 8d95465388723e36b14845e6e8573bb0bdbe33c1..bed99d6cc4062ee99ee1da27fd8330cd76783266 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -587,14 +587,16 @@ mod element { use std::{cell::RefCell, ops::Range, rc::Rc}; use gpui::{ + elements::MouseEventHandler, geometry::{ rect::RectF, vector::{vec2f, Vector2F}, }, json::{self, ToJson}, platform::{CursorStyle, MouseButton}, - AnyElement, Axis, CursorRegion, Element, LayoutContext, MouseRegion, RectFExt, - SceneBuilder, SizeConstraint, Vector2FExt, ViewContext, + scene::MouseDrag, + AnyElement, Axis, CursorRegion, Element, EventContext, LayoutContext, MouseRegion, + RectFExt, SceneBuilder, SizeConstraint, Vector2FExt, ViewContext, }; use crate::{ @@ -682,6 +684,90 @@ mod element { *cross_axis_max = cross_axis_max.max(child_size.along(cross_axis)); } } + + fn handle_resize( + flexes: Rc>>, + axis: Axis, + ix: usize, + child_start: Vector2F, + drag_bounds: RectF, + ) -> impl Fn(MouseDrag, &mut Workspace, &mut EventContext) { + let size = move |ix, flexes: &[f32]| { + drag_bounds.length_along(axis) * (flexes[ix] / flexes.len() as f32) + }; + + move |drag, workspace: &mut Workspace, cx| { + let min_size = match axis { + Axis::Horizontal => HORIZONTAL_MIN_SIZE, + Axis::Vertical => VERTICAL_MIN_SIZE, + }; + let mut flexes = flexes.borrow_mut(); + + // Don't allow resizing to less than the minimum size, if elements are already too small + if min_size - 1. > size(ix, flexes.as_slice()) { + return; + } + + let mut current_target_size = (drag.position - child_start).along(axis); + + let mut proposed_current_pixel_change = + current_target_size - size(ix, flexes.as_slice()); + + let flex_changes = |pixel_dx, target_ix, flexes: &[f32]| { + let flex_change = pixel_dx / drag_bounds.length_along(axis); + let current_target_flex = flexes[target_ix] + flex_change; + let next_target_flex = flexes[target_ix + 1] - flex_change; + (current_target_flex, next_target_flex) + }; + + if proposed_current_pixel_change < 0. { + current_target_size = f32::max(current_target_size, min_size); + let current_pixel_change = current_target_size - size(ix, flexes.as_slice()); + + let (current_target_flex, next_target_flex) = + flex_changes(current_pixel_change, ix, flexes.as_slice()); + + flexes[ix] = current_target_flex; + flexes[ix + 1] = next_target_flex; + } else if proposed_current_pixel_change > 0. { + let mut ix_offset = 0; + while proposed_current_pixel_change > 0.01 && ix + 1 + ix_offset < flexes.len() + { + let next_target_size = f32::max( + size(ix + 1, flexes.as_slice()) - proposed_current_pixel_change, + min_size, + ); + + current_target_size = f32::min( + current_target_size, + size(ix, flexes.as_slice()) + size(ix + 1, flexes.as_slice()) + - next_target_size, + ); + + let current_pixel_change = + current_target_size - size(ix, flexes.as_slice()); + + let (current_target_flex, next_target_flex) = + flex_changes(current_pixel_change, ix, flexes.as_slice()); + + flexes[ix_offset + ix] = current_target_flex; + flexes[ix_offset + ix + 1] = next_target_flex; + + dbg!( + current_pixel_change, + proposed_current_pixel_change, + proposed_current_pixel_change - current_pixel_change + ); + proposed_current_pixel_change -= current_pixel_change; + ix_offset += 1; + } + dbg!("done"); + } + + workspace.schedule_serialize(cx); + cx.notify(); + } + } } impl Extend> for PaneAxisElement { @@ -780,11 +866,6 @@ mod element { let mut bounding_boxes = self.bounding_boxes.borrow_mut(); bounding_boxes.clear(); - let sizes = self - .children - .iter() - .map(|child| child.size()) - .collect::>(); let mut children_iter = self.children.iter_mut().enumerate().peekable(); while let Some((ix, child)) = children_iter.next() { let child_start = child_origin.clone(); @@ -826,8 +907,6 @@ mod element { style, }); - let axis = self.axis; - let drag_bounds = visible_bounds.clone(); enum ResizeHandle {} let mut mouse_region = MouseRegion::new::( cx.view_id(), @@ -835,75 +914,16 @@ mod element { handle_bounds, ); mouse_region = mouse_region - .on_drag(MouseButton::Left, { - let flexes = self.flexes.clone(); - let sizes = sizes.clone(); - move |drag, workspace: &mut Workspace, cx| { - let min_size = match axis { - Axis::Horizontal => HORIZONTAL_MIN_SIZE, - Axis::Vertical => VERTICAL_MIN_SIZE, - }; - // Don't allow resizing to less than the minimum size, if elements are already too small - if min_size - 1. > sizes[ix].along(axis) { - return; - } - - let mut flexes = flexes.borrow_mut(); - - let mut current_target_size = - (drag.position - child_start).along(axis); - - let mut proposed_current_pixel_change = - current_target_size - sizes[ix].along(axis); - - let flex_changes = |target_size, target_ix| { - let current_pixel_change = target_size - sizes[ix].along(axis); - let flex_change = - current_pixel_change / drag_bounds.length_along(axis); - let current_target_flex = flexes[target_ix] + flex_change; - let next_target_flex = flexes[target_ix + 1] - flex_change; - (current_target_flex, next_target_flex) - }; - - if proposed_current_pixel_change < 0. { - current_target_size = f32::max(current_target_size, min_size); - let (current_target_flex, next_target_flex) = - flex_changes(current_target_size, ix); - - *flexes.get_mut(ix).unwrap() = current_target_flex; - *flexes.get_mut(ix + 1).unwrap() = next_target_flex; - } else if proposed_current_pixel_change > 0. { - let mut next_target_size = f32::max( - sizes[ix + 1].along(axis) - proposed_current_pixel_change, - min_size, - ); - - current_target_size = f32::min( - current_target_size, - sizes[ix].along(axis) + sizes[ix + 1].along(axis) - - next_target_size, - ); - - let (current_target_flex, next_target_flex) = - flex_changes(current_target_size, ix); - - // TODO: make this into a loop - *flexes.get_mut(ix).unwrap() = current_target_flex; - *flexes.get_mut(ix + 1).unwrap() = next_target_flex; - - // let mut ix_offset = 0; - - // while proposed_current_pixel_change > 0. - // && ix + 1 + ix_offset < flexes.len() - // { - - // } - } - - workspace.schedule_serialize(cx); - cx.notify(); - } - }) + .on_drag( + MouseButton::Left, + Self::handle_resize( + self.flexes.clone(), + self.axis, + ix, + child_start, + visible_bounds.clone(), + ), + ) .on_click(MouseButton::Left, { let flexes = self.flexes.clone(); move |e, v: &mut Workspace, cx| { From 429a2fc623bb1b56f9d67b2d48f20fad629b04b2 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Sun, 23 Jul 2023 13:28:30 -0700 Subject: [PATCH 035/160] Add drag end events Fix left dragging cascade WIP: Implement right dragging, WIP: use drag end events to set and reset state around initial flex orientation --- crates/gpui/src/app/window.rs | 20 ++++++++++++++++ crates/gpui/src/scene/mouse_event.rs | 1 + crates/workspace/src/pane_group.rs | 34 +++++++++++++++------------- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 1dc88d2e717a985be4aed9984597f4abf7b92a1a..e4beb58873cfb3599be6fc81a2ad0bd87ce811c3 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -518,6 +518,18 @@ impl<'a> WindowContext<'a> { // NOTE: The order of event pushes is important! MouseUp events MUST be fired // before click events, and so the MouseUp events need to be pushed before // MouseClick events. + + // Synthesize one last drag event to end the drag + mouse_events.push(MouseEvent::Drag(MouseDrag { + region: Default::default(), + prev_mouse_position: self.window.mouse_position, + platform_event: MouseMovedEvent { + position: e.position, + pressed_button: Some(e.button), + modifiers: e.modifiers, + }, + end: true, + })); mouse_events.push(MouseEvent::Up(MouseUp { region: Default::default(), platform_event: e.clone(), @@ -565,8 +577,16 @@ impl<'a> WindowContext<'a> { region: Default::default(), prev_mouse_position: self.window.mouse_position, platform_event: e.clone(), + end: false, })); } else if let Some((_, clicked_button)) = self.window.clicked_region { + mouse_events.push(MouseEvent::Drag(MouseDrag { + region: Default::default(), + prev_mouse_position: self.window.mouse_position, + platform_event: e.clone(), + end: true, + })); + // Mouse up event happened outside the current window. Simulate mouse up button event let button_event = e.to_button_event(clicked_button); mouse_events.push(MouseEvent::Up(MouseUp { diff --git a/crates/gpui/src/scene/mouse_event.rs b/crates/gpui/src/scene/mouse_event.rs index a492da771b848574e29411e91d8876873ead4917..21d3716aa6ea083baad8196c7d88d870b38615bd 100644 --- a/crates/gpui/src/scene/mouse_event.rs +++ b/crates/gpui/src/scene/mouse_event.rs @@ -32,6 +32,7 @@ pub struct MouseDrag { pub region: RectF, pub prev_mouse_position: Vector2F, pub platform_event: MouseMovedEvent, + pub end: bool } impl Deref for MouseDrag { diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index bed99d6cc4062ee99ee1da27fd8330cd76783266..05684229ccc6c23184b9ecf55c2c7128fe368682 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -587,7 +587,6 @@ mod element { use std::{cell::RefCell, ops::Range, rc::Rc}; use gpui::{ - elements::MouseEventHandler, geometry::{ rect::RectF, vector::{vec2f, Vector2F}, @@ -697,6 +696,10 @@ mod element { }; move |drag, workspace: &mut Workspace, cx| { + if drag.end { + dbg!("FINISHED"); + return; + } let min_size = match axis { Axis::Horizontal => HORIZONTAL_MIN_SIZE, Axis::Vertical => VERTICAL_MIN_SIZE, @@ -713,10 +716,10 @@ mod element { let mut proposed_current_pixel_change = current_target_size - size(ix, flexes.as_slice()); - let flex_changes = |pixel_dx, target_ix, flexes: &[f32]| { + let flex_changes = |pixel_dx, target_ix, next: isize, flexes: &[f32]| { let flex_change = pixel_dx / drag_bounds.length_along(axis); let current_target_flex = flexes[target_ix] + flex_change; - let next_target_flex = flexes[target_ix + 1] - flex_change; + let next_target_flex = flexes[(target_ix as isize + next) as usize] - flex_change; (current_target_flex, next_target_flex) }; @@ -725,7 +728,7 @@ mod element { let current_pixel_change = current_target_size - size(ix, flexes.as_slice()); let (current_target_flex, next_target_flex) = - flex_changes(current_pixel_change, ix, flexes.as_slice()); + flex_changes(current_pixel_change, ix, 1, flexes.as_slice()); flexes[ix] = current_target_flex; flexes[ix + 1] = next_target_flex; @@ -733,35 +736,31 @@ mod element { let mut ix_offset = 0; while proposed_current_pixel_change > 0.01 && ix + 1 + ix_offset < flexes.len() { + let current_ix = ix_offset + ix; let next_target_size = f32::max( - size(ix + 1, flexes.as_slice()) - proposed_current_pixel_change, + size(current_ix + 1, flexes.as_slice()) - proposed_current_pixel_change, min_size, ); current_target_size = f32::min( current_target_size, - size(ix, flexes.as_slice()) + size(ix + 1, flexes.as_slice()) + size(current_ix, flexes.as_slice()) + + size(current_ix + 1, flexes.as_slice()) - next_target_size, ); let current_pixel_change = - current_target_size - size(ix, flexes.as_slice()); + current_target_size - size(current_ix, flexes.as_slice()); let (current_target_flex, next_target_flex) = - flex_changes(current_pixel_change, ix, flexes.as_slice()); + flex_changes(current_pixel_change, current_ix, 1, flexes.as_slice()); - flexes[ix_offset + ix] = current_target_flex; - flexes[ix_offset + ix + 1] = next_target_flex; + flexes[current_ix] = current_target_flex; + flexes[current_ix + 1] = next_target_flex; - dbg!( - current_pixel_change, - proposed_current_pixel_change, - proposed_current_pixel_change - current_pixel_change - ); proposed_current_pixel_change -= current_pixel_change; ix_offset += 1; } - dbg!("done"); } workspace.schedule_serialize(cx); @@ -924,6 +923,9 @@ mod element { visible_bounds.clone(), ), ) + .on_down(MouseButton::Left, |_, _: &mut Workspace, _| { + dbg!("INITIATE"); + }) .on_click(MouseButton::Left, { let flexes = self.flexes.clone(); move |e, v: &mut Workspace, cx| { From fe388ed71ef9d8877fbef216061ac807acc1ba3d Mon Sep 17 00:00:00 2001 From: Quinn Wilton Date: Sun, 23 Jul 2023 14:39:43 -0700 Subject: [PATCH 036/160] Add tree-sitter-nix --- Cargo.lock | 10 +++ Cargo.toml | 1 + crates/zed/Cargo.toml | 1 + crates/zed/src/languages.rs | 1 + crates/zed/src/languages/nix/config.toml | 11 +++ crates/zed/src/languages/nix/highlights.scm | 95 +++++++++++++++++++++ 6 files changed, 119 insertions(+) create mode 100644 crates/zed/src/languages/nix/config.toml create mode 100644 crates/zed/src/languages/nix/highlights.scm diff --git a/Cargo.lock b/Cargo.lock index f0c8917aa28d300e1aea521f7c936c3ce918a984..175b3d931532bce1fbe9c4f41bbcfab557e88fdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8065,6 +8065,15 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "tree-sitter-nix" +version = "0.0.1" +source = "git+https://github.com/nix-community/tree-sitter-nix?rev=66e3e9ce9180ae08fc57372061006ef83f0abde7#66e3e9ce9180ae08fc57372061006ef83f0abde7" +dependencies = [ + "cc", + "tree-sitter", +] + [[package]] name = "tree-sitter-php" version = "0.19.1" @@ -9550,6 +9559,7 @@ dependencies = [ "tree-sitter-json 0.20.0", "tree-sitter-lua", "tree-sitter-markdown", + "tree-sitter-nix", "tree-sitter-php", "tree-sitter-python", "tree-sitter-racket", diff --git a/Cargo.toml b/Cargo.toml index fa824115cb82b02c2428f2f1bd9889a0b93a5757..ca13a4eb2fd2b0af34a115274ea4347c57883259 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -129,6 +129,7 @@ tree-sitter-svelte = { git = "https://github.com/Himujjal/tree-sitter-svelte", r tree-sitter-racket = { git = "https://github.com/zed-industries/tree-sitter-racket", rev = "eb010cf2c674c6fd9a6316a84e28ef90190fe51a"} tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml", rev = "f545a41f57502e1b5ddf2a6668896c1b0620f930"} tree-sitter-lua = "0.0.14" +tree-sitter-nix = { git = "https://github.com/nix-community/tree-sitter-nix", rev = "66e3e9ce9180ae08fc57372061006ef83f0abde7" } [patch.crates-io] tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "49226023693107fba9a1191136a4f47f38cdca73" } diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index c5bf313701e76f1ea7084f7299f7596b7b0306df..88185acfc29f03f8e3cae0e51488c3e2234a684b 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -126,6 +126,7 @@ tree-sitter-svelte.workspace = true tree-sitter-racket.workspace = true tree-sitter-yaml.workspace = true tree-sitter-lua.workspace = true +tree-sitter-nix.workspace = true url = "2.2" urlencoding = "2.1.2" diff --git a/crates/zed/src/languages.rs b/crates/zed/src/languages.rs index 365e8a30232e5dc9193b1077b16186f3c44e9d19..9ba0f2755240e0e22357ffc2b8ea2fd6dda02dd3 100644 --- a/crates/zed/src/languages.rs +++ b/crates/zed/src/languages.rs @@ -152,6 +152,7 @@ pub fn init(languages: Arc, node_runtime: Arc) { tree_sitter_php::language(), vec![Arc::new(php::IntelephenseLspAdapter::new(node_runtime))], ); + language("nix", tree_sitter_nix::language(), vec![]) } #[cfg(any(test, feature = "test-support"))] diff --git a/crates/zed/src/languages/nix/config.toml b/crates/zed/src/languages/nix/config.toml new file mode 100644 index 0000000000000000000000000000000000000000..778f0a6f050a72eb231d374eeff09bff3591cbdd --- /dev/null +++ b/crates/zed/src/languages/nix/config.toml @@ -0,0 +1,11 @@ +name = "Nix" +path_suffixes = ["nix"] +line_comment = "# " +block_comment = ["/* ", " */"] +autoclose_before = ";:.,=}])>` \n\t\"" +brackets = [ + { start = "{", end = "}", close = true, newline = true }, + { start = "[", end = "]", close = true, newline = true }, + { start = "(", end = ")", close = true, newline = true }, + { start = "<", end = ">", close = true, newline = true }, +] diff --git a/crates/zed/src/languages/nix/highlights.scm b/crates/zed/src/languages/nix/highlights.scm new file mode 100644 index 0000000000000000000000000000000000000000..d63a46411ae830a0b86d55a18e405a8086af6548 --- /dev/null +++ b/crates/zed/src/languages/nix/highlights.scm @@ -0,0 +1,95 @@ +(comment) @comment + +[ + "if" + "then" + "else" + "let" + "inherit" + "in" + "rec" + "with" + "assert" + "or" +] @keyword + +[ + (string_expression) + (indented_string_expression) +] @string + +[ + (path_expression) + (hpath_expression) + (spath_expression) +] @string.special.path + +(uri_expression) @link_uri + +[ + (integer_expression) + (float_expression) +] @number + +(interpolation + "${" @punctuation.special + "}" @punctuation.special) @embedded + +(escape_sequence) @escape +(dollar_escape) @escape + +(function_expression + universal: (identifier) @parameter +) + +(formal + name: (identifier) @parameter + "?"? @punctuation.delimiter) + +(select_expression + attrpath: (attrpath (identifier)) @property) + +(apply_expression + function: [ + (variable_expression (identifier)) @function + (select_expression + attrpath: (attrpath + attr: (identifier) @function .))]) + +(unary_expression + operator: _ @operator) + +(binary_expression + operator: _ @operator) + +(variable_expression (identifier) @variable) + +(binding + attrpath: (attrpath (identifier)) @property) + +"=" @operator + +[ + ";" + "." + "," +] @punctuation.delimiter + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +(identifier) @variable + +((identifier) @function.builtin + (#match? @function.builtin "^(__add|__addErrorContext|__all|__any|__appendContext|__attrNames|__attrValues|__bitAnd|__bitOr|__bitXor|__catAttrs|__compareVersions|__concatLists|__concatMap|__concatStringsSep|__deepSeq|__div|__elem|__elemAt|__fetchurl|__filter|__filterSource|__findFile|__foldl'|__fromJSON|__functionArgs|__genList|__genericClosure|__getAttr|__getContext|__getEnv|__hasAttr|__hasContext|__hashFile|__hashString|__head|__intersectAttrs|__isAttrs|__isBool|__isFloat|__isFunction|__isInt|__isList|__isPath|__isString|__langVersion|__length|__lessThan|__listToAttrs|__mapAttrs|__match|__mul|__parseDrvName|__partition|__path|__pathExists|__readDir|__readFile|__replaceStrings|__seq|__sort|__split|__splitVersion|__storePath|__stringLength|__sub|__substring|__tail|__toFile|__toJSON|__toPath|__toXML|__trace|__tryEval|__typeOf|__unsafeDiscardOutputDependency|__unsafeDiscardStringContext|__unsafeGetAttrPos|__valueSize|abort|baseNameOf|derivation|derivationStrict|dirOf|fetchGit|fetchMercurial|fetchTarball|fromTOML|import|isNull|map|placeholder|removeAttrs|scopedImport|throw|toString)$") + (#is-not? local)) + +((identifier) @variable.builtin + (#match? @variable.builtin "^(__currentSystem|__currentTime|__nixPath|__nixVersion|__storeDir|builtins|false|null|true)$") + (#is-not? local)) From 25e4bcea7f8154afdea7de62b66b4fd025bb6f5f Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Mon, 24 Jul 2023 08:04:46 -0700 Subject: [PATCH 037/160] Implement cascading resize algorithm --- crates/workspace/src/pane_group.rs | 96 ++++++++++++++++-------------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index 05684229ccc6c23184b9ecf55c2c7128fe368682..22435b56f0576fccd2629c135b9cca9011935010 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -584,7 +584,7 @@ impl SplitDirection { } mod element { - use std::{cell::RefCell, ops::Range, rc::Rc}; + use std::{cell::RefCell, iter::from_fn, ops::Range, rc::Rc}; use gpui::{ geometry::{ @@ -687,7 +687,7 @@ mod element { fn handle_resize( flexes: Rc>>, axis: Axis, - ix: usize, + preceding_ix: usize, child_start: Vector2F, drag_bounds: RectF, ) -> impl Fn(MouseDrag, &mut Workspace, &mut EventContext) { @@ -697,7 +697,7 @@ mod element { move |drag, workspace: &mut Workspace, cx| { if drag.end { - dbg!("FINISHED"); + // Clear cascading resize state return; } let min_size = match axis { @@ -707,60 +707,66 @@ mod element { let mut flexes = flexes.borrow_mut(); // Don't allow resizing to less than the minimum size, if elements are already too small - if min_size - 1. > size(ix, flexes.as_slice()) { + if min_size - 1. > size(preceding_ix, flexes.as_slice()) { return; } - let mut current_target_size = (drag.position - child_start).along(axis); - - let mut proposed_current_pixel_change = - current_target_size - size(ix, flexes.as_slice()); + let mut proposed_current_pixel_change = (drag.position - child_start).along(axis) + - size(preceding_ix, flexes.as_slice()); let flex_changes = |pixel_dx, target_ix, next: isize, flexes: &[f32]| { let flex_change = pixel_dx / drag_bounds.length_along(axis); let current_target_flex = flexes[target_ix] + flex_change; - let next_target_flex = flexes[(target_ix as isize + next) as usize] - flex_change; + let next_target_flex = + flexes[(target_ix as isize + next) as usize] - flex_change; (current_target_flex, next_target_flex) }; - if proposed_current_pixel_change < 0. { - current_target_size = f32::max(current_target_size, min_size); - let current_pixel_change = current_target_size - size(ix, flexes.as_slice()); - - let (current_target_flex, next_target_flex) = - flex_changes(current_pixel_change, ix, 1, flexes.as_slice()); - - flexes[ix] = current_target_flex; - flexes[ix + 1] = next_target_flex; - } else if proposed_current_pixel_change > 0. { + let mut successors = from_fn({ + let forward = proposed_current_pixel_change > 0.; let mut ix_offset = 0; - while proposed_current_pixel_change > 0.01 && ix + 1 + ix_offset < flexes.len() - { - let current_ix = ix_offset + ix; - let next_target_size = f32::max( - size(current_ix + 1, flexes.as_slice()) - proposed_current_pixel_change, - min_size, - ); - - current_target_size = f32::min( - current_target_size, - size(current_ix, flexes.as_slice()) - + size(current_ix + 1, flexes.as_slice()) - - next_target_size, - ); - - let current_pixel_change = - current_target_size - size(current_ix, flexes.as_slice()); - - let (current_target_flex, next_target_flex) = - flex_changes(current_pixel_change, current_ix, 1, flexes.as_slice()); - - flexes[current_ix] = current_target_flex; - flexes[current_ix + 1] = next_target_flex; - - proposed_current_pixel_change -= current_pixel_change; + let len = flexes.len(); + move || { + let result = if forward { + (preceding_ix + 1 + ix_offset < len).then(|| preceding_ix + ix_offset) + } else { + (preceding_ix as isize - ix_offset as isize >= 0) + .then(|| preceding_ix - ix_offset) + }; + ix_offset += 1; + + result } + }); + + while proposed_current_pixel_change.abs() > 0. { + let Some(current_ix) = successors.next() else { + break; + }; + + let next_target_size = f32::max( + size(current_ix + 1, flexes.as_slice()) - proposed_current_pixel_change, + min_size, + ); + + let current_target_size = f32::max( + size(current_ix, flexes.as_slice()) + + size(current_ix + 1, flexes.as_slice()) + - next_target_size, + min_size, + ); + + let current_pixel_change = + current_target_size - size(current_ix, flexes.as_slice()); + + let (current_target_flex, next_target_flex) = + flex_changes(current_pixel_change, current_ix, 1, flexes.as_slice()); + + flexes[current_ix] = current_target_flex; + flexes[current_ix + 1] = next_target_flex; + + proposed_current_pixel_change -= current_pixel_change; } workspace.schedule_serialize(cx); @@ -924,7 +930,7 @@ mod element { ), ) .on_down(MouseButton::Left, |_, _: &mut Workspace, _| { - dbg!("INITIATE"); + // Save cascading resize state }) .on_click(MouseButton::Left, { let flexes = self.flexes.clone(); From 43d94e37eccd15ac5fad02811989682c387728b6 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Mon, 24 Jul 2023 09:37:48 -0600 Subject: [PATCH 038/160] Refactor mode indicator to remove itself One of the problems we had is that the status_bar shows a gap between items, and we want to not add an additional gap for an invisible status indicator. --- crates/theme/src/theme.rs | 2 +- crates/vim/src/mode_indicator.rs | 49 +++++++++--------------- crates/vim/src/test.rs | 58 ++++++++++++++++++++++++++++- crates/vim/src/vim.rs | 52 ++++++++++++++++++++++++++ crates/workspace/src/status_bar.rs | 17 ++++++--- crates/zed/src/zed.rs | 3 +- styles/src/style_tree/status_bar.ts | 2 +- 7 files changed, 142 insertions(+), 41 deletions(-) diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index de0701a343c47df81ef58f51d92ca5877428108e..82c3f2a142f278945b70f55901d0d201edb210c8 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -402,7 +402,7 @@ pub struct StatusBar { pub height: f32, pub item_spacing: f32, pub cursor_position: TextStyle, - pub vim_mode: TextStyle, + pub vim_mode_indicator: TextStyle, pub active_language: Interactive, pub auto_update_progress_message: TextStyle, pub auto_update_done_message: TextStyle, diff --git a/crates/vim/src/mode_indicator.rs b/crates/vim/src/mode_indicator.rs index ef8d1590180c395696d894e1846af6226d016064..683024267c139ec058b60d6204098c1316a608a4 100644 --- a/crates/vim/src/mode_indicator.rs +++ b/crates/vim/src/mode_indicator.rs @@ -1,30 +1,18 @@ -use gpui::{ - elements::{Empty, Label}, - AnyElement, Element, Entity, View, ViewContext, -}; +use gpui::{elements::Label, AnyElement, Element, Entity, View, ViewContext}; use workspace::{item::ItemHandle, StatusItemView}; -use crate::{state::Mode, Vim}; +use crate::state::Mode; pub struct ModeIndicator { - mode: Option, + pub mode: Mode, } impl ModeIndicator { - pub fn new(cx: &mut ViewContext) -> Self { - cx.observe_global::(|this, cx| { - let vim = Vim::read(cx); - if vim.enabled { - this.set_mode(Some(Vim::read(cx).state.mode), cx) - } else { - this.set_mode(None, cx) - } - }) - .detach(); - Self { mode: None } + pub fn new(mode: Mode) -> Self { + Self { mode } } - pub fn set_mode(&mut self, mode: Option, cx: &mut ViewContext) { + pub fn set_mode(&mut self, mode: Mode, cx: &mut ViewContext) { if mode != self.mode { self.mode = mode; cx.notify(); @@ -38,22 +26,21 @@ impl Entity for ModeIndicator { impl View for ModeIndicator { fn ui_name() -> &'static str { - "ModeIndicator" + "ModeIndicatorView" } fn render(&mut self, cx: &mut ViewContext) -> AnyElement { - if let Some(mode) = self.mode { - let theme = &theme::current(cx).workspace.status_bar; - let text = match mode { - Mode::Normal => "", - Mode::Insert => "--- INSERT ---", - Mode::Visual { line: false } => "--- VISUAL ---", - Mode::Visual { line: true } => "--- VISUAL LINE ---", - }; - Label::new(text, theme.vim_mode.clone()).into_any() - } else { - Empty::new().into_any() - } + let theme = &theme::current(cx).workspace.status_bar; + // we always choose text to be 12 monospace characters + // so that as the mode indicator changes, the rest of the + // UI stays still. + let text = match self.mode { + Mode::Normal => "-- NORMAL --", + Mode::Insert => "-- INSERT --", + Mode::Visual { line: false } => "-- VISUAL --", + Mode::Visual { line: true } => "VISUAL LINE ", + }; + Label::new(text, theme.vim_mode_indicator.clone()).into_any() } } diff --git a/crates/vim/src/test.rs b/crates/vim/src/test.rs index 8ed649e61bef510d8cf9fa76eb8d2edf3eca4e69..96d6a2b69019d47ef7d131f1ef66d6c218089ec1 100644 --- a/crates/vim/src/test.rs +++ b/crates/vim/src/test.rs @@ -4,6 +4,8 @@ mod neovim_connection; mod vim_binding_test_context; mod vim_test_context; +use std::sync::Arc; + use command_palette::CommandPalette; use editor::DisplayPoint; pub use neovim_backed_binding_test_context::*; @@ -14,7 +16,7 @@ pub use vim_test_context::*; use indoc::indoc; use search::BufferSearchBar; -use crate::state::Mode; +use crate::{state::Mode, ModeIndicator}; #[gpui::test] async fn test_initially_disabled(cx: &mut gpui::TestAppContext) { @@ -195,3 +197,57 @@ async fn test_selection_on_search(cx: &mut gpui::TestAppContext) { cx.simulate_keystrokes(["shift-n"]); cx.assert_state(indoc! {"aa\nbb\nˇcc\ncc\ncc\n"}, Mode::Normal); } + +#[gpui::test] +async fn test_status_indicator( + cx: &mut gpui::TestAppContext, + deterministic: Arc, +) { + let mut cx = VimTestContext::new(cx, true).await; + deterministic.run_until_parked(); + + let mode_indicator = cx.workspace(|workspace, cx| { + let status_bar = workspace.status_bar().read(cx); + let mode_indicator = status_bar.item_of_type::(); + assert!(mode_indicator.is_some()); + mode_indicator.unwrap() + }); + + assert_eq!( + cx.workspace(|_, cx| mode_indicator.read(cx).mode), + Mode::Normal + ); + + // shows the correct mode + cx.simulate_keystrokes(["i"]); + deterministic.run_until_parked(); + assert_eq!( + cx.workspace(|_, cx| mode_indicator.read(cx).mode), + Mode::Insert + ); + + // shows even in search + cx.simulate_keystrokes(["escape", "v", "/"]); + deterministic.run_until_parked(); + assert_eq!( + cx.workspace(|_, cx| mode_indicator.read(cx).mode), + Mode::Visual { line: false } + ); + + // hides if vim mode is disabled + cx.disable_vim(); + deterministic.run_until_parked(); + cx.workspace(|workspace, cx| { + let status_bar = workspace.status_bar().read(cx); + let mode_indicator = status_bar.item_of_type::(); + assert!(mode_indicator.is_none()); + }); + + cx.enable_vim(); + deterministic.run_until_parked(); + cx.workspace(|workspace, cx| { + let status_bar = workspace.status_bar().read(cx); + let mode_indicator = status_bar.item_of_type::(); + assert!(mode_indicator.is_some()); + }); +} diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 8ab110ba1e761ffbb506fb7b43ec6679a241d7a6..54d18825cdde124437ee3ada99335e7ddaf62faf 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -118,6 +118,7 @@ pub fn observe_keystrokes(cx: &mut WindowContext) { pub struct Vim { active_editor: Option>, editor_subscription: Option, + mode_indicator: Option>, enabled: bool, state: VimState, @@ -177,6 +178,10 @@ impl Vim { self.state.mode = mode; self.state.operator_stack.clear(); + if let Some(mode_indicator) = &self.mode_indicator { + mode_indicator.update(cx, |mode_indicator, cx| mode_indicator.set_mode(mode, cx)) + } + // Sync editor settings like clip mode self.sync_vim_settings(cx); @@ -259,6 +264,51 @@ impl Vim { } } + fn sync_mode_indicator(cx: &mut AppContext) { + cx.spawn(|mut cx| async move { + let workspace = match cx.update(|cx| { + cx.update_active_window(|cx| { + cx.root_view() + .downcast_ref::() + .map(|workspace| workspace.downgrade()) + }) + }) { + Some(Some(workspace)) => workspace, + _ => { + return Ok(()); + } + }; + + workspace.update(&mut cx, |workspace, cx| { + Vim::update(cx, |vim, cx| { + workspace.status_bar().update(cx, |status_bar, cx| { + let current_position = status_bar.position_of_item::(); + if vim.enabled && current_position.is_none() { + if vim.mode_indicator.is_none() { + vim.mode_indicator = + Some(cx.add_view(|_| ModeIndicator::new(vim.state.mode))); + }; + let mode_indicator = vim.mode_indicator.as_ref().unwrap(); + // TODO: would it be better to depend on the diagnostics crate + // so we can pass the type directly? + let position = status_bar.position_of_named_item("DiagnosticIndicator"); + if let Some(position) = position { + status_bar.insert_item_after(position, mode_indicator.clone(), cx) + } else { + status_bar.add_left_item(mode_indicator.clone(), cx) + } + } else if !vim.enabled { + if let Some(position) = current_position { + status_bar.remove_item_at(position, cx) + } + } + }) + }) + }) + }) + .detach_and_log_err(cx); + } + fn set_enabled(&mut self, enabled: bool, cx: &mut AppContext) { if self.enabled != enabled { self.enabled = enabled; @@ -309,6 +359,8 @@ impl Vim { self.unhook_vim_settings(editor, cx); } }); + + Vim::sync_mode_indicator(cx); } fn unhook_vim_settings(&self, editor: &mut Editor, cx: &mut ViewContext) { diff --git a/crates/workspace/src/status_bar.rs b/crates/workspace/src/status_bar.rs index 6fd3bd53108962ebe983b7d5a31d76ff64a3d0ee..7b1c11dcf25e88a11c11d028b1b8864521b5f251 100644 --- a/crates/workspace/src/status_bar.rs +++ b/crates/workspace/src/status_bar.rs @@ -1,4 +1,4 @@ -use std::{any::TypeId, ops::Range}; +use std::ops::Range; use crate::{ItemHandle, Pane}; use gpui::{ @@ -96,14 +96,21 @@ impl StatusBar { cx.notify(); } - pub fn position_of_item(&mut self) -> Option + pub fn position_of_item(&self) -> Option where T: StatusItemView, { self.position_of_named_item(T::ui_name()) } - pub fn position_of_named_item(&mut self, name: &str) -> Option { + pub fn item_of_type(&self) -> Option> { + self.left_items + .iter() + .chain(self.right_items.iter()) + .find_map(|item| item.as_any().clone().downcast()) + } + + pub fn position_of_named_item(&self, name: &str) -> Option { for (index, item) in self.left_items.iter().enumerate() { if item.as_ref().ui_name() == name { return Some(index); @@ -126,10 +133,10 @@ impl StatusBar { T: 'static + StatusItemView, { if position < self.left_items.len() { - self.left_items.insert(position, Box::new(item)) + self.left_items.insert(position + 1, Box::new(item)) } else { self.right_items - .insert(position - self.left_items.len(), Box::new(item)) + .insert(position + 1 - self.left_items.len(), Box::new(item)) } cx.notify() } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 645371d4195f27b9ec51e41a5482ac54c1532737..639e1a3f605ab2d333243ff67c8ee3c5229e5466 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -312,11 +312,10 @@ pub fn initialize_workspace( feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace) }); let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new()); - let vim_mode = cx.add_view(|cx| vim::ModeIndicator::new(cx)); workspace.status_bar().update(cx, |status_bar, cx| { status_bar.add_left_item(diagnostic_summary, cx); - status_bar.add_left_item(vim_mode, cx); status_bar.add_left_item(activity_indicator, cx); + status_bar.add_right_item(feedback_button, cx); status_bar.add_right_item(copilot, cx); status_bar.add_right_item(active_buffer_language, cx); diff --git a/styles/src/style_tree/status_bar.ts b/styles/src/style_tree/status_bar.ts index b4273cbf993b73d64a52561ac4a6981ff646bb3f..74ad7064d1bbd6e5bbc0d4e28743d0c11574583c 100644 --- a/styles/src/style_tree/status_bar.ts +++ b/styles/src/style_tree/status_bar.ts @@ -27,7 +27,7 @@ export default function status_bar(): any { }, border: border(layer, { top: true, overlay: true }), cursor_position: text(layer, "sans", "variant"), - vim_mode: text(layer, "sans", "variant"), + vim_mode_indicator: text(layer, "mono", "variant"), active_language: interactive({ base: { padding: { left: 6, right: 6 }, From baa16a2fc6d23b208f4824ad8b6130ff5385f1d1 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Mon, 24 Jul 2023 09:57:51 -0600 Subject: [PATCH 039/160] Better method ordering --- crates/workspace/src/status_bar.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/workspace/src/status_bar.rs b/crates/workspace/src/status_bar.rs index 7b1c11dcf25e88a11c11d028b1b8864521b5f251..8c3cfe20532946c088fe9947869d426319cbdd62 100644 --- a/crates/workspace/src/status_bar.rs +++ b/crates/workspace/src/status_bar.rs @@ -96,13 +96,6 @@ impl StatusBar { cx.notify(); } - pub fn position_of_item(&self) -> Option - where - T: StatusItemView, - { - self.position_of_named_item(T::ui_name()) - } - pub fn item_of_type(&self) -> Option> { self.left_items .iter() @@ -110,6 +103,13 @@ impl StatusBar { .find_map(|item| item.as_any().clone().downcast()) } + pub fn position_of_item(&self) -> Option + where + T: StatusItemView, + { + self.position_of_named_item(T::ui_name()) + } + pub fn position_of_named_item(&self, name: &str) -> Option { for (index, item) in self.left_items.iter().enumerate() { if item.as_ref().ui_name() == name { From c86096a886701c96c6dd09fca36c0281bc140111 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Tue, 25 Jul 2023 10:38:37 -0400 Subject: [PATCH 040/160] update semantic index tests for javascript --- .../src/semantic_index_tests.rs | 196 +++++++++++------- .../src/languages/javascript/embedding.scm | 92 ++++---- crates/zed/src/languages/tsx/embedding.scm | 106 ++++------ .../src/languages/typescript/embedding.scm | 116 +++++------ 4 files changed, 259 insertions(+), 251 deletions(-) diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index 432f6b5b5328ed7bf72c52a34a762de0baacb7de..9bd6efc954ced0f505d8532c3049be9be13466af 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -388,43 +388,103 @@ fn assert_documents_eq( ); } -// #[gpui::test] -// async fn test_code_context_retrieval_javascript() { -// let language = js_lang(); -// let mut retriever = CodeContextRetriever::new(); +#[gpui::test] +async fn test_code_context_retrieval_javascript() { + let language = js_lang(); + let mut retriever = CodeContextRetriever::new(); -// let text = " -// /* globals importScripts, backend */ -// function _authorize() {} + let text = " + /* globals importScripts, backend */ + function _authorize() {} + + /** + * Sometimes the frontend build is way faster than backend. + */ + export async function authorizeBank() { + _authorize(pushModal, upgradingAccountId, {}); + } -// /** -// * Sometimes the frontend build is way faster than backend. -// */ -// export async function authorizeBank() { -// _authorize(pushModal, upgradingAccountId, {}); -// } + export class SettingsPage { + /* This is a test setting */ + constructor(page) { + this.page = page; + } + } -// export class SettingsPage { -// /* This is a test setting */ -// constructor(page) { -// this.page = page; -// } -// } + /* This is a test comment */ + class TestClass {} -// /* This is a test comment */ -// class TestClass {} + /* Schema for editor_events in Clickhouse. */ + export interface ClickhouseEditorEvent { + installation_id: string + operation: string + } + " + .unindent(); -// /* Schema for editor_events in Clickhouse. */ -// export interface ClickhouseEditorEvent { -// installation_id: string -// operation: string -// } -// " -// .unindent(); + let documents = retriever.parse_file(&text, language.clone()).unwrap(); -// let parsed_files = retriever -// .parse_file(Path::new("foo.js"), &text, language) -// .unwrap(); + assert_documents_eq( + &documents, + &[ + ( + " + /* globals importScripts, backend */ + function _authorize() {}" + .unindent(), + 37, + ), + ( + " + /** + * Sometimes the frontend build is way faster than backend. + */ + export async function authorizeBank() { + _authorize(pushModal, upgradingAccountId, {}); + }" + .unindent(), + 131, + ), + ( + " + export class SettingsPage { + /* This is a test setting */ + constructor(page) { + this.page = page; + } + }" + .unindent(), + 225, + ), + ( + " + /* This is a test setting */ + constructor(page) { + this.page = page; + }" + .unindent(), + 290, + ), + ( + " + /* This is a test comment */ + class TestClass {}" + .unindent(), + 374, + ), + ( + " + /* Schema for editor_events in Clickhouse. */ + export interface ClickhouseEditorEvent { + installation_id: string + operation: string + }" + .unindent(), + 440, + ), + ], + ) +} // let test_documents = &[ // Document { @@ -924,86 +984,74 @@ fn js_lang() -> Arc { ( (comment)* @context . + [ (export_statement (function_declaration "async"? @name "function" @name - name: (_) @name)) @item - ) - - ( - (comment)* @context - . + name: (_) @name)) (function_declaration "async"? @name "function" @name - name: (_) @name) @item - ) + name: (_) @name) + ] @item + ) ( (comment)* @context . + [ (export_statement (class_declaration "class" @name - name: (_) @name)) @item - ) - - ( - (comment)* @context - . + name: (_) @name)) (class_declaration "class" @name - name: (_) @name) @item - ) - - ( - (comment)* @context - . - (method_definition - [ - "get" - "set" - "async" - "*" - "static" - ]* @name - name: (_) @name) @item - ) + name: (_) @name) + ] @item + ) ( (comment)* @context . + [ (export_statement (interface_declaration "interface" @name - name: (_) @name)) @item - ) - - ( - (comment)* @context - . + name: (_) @name)) (interface_declaration "interface" @name - name: (_) @name) @item - ) + name: (_) @name) + ] @item + ) ( (comment)* @context . + [ (export_statement (enum_declaration "enum" @name - name: (_) @name)) @item - ) + name: (_) @name)) + (enum_declaration + "enum" @name + name: (_) @name) + ] @item + ) ( (comment)* @context . - (enum_declaration - "enum" @name + (method_definition + [ + "get" + "set" + "async" + "*" + "static" + ]* @name name: (_) @name) @item - ) + ) "# .unindent(), diff --git a/crates/zed/src/languages/javascript/embedding.scm b/crates/zed/src/languages/javascript/embedding.scm index a2140400318db95a8d29074402ab2d212561a79b..ab1a3b6b063c3bf57adad3c302a156fcd0239448 100644 --- a/crates/zed/src/languages/javascript/embedding.scm +++ b/crates/zed/src/languages/javascript/embedding.scm @@ -1,38 +1,60 @@ ( (comment)* @context . - (export_statement + [ + (export_statement + (function_declaration + "async"? @name + "function" @name + name: (_) @name)) (function_declaration "async"? @name "function" @name - name: (_) @name)) @item - ) + name: (_) @name) + ] @item +) ( (comment)* @context . - (function_declaration - "async"? @name - "function" @name - name: (_) @name) @item - ) + [ + (export_statement + (class_declaration + "class" @name + name: (_) @name)) + (class_declaration + "class" @name + name: (_) @name) + ] @item +) ( (comment)* @context . - (export_statement - (class_declaration - "class" @name - name: (_) @name)) @item - ) + [ + (export_statement + (interface_declaration + "interface" @name + name: (_) @name)) + (interface_declaration + "interface" @name + name: (_) @name) + ] @item +) ( (comment)* @context . - (class_declaration - "class" @name - name: (_) @name) @item - ) + [ + (export_statement + (enum_declaration + "enum" @name + name: (_) @name)) + (enum_declaration + "enum" @name + name: (_) @name) + ] @item +) ( (comment)* @context @@ -46,38 +68,4 @@ "static" ]* @name name: (_) @name) @item - ) - -( - (comment)* @context - . - (export_statement - (interface_declaration - "interface" @name - name: (_) @name)) @item - ) - -( - (comment)* @context - . - (interface_declaration - "interface" @name - name: (_) @name) @item - ) - -( - (comment)* @context - . - (export_statement - (enum_declaration - "enum" @name - name: (_) @name)) @item - ) - -( - (comment)* @context - . - (enum_declaration - "enum" @name - name: (_) @name) @item - ) +) diff --git a/crates/zed/src/languages/tsx/embedding.scm b/crates/zed/src/languages/tsx/embedding.scm index 4bb4fea254d0cf86f2fbb9d5c8f657e06238971f..ddcff665841091aa170bd5f9bb60439a2cadb2c5 100644 --- a/crates/zed/src/languages/tsx/embedding.scm +++ b/crates/zed/src/languages/tsx/embedding.scm @@ -1,99 +1,85 @@ ( (comment)* @context . - (export_statement + [ + (export_statement + (function_declaration + "async"? @name + "function" @name + name: (_) @name)) (function_declaration "async"? @name "function" @name - name: (_) @name)) @item + name: (_) @name) + ] @item ) ( (comment)* @context . - (function_declaration - "async"? @name - "function" @name - name: (_) @name) @item - ) - -( - (comment)* @context - . - (export_statement + [ + (export_statement + (class_declaration + "class" @name + name: (_) @name)) (class_declaration "class" @name - name: (_) @name)) @item - ) - -( - (comment)* @context - . - (class_declaration - "class" @name - name: (_) @name) @item - ) - -( - (comment)* @context - . - (method_definition - [ - "get" - "set" - "async" - "*" - "static" - ]* @name - name: (_) @name) @item + name: (_) @name) + ] @item ) ( (comment)* @context . - (export_statement + [ + (export_statement + (interface_declaration + "interface" @name + name: (_) @name)) (interface_declaration "interface" @name - name: (_) @name)) @item - ) - -( - (comment)* @context - . - (interface_declaration - "interface" @name - name: (_) @name) @item + name: (_) @name) + ] @item ) ( (comment)* @context . - (export_statement + [ + (export_statement + (enum_declaration + "enum" @name + name: (_) @name)) (enum_declaration "enum" @name - name: (_) @name)) @item - ) - -( - (comment)* @context - . - (enum_declaration - "enum" @name - name: (_) @name) @item + name: (_) @name) + ] @item ) ( (comment)* @context . - (export_statement + [ + (export_statement + (type_alias_declaration + "type" @name + name: (_) @name)) (type_alias_declaration "type" @name - name: (_) @name)) @item + name: (_) @name) + ] @item ) ( (comment)* @context . - (type_alias_declaration - "type" @name - name: (_) @name) @item) + (method_definition + [ + "get" + "set" + "async" + "*" + "static" + ]* @name + name: (_) @name) @item + ) diff --git a/crates/zed/src/languages/typescript/embedding.scm b/crates/zed/src/languages/typescript/embedding.scm index 4bb4fea254d0cf86f2fbb9d5c8f657e06238971f..3170cb7c957e51e00c175c7eaa2b4b51deda042a 100644 --- a/crates/zed/src/languages/typescript/embedding.scm +++ b/crates/zed/src/languages/typescript/embedding.scm @@ -1,99 +1,85 @@ ( (comment)* @context . - (export_statement + [ + (export_statement + (function_declaration + "async"? @name + "function" @name + name: (_) @name)) (function_declaration "async"? @name "function" @name - name: (_) @name)) @item - ) + name: (_) @name) + ] @item +) ( (comment)* @context . - (function_declaration - "async"? @name - "function" @name - name: (_) @name) @item - ) - -( - (comment)* @context - . - (export_statement + [ + (export_statement + (class_declaration + "class" @name + name: (_) @name)) (class_declaration "class" @name - name: (_) @name)) @item - ) - -( - (comment)* @context - . - (class_declaration - "class" @name - name: (_) @name) @item - ) - -( - (comment)* @context - . - (method_definition - [ - "get" - "set" - "async" - "*" - "static" - ]* @name - name: (_) @name) @item - ) + name: (_) @name) + ] @item +) ( (comment)* @context . - (export_statement + [ + (export_statement + (interface_declaration + "interface" @name + name: (_) @name)) (interface_declaration "interface" @name - name: (_) @name)) @item - ) + name: (_) @name) + ] @item +) ( (comment)* @context . - (interface_declaration - "interface" @name - name: (_) @name) @item - ) - -( - (comment)* @context - . - (export_statement + [ + (export_statement + (enum_declaration + "enum" @name + name: (_) @name)) (enum_declaration "enum" @name - name: (_) @name)) @item - ) + name: (_) @name) + ] @item +) ( (comment)* @context . - (enum_declaration - "enum" @name - name: (_) @name) @item - ) - -( - (comment)* @context - . - (export_statement + [ + (export_statement + (type_alias_declaration + "type" @name + name: (_) @name)) (type_alias_declaration "type" @name - name: (_) @name)) @item - ) + name: (_) @name) + ] @item +) ( (comment)* @context . - (type_alias_declaration - "type" @name - name: (_) @name) @item) + (method_definition + [ + "get" + "set" + "async" + "*" + "static" + ]* @name + name: (_) @name) @item +) From 1f65effe57b85d126fcb5689d6d37ec3f768502e Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Tue, 25 Jul 2023 10:58:44 -0600 Subject: [PATCH 041/160] Update status bar theming Co-Authored-By: Nate Butler --- Cargo.lock | 1 + crates/theme/src/theme.rs | 2 +- crates/vim/Cargo.toml | 1 + crates/vim/src/mode_indicator.rs | 5 ++++- crates/vim/src/vim.rs | 5 ++--- crates/workspace/src/status_bar.rs | 8 ++------ styles/src/style_tree/status_bar.ts | 31 +++++++++++++---------------- 7 files changed, 25 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e805a87230f1a4551b361fac825dc6b3556e3c19..704eba74b1d10130259c7a2ea5e2176db21aa621 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8514,6 +8514,7 @@ dependencies = [ "indoc", "itertools", "language", + "language_selector", "log", "nvim-rs", "parking_lot 0.11.2", diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 82c3f2a142f278945b70f55901d0d201edb210c8..4766f636f37bbef734e364eaff95e0fb63e152ac 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -402,7 +402,7 @@ pub struct StatusBar { pub height: f32, pub item_spacing: f32, pub cursor_position: TextStyle, - pub vim_mode_indicator: TextStyle, + pub vim_mode_indicator: ContainedText, pub active_language: Interactive, pub auto_update_progress_message: TextStyle, pub auto_update_done_message: TextStyle, diff --git a/crates/vim/Cargo.toml b/crates/vim/Cargo.toml index 3a5974d6c92afec181426c1a35e49ddf787d9eae..2d394e3dcf8c127d48a010ce54c045d7d87a4aed 100644 --- a/crates/vim/Cargo.toml +++ b/crates/vim/Cargo.toml @@ -33,6 +33,7 @@ search = { path = "../search" } settings = { path = "../settings" } workspace = { path = "../workspace" } theme = { path = "../theme" } +language_selector = { path = "../language_selector"} [dev-dependencies] indoc.workspace = true diff --git a/crates/vim/src/mode_indicator.rs b/crates/vim/src/mode_indicator.rs index 683024267c139ec058b60d6204098c1316a608a4..e0d2b65955489ae72742febd13de1b0c5e1e5e41 100644 --- a/crates/vim/src/mode_indicator.rs +++ b/crates/vim/src/mode_indicator.rs @@ -40,7 +40,10 @@ impl View for ModeIndicator { Mode::Visual { line: false } => "-- VISUAL --", Mode::Visual { line: true } => "VISUAL LINE ", }; - Label::new(text, theme.vim_mode_indicator.clone()).into_any() + Label::new(text, theme.vim_mode_indicator.text.clone()) + .contained() + .with_style(theme.vim_mode_indicator.container) + .into_any() } } diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 54d18825cdde124437ee3ada99335e7ddaf62faf..363901d260ef3a0b54f390923a1439a9ed59f277 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -289,9 +289,8 @@ impl Vim { Some(cx.add_view(|_| ModeIndicator::new(vim.state.mode))); }; let mode_indicator = vim.mode_indicator.as_ref().unwrap(); - // TODO: would it be better to depend on the diagnostics crate - // so we can pass the type directly? - let position = status_bar.position_of_named_item("DiagnosticIndicator"); + let position = status_bar + .position_of_item::(); if let Some(position) = position { status_bar.insert_item_after(position, mode_indicator.clone(), cx) } else { diff --git a/crates/workspace/src/status_bar.rs b/crates/workspace/src/status_bar.rs index 8c3cfe20532946c088fe9947869d426319cbdd62..8726eaf5698ae68cdde7205089cd22969ae266a1 100644 --- a/crates/workspace/src/status_bar.rs +++ b/crates/workspace/src/status_bar.rs @@ -107,17 +107,13 @@ impl StatusBar { where T: StatusItemView, { - self.position_of_named_item(T::ui_name()) - } - - pub fn position_of_named_item(&self, name: &str) -> Option { for (index, item) in self.left_items.iter().enumerate() { - if item.as_ref().ui_name() == name { + if item.as_ref().ui_name() == T::ui_name() { return Some(index); } } for (index, item) in self.right_items.iter().enumerate() { - if item.as_ref().ui_name() == name { + if item.as_ref().ui_name() == T::ui_name() { return Some(index + self.left_items.len()); } } diff --git a/styles/src/style_tree/status_bar.ts b/styles/src/style_tree/status_bar.ts index 74ad7064d1bbd6e5bbc0d4e28743d0c11574583c..06afc378235ec843d64a28313a38c05d395f1962 100644 --- a/styles/src/style_tree/status_bar.ts +++ b/styles/src/style_tree/status_bar.ts @@ -1,6 +1,8 @@ import { background, border, foreground, text } from "./components" import { interactive, toggleable } from "../element" import { useTheme } from "../common" +import { text_button } from "../component/text_button" + export default function status_bar(): any { const theme = useTheme() @@ -26,21 +28,16 @@ export default function status_bar(): any { right: 6, }, border: border(layer, { top: true, overlay: true }), - cursor_position: text(layer, "sans", "variant"), - vim_mode_indicator: text(layer, "mono", "variant"), - active_language: interactive({ - base: { - padding: { left: 6, right: 6 }, - ...text(layer, "sans", "variant"), - }, - state: { - hovered: { - ...text(layer, "sans", "on"), - }, - }, + cursor_position: text(layer, "sans", "variant", { size: "xs" }), + vim_mode_indicator: { + margin: { left: 6 }, + ...text(layer, "mono", "variant", { size: "xs" }), + }, + active_language: text_button({ + color: "variant" }), - auto_update_progress_message: text(layer, "sans", "variant"), - auto_update_done_message: text(layer, "sans", "variant"), + auto_update_progress_message: text(layer, "sans", "variant", { size: "xs" }), + auto_update_done_message: text(layer, "sans", "variant", { size: "xs" }), lsp_status: interactive({ base: { ...diagnostic_status_container, @@ -60,9 +57,9 @@ export default function status_bar(): any { }), diagnostic_message: interactive({ base: { - ...text(layer, "sans"), + ...text(layer, "sans", { size: "xs" }), }, - state: { hovered: text(layer, "sans", "hovered") }, + state: { hovered: text(layer, "sans", "hovered", { size: "xs" }) }, }), diagnostic_summary: interactive({ base: { @@ -118,7 +115,7 @@ export default function status_bar(): any { icon_color: foreground(layer, "variant"), label: { margin: { left: 6 }, - ...text(layer, "sans", { size: "sm" }), + ...text(layer, "sans", { size: "xs" }), }, }, state: { From 97c3d97792ec0feb1e93de302c377fe8df28fcf0 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Tue, 25 Jul 2023 13:30:38 -0400 Subject: [PATCH 042/160] update semantic index tests for cpp --- .../src/semantic_index_tests.rs | 418 +++++++----------- 1 file changed, 148 insertions(+), 270 deletions(-) diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index 9bd6efc954ced0f505d8532c3049be9be13466af..2ae9a06c0fbbeeb3371ff958612b9d94bc88daef 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -486,105 +486,6 @@ async fn test_code_context_retrieval_javascript() { ) } -// let test_documents = &[ -// Document { -// name: "function _authorize".into(), -// range: text.find("function _authorize").unwrap()..(text.find("}").unwrap() + 1), -// content: " -// The below code snippet is from file 'foo.js' - -// ```javascript -// /* globals importScripts, backend */ -// function _authorize() {} -// ```" -// .unindent(), -// embedding: vec![], -// }, -// Document { -// name: "async function authorizeBank".into(), -// range: text.find("export async").unwrap()..223, -// content: " -// The below code snippet is from file 'foo.js' - -// ```javascript -// /** -// * Sometimes the frontend build is way faster than backend. -// */ -// export async function authorizeBank() { -// _authorize(pushModal, upgradingAccountId, {}); -// } -// ```" -// .unindent(), -// embedding: vec![], -// }, -// Document { -// name: "class SettingsPage".into(), -// range: 225..343, -// content: " -// The below code snippet is from file 'foo.js' - -// ```javascript -// export class SettingsPage { -// /* This is a test setting */ -// constructor(page) { -// this.page = page; -// } -// } -// ```" -// .unindent(), -// embedding: vec![], -// }, -// Document { -// name: "constructor".into(), -// range: 290..341, -// content: " -// The below code snippet is from file 'foo.js' - -// ```javascript -// /* This is a test setting */ -// constructor(page) { -// this.page = page; -// } -// ```" -// .unindent(), -// embedding: vec![], -// }, -// Document { -// name: "class TestClass".into(), -// range: 374..392, -// content: " -// The below code snippet is from file 'foo.js' - -// ```javascript -// /* This is a test comment */ -// class TestClass {} -// ```" -// .unindent(), -// embedding: vec![], -// }, -// Document { -// name: "interface ClickhouseEditorEvent".into(), -// range: 440..532, -// content: " -// The below code snippet is from file 'foo.js' - -// ```javascript -// /* Schema for editor_events in Clickhouse. */ -// export interface ClickhouseEditorEvent { -// installation_id: string -// operation: string -// } -// ```" -// .unindent(), -// embedding: vec![], -// }, -// ]; - -// for idx in 0..test_documents.len() { -// assert_eq!(test_documents[idx], parsed_files[idx]); -// } -// } - // #[gpui::test] // async fn test_code_context_retrieval_elixir() { // let language = elixir_lang(); @@ -722,180 +623,157 @@ async fn test_code_context_retrieval_javascript() { // } // } -// #[gpui::test] -// async fn test_code_context_retrieval_cpp() { -// let language = cpp_lang(); -// let mut retriever = CodeContextRetriever::new(); - -// let text = " -// /** -// * @brief Main function -// * @returns 0 on exit -// */ -// int main() { return 0; } - -// /** -// * This is a test comment -// */ -// class MyClass { // The class -// public: // Access specifier -// int myNum; // Attribute (int variable) -// string myString; // Attribute (string variable) -// }; - -// // This is a test comment -// enum Color { red, green, blue }; - -// /** This is a preceding block comment -// * This is the second line -// */ -// struct { // Structure declaration -// int myNum; // Member (int variable) -// string myString; // Member (string variable) -// } myStructure; - -// /** -// * @brief Matrix class. -// */ -// template ::value || std::is_floating_point::value, -// bool>::type> -// class Matrix2 { -// std::vector> _mat; - -// public: -// /** -// * @brief Constructor -// * @tparam Integer ensuring integers are being evaluated and not other -// * data types. -// * @param size denoting the size of Matrix as size x size -// */ -// template ::value, -// Integer>::type> -// explicit Matrix(const Integer size) { -// for (size_t i = 0; i < size; ++i) { -// _mat.emplace_back(std::vector(size, 0)); -// } -// } -// }" -// .unindent(); +#[gpui::test] +async fn test_code_context_retrieval_cpp() { + let language = cpp_lang(); + let mut retriever = CodeContextRetriever::new(); -// let parsed_files = retriever -// .parse_file(Path::new("foo.cpp"), &text, language) -// .unwrap(); + let text = " + /** + * @brief Main function + * @returns 0 on exit + */ + int main() { return 0; } + + /** + * This is a test comment + */ + class MyClass { // The class + public: // Access specifier + int myNum; // Attribute (int variable) + string myString; // Attribute (string variable) + }; + + // This is a test comment + enum Color { red, green, blue }; + + /** This is a preceding block comment + * This is the second line + */ + struct { // Structure declaration + int myNum; // Member (int variable) + string myString; // Member (string variable) + } myStructure; + + /** + * @brief Matrix class. + */ + template ::value || std::is_floating_point::value, + bool>::type> + class Matrix2 { + std::vector> _mat; + + public: + /** + * @brief Constructor + * @tparam Integer ensuring integers are being evaluated and not other + * data types. + * @param size denoting the size of Matrix as size x size + */ + template ::value, + Integer>::type> + explicit Matrix(const Integer size) { + for (size_t i = 0; i < size; ++i) { + _mat.emplace_back(std::vector(size, 0)); + } + } + }" + .unindent(); -// let test_documents = &[ -// Document { -// name: "int main".into(), -// range: 54..78, -// content: " -// The below code snippet is from file 'foo.cpp' - -// ```cpp -// /** -// * @brief Main function -// * @returns 0 on exit -// */ -// int main() { return 0; } -// ```" -// .unindent(), -// embedding: vec![], -// }, -// Document { -// name: "class MyClass".into(), -// range: 112..295, -// content: " -// The below code snippet is from file 'foo.cpp' - -// ```cpp -// /** -// * This is a test comment -// */ -// class MyClass { // The class -// public: // Access specifier -// int myNum; // Attribute (int variable) -// string myString; // Attribute (string variable) -// } -// ```" -// .unindent(), -// embedding: vec![], -// }, -// Document { -// name: "enum Color".into(), -// range: 324..355, -// content: " -// The below code snippet is from file 'foo.cpp' - -// ```cpp -// // This is a test comment -// enum Color { red, green, blue } -// ```" -// .unindent(), -// embedding: vec![], -// }, -// Document { -// name: "struct myStructure".into(), -// range: 428..581, -// content: " -// The below code snippet is from file 'foo.cpp' - -// ```cpp -// /** This is a preceding block comment -// * This is the second line -// */ -// struct { // Structure declaration -// int myNum; // Member (int variable) -// string myString; // Member (string variable) -// } myStructure; -// ```" -// .unindent(), -// embedding: vec![], -// }, -// Document { -// name: "class Matrix2".into(), -// range: 613..1342, -// content: " -// The below code snippet is from file 'foo.cpp' - -// ```cpp -// /** -// * @brief Matrix class. -// */ -// template ::value || std::is_floating_point::value, -// bool>::type> -// class Matrix2 { -// std::vector> _mat; - -// public: -// /** -// * @brief Constructor -// * @tparam Integer ensuring integers are being evaluated and not other -// * data types. -// * @param size denoting the size of Matrix as size x size -// */ -// template ::value, -// Integer>::type> -// explicit Matrix(const Integer size) { -// for (size_t i = 0; i < size; ++i) { -// _mat.emplace_back(std::vector(size, 0)); -// } -// } -// } -// ```" -// .unindent(), -// embedding: vec![], -// }, -// ]; + let documents = retriever.parse_file(&text, language.clone()).unwrap(); -// for idx in 0..test_documents.len() { -// assert_eq!(test_documents[idx], parsed_files[idx]); -// } -// } + assert_documents_eq( + &documents, + &[ + ( + " + /** + * @brief Main function + * @returns 0 on exit + */ + int main() { return 0; }" + .unindent(), + 54, + ), + ( + " + /** + * This is a test comment + */ + class MyClass { // The class + public: // Access specifier + int myNum; // Attribute (int variable) + string myString; // Attribute (string variable) + }" + .unindent(), + 112, + ), + ( + " + // This is a test comment + enum Color { red, green, blue }" + .unindent(), + 322, + ), + ( + " + /** This is a preceding block comment + * This is the second line + */ + struct { // Structure declaration + int myNum; // Member (int variable) + string myString; // Member (string variable) + } myStructure;" + .unindent(), + 425, + ), + ( + " + /** + * @brief Matrix class. + */ + template ::value || std::is_floating_point::value, + bool>::type> + class Matrix2 { + std::vector> _mat; + + public: + /** + * @brief Constructor + * @tparam Integer ensuring integers are being evaluated and not other + * data types. + * @param size denoting the size of Matrix as size x size + */ + template ::value, + Integer>::type> + explicit Matrix(const Integer size) { + for (size_t i = 0; i < size; ++i) { + _mat.emplace_back(std::vector(size, 0)); + } + } + }" + .unindent(), + 612, + ), + ( + " + explicit Matrix(const Integer size) { + for (size_t i = 0; i < size; ++i) { + _mat.emplace_back(std::vector(size, 0)); + } + }" + .unindent(), + 1226, + ), + ], + ); +} #[gpui::test] fn test_dot_product(mut rng: StdRng) { From 64b252e81a020f2ccf0895c2afeaf12cff37d182 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Tue, 25 Jul 2023 12:55:01 -0600 Subject: [PATCH 043/160] A little refactor Co-Authored-By: Mikayla Maki --- crates/vim/src/vim.rs | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 363901d260ef3a0b54f390923a1439a9ed59f277..340da4f896eb0d0ed33209a82734b295d386f7fd 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -264,25 +264,19 @@ impl Vim { } } - fn sync_mode_indicator(cx: &mut AppContext) { - cx.spawn(|mut cx| async move { - let workspace = match cx.update(|cx| { - cx.update_active_window(|cx| { - cx.root_view() - .downcast_ref::() - .map(|workspace| workspace.downgrade()) - }) - }) { - Some(Some(workspace)) => workspace, - _ => { - return Ok(()); - } + fn sync_mode_indicator(cx: &mut WindowContext) { + let Some(workspace) = cx.root_view() + .downcast_ref::() + .map(|workspace| workspace.downgrade()) else { + return; }; + cx.spawn(|mut cx| async move { workspace.update(&mut cx, |workspace, cx| { Vim::update(cx, |vim, cx| { workspace.status_bar().update(cx, |status_bar, cx| { let current_position = status_bar.position_of_item::(); + if vim.enabled && current_position.is_none() { if vim.mode_indicator.is_none() { vim.mode_indicator = From cdceddd2cc3d21f3efd504e8b568a67535093626 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Tue, 25 Jul 2023 15:20:35 -0400 Subject: [PATCH 044/160] update semantic index tests for elixir --- .../src/semantic_index_tests.rs | 251 ++++++++---------- 1 file changed, 115 insertions(+), 136 deletions(-) diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index 2ae9a06c0fbbeeb3371ff958612b9d94bc88daef..acf5a9d72b43a1123102e105da2b4b039fba87c6 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -486,142 +486,121 @@ async fn test_code_context_retrieval_javascript() { ) } -// #[gpui::test] -// async fn test_code_context_retrieval_elixir() { -// let language = elixir_lang(); -// let mut retriever = CodeContextRetriever::new(); - -// let text = r#" -// defmodule File.Stream do -// @moduledoc """ -// Defines a `File.Stream` struct returned by `File.stream!/3`. - -// The following fields are public: - -// * `path` - the file path -// * `modes` - the file modes -// * `raw` - a boolean indicating if bin functions should be used -// * `line_or_bytes` - if reading should read lines or a given number of bytes -// * `node` - the node the file belongs to - -// """ - -// defstruct path: nil, modes: [], line_or_bytes: :line, raw: true, node: nil - -// @type t :: %__MODULE__{} - -// @doc false -// def __build__(path, modes, line_or_bytes) do -// raw = :lists.keyfind(:encoding, 1, modes) == false - -// modes = -// case raw do -// true -> -// case :lists.keyfind(:read_ahead, 1, modes) do -// {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] -// {:read_ahead, _} -> [:raw | modes] -// false -> [:raw, :read_ahead | modes] -// end - -// false -> -// modes -// end - -// %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} - -// end -// "# -// .unindent(); - -// let parsed_files = retriever -// .parse_file(Path::new("foo.ex"), &text, language) -// .unwrap(); - -// let test_documents = &[ -// Document{ -// name: "defmodule File.Stream".into(), -// range: 0..1132, -// content: r#" -// The below code snippet is from file 'foo.ex' - -// ```elixir -// defmodule File.Stream do -// @moduledoc """ -// Defines a `File.Stream` struct returned by `File.stream!/3`. - -// The following fields are public: - -// * `path` - the file path -// * `modes` - the file modes -// * `raw` - a boolean indicating if bin functions should be used -// * `line_or_bytes` - if reading should read lines or a given number of bytes -// * `node` - the node the file belongs to - -// """ - -// defstruct path: nil, modes: [], line_or_bytes: :line, raw: true, node: nil - -// @type t :: %__MODULE__{} - -// @doc false -// def __build__(path, modes, line_or_bytes) do -// raw = :lists.keyfind(:encoding, 1, modes) == false - -// modes = -// case raw do -// true -> -// case :lists.keyfind(:read_ahead, 1, modes) do -// {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] -// {:read_ahead, _} -> [:raw | modes] -// false -> [:raw, :read_ahead | modes] -// end - -// false -> -// modes -// end - -// %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} - -// end -// ```"#.unindent(), -// embedding: vec![], -// }, -// Document { -// name: "def __build__".into(), -// range: 574..1132, -// content: r#" -// The below code snippet is from file 'foo.ex' - -// ```elixir -// @doc false -// def __build__(path, modes, line_or_bytes) do -// raw = :lists.keyfind(:encoding, 1, modes) == false - -// modes = -// case raw do -// true -> -// case :lists.keyfind(:read_ahead, 1, modes) do -// {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] -// {:read_ahead, _} -> [:raw | modes] -// false -> [:raw, :read_ahead | modes] -// end - -// false -> -// modes -// end - -// %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} - -// end -// ```"# -// .unindent(), -// embedding: vec![], -// }]; - -// for idx in 0..test_documents.len() { -// assert_eq!(test_documents[idx], parsed_files[idx]); -// } -// } +#[gpui::test] +async fn test_code_context_retrieval_elixir() { + let language = elixir_lang(); + let mut retriever = CodeContextRetriever::new(); + + let text = r#" + defmodule File.Stream do + @moduledoc """ + Defines a `File.Stream` struct returned by `File.stream!/3`. + + The following fields are public: + + * `path` - the file path + * `modes` - the file modes + * `raw` - a boolean indicating if bin functions should be used + * `line_or_bytes` - if reading should read lines or a given number of bytes + * `node` - the node the file belongs to + + """ + + defstruct path: nil, modes: [], line_or_bytes: :line, raw: true, node: nil + + @type t :: %__MODULE__{} + + @doc false + def __build__(path, modes, line_or_bytes) do + raw = :lists.keyfind(:encoding, 1, modes) == false + + modes = + case raw do + true -> + case :lists.keyfind(:read_ahead, 1, modes) do + {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] + {:read_ahead, _} -> [:raw | modes] + false -> [:raw, :read_ahead | modes] + end + + false -> + modes + end + + %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} + + end"# + .unindent(); + + let documents = retriever.parse_file(&text, language.clone()).unwrap(); + + assert_documents_eq( + &documents, + &[( + r#" + defmodule File.Stream do + @moduledoc """ + Defines a `File.Stream` struct returned by `File.stream!/3`. + + The following fields are public: + + * `path` - the file path + * `modes` - the file modes + * `raw` - a boolean indicating if bin functions should be used + * `line_or_bytes` - if reading should read lines or a given number of bytes + * `node` - the node the file belongs to + + """ + + defstruct path: nil, modes: [], line_or_bytes: :line, raw: true, node: nil + + @type t :: %__MODULE__{} + + @doc false + def __build__(path, modes, line_or_bytes) do + raw = :lists.keyfind(:encoding, 1, modes) == false + + modes = + case raw do + true -> + case :lists.keyfind(:read_ahead, 1, modes) do + {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] + {:read_ahead, _} -> [:raw | modes] + false -> [:raw, :read_ahead | modes] + end + + false -> + modes + end + + %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} + + end"# + .unindent(), + 0, + ),(r#" + @doc false + def __build__(path, modes, line_or_bytes) do + raw = :lists.keyfind(:encoding, 1, modes) == false + + modes = + case raw do + true -> + case :lists.keyfind(:read_ahead, 1, modes) do + {:read_ahead, false} -> [:raw | :lists.keydelete(:read_ahead, 1, modes)] + {:read_ahead, _} -> [:raw | modes] + false -> [:raw, :read_ahead | modes] + end + + false -> + modes + end + + %File.Stream{path: path, modes: modes, raw: raw, line_or_bytes: line_or_bytes, node: node()} + + end"#.unindent(), 574)], + ); +} #[gpui::test] async fn test_code_context_retrieval_cpp() { From e8210b827d8bb0871dbebf046506e12d4d6a934d Mon Sep 17 00:00:00 2001 From: KCaverly Date: Tue, 25 Jul 2023 15:24:27 -0400 Subject: [PATCH 045/160] move visible text to just start anchor with context lines for semantic search --- crates/search/src/project_search.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 28085f59feb16bd9158ee766ba752f4d2cd72340..6903337e07160bdb1bec048ad9d3fe4672c91f09 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -217,7 +217,7 @@ impl ProjectSearch { let matches = results .into_iter() - .map(|result| (result.buffer, vec![result.range])) + .map(|result| (result.buffer, vec![result.range.start..result.range.start])) .collect(); excerpts.stream_excerpts_with_context_lines(matches, 3, cx) From 75999204adcee661da958dd27fc3acc536d05b67 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Tue, 25 Jul 2023 16:26:37 -0400 Subject: [PATCH 046/160] update project search to only show semantic button visible with semantic_index enabled --- crates/search/src/project_search.rs | 24 ++++++++++++++++----- crates/semantic_index/src/semantic_index.rs | 6 +++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 6903337e07160bdb1bec048ad9d3fe4672c91f09..ec9108f92cffa392233f22625f40c15da59bf3cc 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -996,6 +996,10 @@ impl ProjectSearchBar { SearchOption::Regex => &mut search_view.regex, }; *value = !*value; + + if value.clone() { + search_view.semantic = None; + } search_view.search(cx); }); cx.notify(); @@ -1012,6 +1016,9 @@ impl ProjectSearchBar { search_view.semantic = None; } else if let Some(semantic_index) = SemanticIndex::global(cx) { // TODO: confirm that it's ok to send this project + search_view.regex = false; + search_view.case_sensitive = false; + search_view.whole_word = false; let project = search_view.model.read(cx).project.clone(); let index_task = semantic_index.update(cx, |semantic_index, cx| { @@ -1266,9 +1273,14 @@ impl View for ProjectSearchBar { .with_child(self.render_nav_button(">", Direction::Next, cx)) .aligned(), ) - .with_child( - Flex::row() - .with_child(self.render_semantic_search_button(cx)) + .with_child({ + let row = if SemanticIndex::enabled(cx) { + Flex::row().with_child(self.render_semantic_search_button(cx)) + } else { + Flex::row() + }; + + let row = row .with_child(self.render_option_button( "Case", SearchOption::CaseSensitive, @@ -1286,8 +1298,10 @@ impl View for ProjectSearchBar { )) .contained() .with_style(theme.search.option_button_group) - .aligned(), - ) + .aligned(); + + row + }) .contained() .with_margin_bottom(row_spacing), ) diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 215ca38a28845fdf8b24d8c5d0a5d1249a03bcec..7e8d183ba00a9626af53a881a9fa3d272c257a83 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -1,7 +1,7 @@ mod db; mod embedding; mod parsing; -mod semantic_index_settings; +pub mod semantic_index_settings; #[cfg(test)] mod semantic_index_tests; @@ -183,6 +183,10 @@ impl SemanticIndex { } } + pub fn enabled(cx: &AppContext) -> bool { + settings::get::(cx).enabled + } + async fn new( fs: Arc, database_url: PathBuf, From ca6f7d8a804ec486a4608cd627a7e9182f51a3c8 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Wed, 26 Jul 2023 09:17:04 -0400 Subject: [PATCH 047/160] add worktree previously indexed functionality to vector db --- crates/semantic_index/src/db.rs | 17 +++++++ crates/semantic_index/src/semantic_index.rs | 53 ++++++++++++++++++++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/crates/semantic_index/src/db.rs b/crates/semantic_index/src/db.rs index b1e78b7aff994ca977fbbea41d595f08fb65766a..4bc97da0f08e3d56dd249da72cd8deaff56f7e0f 100644 --- a/crates/semantic_index/src/db.rs +++ b/crates/semantic_index/src/db.rs @@ -197,6 +197,23 @@ impl VectorDatabase { Ok(()) } + pub fn worktree_previously_indexed(&self, worktree_root_path: &Path) -> Result { + let mut worktree_query = self + .db + .prepare("SELECT id FROM worktrees WHERE absolute_path = ?1")?; + let worktree_id = worktree_query + .query_row(params![worktree_root_path.to_string_lossy()], |row| { + Ok(row.get::<_, i64>(0)?) + }) + .map_err(|err| anyhow!(err)); + + if worktree_id.is_ok() { + return Ok(true); + } else { + return Ok(false); + } + } + pub fn find_or_create_worktree(&self, worktree_root_path: &Path) -> Result { // Check that the absolute path doesnt exist let mut worktree_query = self diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 7e8d183ba00a9626af53a881a9fa3d272c257a83..7fee09dcff1d3cdae5b85ec01a11de632da71528 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -34,7 +34,7 @@ use util::{ ResultExt, }; -const SEMANTIC_INDEX_VERSION: usize = 5; +const SEMANTIC_INDEX_VERSION: usize = 6; const EMBEDDINGS_BATCH_SIZE: usize = 80; pub fn init( @@ -161,6 +161,10 @@ enum DbOperation { worktree_id: i64, sender: oneshot::Sender>>, }, + WorktreePreviouslyIndexed { + path: Arc, + sender: oneshot::Sender>, + }, } enum EmbeddingJob { @@ -327,6 +331,10 @@ impl SemanticIndex { let file_mtimes = db.get_file_mtimes(worktree_db_id); sender.send(file_mtimes).ok(); } + DbOperation::WorktreePreviouslyIndexed { path, sender } => { + let worktree_indexed = db.worktree_previously_indexed(path.as_ref()); + sender.send(worktree_indexed).ok(); + } } } @@ -479,6 +487,49 @@ impl SemanticIndex { async move { rx.await? } } + fn worktree_previously_indexed(&self, path: Arc) -> impl Future> { + let (tx, rx) = oneshot::channel(); + self.db_update_tx + .try_send(DbOperation::WorktreePreviouslyIndexed { path, sender: tx }) + .unwrap(); + async move { rx.await? } + } + + pub fn project_previously_indexed( + &mut self, + project: ModelHandle, + cx: &mut ModelContext, + ) -> Task> { + let worktree_scans_complete = project + .read(cx) + .worktrees(cx) + .map(|worktree| { + let scan_complete = worktree.read(cx).as_local().unwrap().scan_complete(); + async move { + scan_complete.await; + } + }) + .collect::>(); + + let worktrees_indexed_previously = project + .read(cx) + .worktrees(cx) + .map(|worktree| self.worktree_previously_indexed(worktree.read(cx).abs_path())) + .collect::>(); + + cx.spawn(|this, mut cx| async move { + futures::future::join_all(worktree_scans_complete).await; + + let worktree_indexed_previously = + futures::future::join_all(worktrees_indexed_previously).await; + + Ok(worktree_indexed_previously + .iter() + .filter(|worktree| worktree.is_ok()) + .all(|v| v.as_ref().log_err().is_some_and(|v| v.to_owned()))) + }) + } + pub fn index_project( &mut self, project: ModelHandle, From 394a105639413d83c8486ff3ccac2530f6d7dcf2 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Wed, 26 Jul 2023 10:03:30 -0400 Subject: [PATCH 048/160] fix warnings --- crates/semantic_index/src/semantic_index.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 7fee09dcff1d3cdae5b85ec01a11de632da71528..396a0a8607dc6d31d3ff13a6eb1c00a54ccf061f 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -517,7 +517,7 @@ impl SemanticIndex { .map(|worktree| self.worktree_previously_indexed(worktree.read(cx).abs_path())) .collect::>(); - cx.spawn(|this, mut cx| async move { + cx.spawn(|_, _cx| async move { futures::future::join_all(worktree_scans_complete).await; let worktree_indexed_previously = From 0b61c93a25c23487c1bb52107d9fa5cec80618cf Mon Sep 17 00:00:00 2001 From: KCaverly Date: Wed, 26 Jul 2023 10:22:33 -0400 Subject: [PATCH 049/160] ensure semantic search is not enabled on stable --- crates/semantic_index/src/semantic_index.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 396a0a8607dc6d31d3ff13a6eb1c00a54ccf061f..e4a307573aabc00336863b23a799138c52adc895 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -189,6 +189,7 @@ impl SemanticIndex { pub fn enabled(cx: &AppContext) -> bool { settings::get::(cx).enabled + && *RELEASE_CHANNEL != ReleaseChannel::Stable } async fn new( From 56704c7c5f930a7840ebc00253fbda9da5476122 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Wed, 26 Jul 2023 09:37:52 -0700 Subject: [PATCH 050/160] Remove placeholders --- crates/workspace/src/pane_group.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index 22435b56f0576fccd2629c135b9cca9011935010..3d7032c14873d4c781307e02a4801e56ef451e71 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -697,7 +697,7 @@ mod element { move |drag, workspace: &mut Workspace, cx| { if drag.end { - // Clear cascading resize state + // TODO: Clear cascading resize state return; } let min_size = match axis { @@ -929,9 +929,6 @@ mod element { visible_bounds.clone(), ), ) - .on_down(MouseButton::Left, |_, _: &mut Workspace, _| { - // Save cascading resize state - }) .on_click(MouseButton::Left, { let flexes = self.flexes.clone(); move |e, v: &mut Workspace, cx| { From a58c9ed7d3b6ad8203b60e4520ddced8b3042f09 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Wed, 26 Jul 2023 09:39:35 -0700 Subject: [PATCH 051/160] fmt --- crates/gpui/src/scene/mouse_event.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/gpui/src/scene/mouse_event.rs b/crates/gpui/src/scene/mouse_event.rs index 21d3716aa6ea083baad8196c7d88d870b38615bd..89bf8745839850839b77c29ff57df627959526cc 100644 --- a/crates/gpui/src/scene/mouse_event.rs +++ b/crates/gpui/src/scene/mouse_event.rs @@ -32,7 +32,7 @@ pub struct MouseDrag { pub region: RectF, pub prev_mouse_position: Vector2F, pub platform_event: MouseMovedEvent, - pub end: bool + pub end: bool, } impl Deref for MouseDrag { From 9fc1ebcb5b33652eed02ffc355beabc340e41950 Mon Sep 17 00:00:00 2001 From: Derek Briggs Date: Wed, 26 Jul 2023 11:19:34 -0600 Subject: [PATCH 052/160] icon updates --- assets/icons/file_icons/ai.svg | 27 +++++++++++++++++++ assets/icons/file_icons/archive.svg | 4 +-- assets/icons/file_icons/audio.svg | 4 +-- assets/icons/file_icons/camera.svg | 2 +- assets/icons/file_icons/conversations.svg | 4 +++ assets/icons/file_icons/database.svg | 2 +- assets/icons/file_icons/file.svg | 4 +-- assets/icons/file_icons/folder.svg | 5 ++-- assets/icons/file_icons/folder_open.svg | 5 ++-- assets/icons/file_icons/git.svg | 2 +- assets/icons/file_icons/image.svg | 2 +- assets/icons/file_icons/lock.svg | 2 +- assets/icons/file_icons/magnifying_glass.svg | 3 +++ assets/icons/file_icons/notebook.svg | 6 ++--- assets/icons/file_icons/package.svg | 2 +- assets/icons/file_icons/plus.svg | 3 +++ assets/icons/file_icons/prettier.svg | 10 +++---- assets/icons/file_icons/project.svg | 5 ++++ assets/icons/file_icons/replace.svg | 11 ++++++++ assets/icons/file_icons/replace_all.svg | 5 ++++ assets/icons/file_icons/replace_next.svg | 5 ++++ assets/icons/file_icons/rust.svg | 4 +-- assets/icons/file_icons/settings.svg | 2 +- assets/icons/file_icons/toml.svg | 2 +- assets/icons/file_icons/typescript.svg | 2 +- assets/icons/file_icons/video.svg | 2 +- crates/zed/resources/app-icon-preview.png | Bin 231466 -> 191163 bytes crates/zed/resources/app-icon-preview@2x.png | Bin 757122 -> 679362 bytes 28 files changed, 93 insertions(+), 32 deletions(-) create mode 100644 assets/icons/file_icons/ai.svg create mode 100644 assets/icons/file_icons/conversations.svg create mode 100644 assets/icons/file_icons/magnifying_glass.svg create mode 100644 assets/icons/file_icons/plus.svg create mode 100644 assets/icons/file_icons/project.svg create mode 100644 assets/icons/file_icons/replace.svg create mode 100644 assets/icons/file_icons/replace_all.svg create mode 100644 assets/icons/file_icons/replace_next.svg diff --git a/assets/icons/file_icons/ai.svg b/assets/icons/file_icons/ai.svg new file mode 100644 index 0000000000000000000000000000000000000000..2dc30cdf95e27f7e02716ee46d58b84cf1d6c7a5 --- /dev/null +++ b/assets/icons/file_icons/ai.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/file_icons/archive.svg b/assets/icons/file_icons/archive.svg index 35e3dc59bdb828e2bd96b119f81081e23d488c72..80c76322b99e87a78bfd181e9eb47edeabd546bf 100644 --- a/assets/icons/file_icons/archive.svg +++ b/assets/icons/file_icons/archive.svg @@ -1,5 +1,5 @@ - - + + diff --git a/assets/icons/file_icons/audio.svg b/assets/icons/file_icons/audio.svg index c2275efb63ffa23646ff5933f159802ef9b4a197..f272fd8643c0af5d0dd50a348c518e80cfe61056 100644 --- a/assets/icons/file_icons/audio.svg +++ b/assets/icons/file_icons/audio.svg @@ -1,6 +1,6 @@ - - + + diff --git a/assets/icons/file_icons/camera.svg b/assets/icons/file_icons/camera.svg index bc1993ad6320486705c54250cfa2559989100745..d9582a2e7bc027385416c2f06417050919c5da3d 100644 --- a/assets/icons/file_icons/camera.svg +++ b/assets/icons/file_icons/camera.svg @@ -1,4 +1,4 @@ - + diff --git a/assets/icons/file_icons/conversations.svg b/assets/icons/file_icons/conversations.svg new file mode 100644 index 0000000000000000000000000000000000000000..a956f8b5a151e62a12a05ec96a7c0dcfae5fe8ac --- /dev/null +++ b/assets/icons/file_icons/conversations.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/file_icons/database.svg b/assets/icons/file_icons/database.svg index 812d147717ee23ae57eb3444023c32ee7954dbd6..d8aae1373cc58eeacaf16289ecf56ef3af395e55 100644 --- a/assets/icons/file_icons/database.svg +++ b/assets/icons/file_icons/database.svg @@ -1,5 +1,5 @@ - + diff --git a/assets/icons/file_icons/file.svg b/assets/icons/file_icons/file.svg index bfffe036844c4469544e0112fa2677c177bbc9d8..ccacfa2ce3ca355c736f30e99974f4ffb076cde3 100644 --- a/assets/icons/file_icons/file.svg +++ b/assets/icons/file_icons/file.svg @@ -1,5 +1,5 @@ - + - + diff --git a/assets/icons/file_icons/folder.svg b/assets/icons/file_icons/folder.svg index fd45ab1c4494b6151f7aa799b8b78b3e427f3d5a..208348994c8ce0a4f69e78c5edb74f583e70f585 100644 --- a/assets/icons/file_icons/folder.svg +++ b/assets/icons/file_icons/folder.svg @@ -1,5 +1,4 @@ - - - + + diff --git a/assets/icons/file_icons/folder_open.svg b/assets/icons/file_icons/folder_open.svg index 55c7d51649a697553629f0c7190d80603abe3323..95f53fc9f72e8edc1338c36156ace4380d6b52fa 100644 --- a/assets/icons/file_icons/folder_open.svg +++ b/assets/icons/file_icons/folder_open.svg @@ -1,5 +1,4 @@ - - - + + diff --git a/assets/icons/file_icons/git.svg b/assets/icons/file_icons/git.svg index a30b47fb86edc6532b709f6e97fec6cbac4501a3..45904645ca0048232a8f4f9c9e5c2ff8b910d299 100644 --- a/assets/icons/file_icons/git.svg +++ b/assets/icons/file_icons/git.svg @@ -1,6 +1,6 @@ - + diff --git a/assets/icons/file_icons/image.svg b/assets/icons/file_icons/image.svg index d9d5b82af1782ef29adca84309a4fbf7e8a37672..a11941e22fc7b1958ee3caee4717a20ab5fa99e8 100644 --- a/assets/icons/file_icons/image.svg +++ b/assets/icons/file_icons/image.svg @@ -1,6 +1,6 @@ - + diff --git a/assets/icons/file_icons/lock.svg b/assets/icons/file_icons/lock.svg index 14fed3941acdf7bbd2b71b504694626a860cec57..64a6470b2f9f89c19184d10058987a5d22e851f7 100644 --- a/assets/icons/file_icons/lock.svg +++ b/assets/icons/file_icons/lock.svg @@ -1,6 +1,6 @@ - + diff --git a/assets/icons/file_icons/magnifying_glass.svg b/assets/icons/file_icons/magnifying_glass.svg new file mode 100644 index 0000000000000000000000000000000000000000..0b539adb6c764451234b898a5e6306baabc64d57 --- /dev/null +++ b/assets/icons/file_icons/magnifying_glass.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/file_icons/notebook.svg b/assets/icons/file_icons/notebook.svg index 4f55ceac58aa69544b396a3756835fa663a85080..62b435c7a207841c60252220e9cc5c85574212b1 100644 --- a/assets/icons/file_icons/notebook.svg +++ b/assets/icons/file_icons/notebook.svg @@ -1,8 +1,8 @@ - + - - + + diff --git a/assets/icons/file_icons/package.svg b/assets/icons/file_icons/package.svg index a46126e3e902e94df8289d459e8916c9995d3a77..2072f30b1e819460475c54f2fe572868c0dfa22b 100644 --- a/assets/icons/file_icons/package.svg +++ b/assets/icons/file_icons/package.svg @@ -1,4 +1,4 @@ - + diff --git a/assets/icons/file_icons/plus.svg b/assets/icons/file_icons/plus.svg new file mode 100644 index 0000000000000000000000000000000000000000..a54dd0ad66226f3c485c33c221f823da87727789 --- /dev/null +++ b/assets/icons/file_icons/plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/file_icons/prettier.svg b/assets/icons/file_icons/prettier.svg index 23cefe0efc834d0f953b081fbf5220acdea9117d..625e99b3a85fc87b1e964ba37e894c5412bdca0a 100644 --- a/assets/icons/file_icons/prettier.svg +++ b/assets/icons/file_icons/prettier.svg @@ -1,12 +1,12 @@ - - + + - + - + - + diff --git a/assets/icons/file_icons/project.svg b/assets/icons/file_icons/project.svg new file mode 100644 index 0000000000000000000000000000000000000000..525109db4ce74d99074c90e714003720d4e97156 --- /dev/null +++ b/assets/icons/file_icons/project.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/file_icons/replace.svg b/assets/icons/file_icons/replace.svg new file mode 100644 index 0000000000000000000000000000000000000000..4e137dbfc551e664c1e89ccaa04ee1865f4c1822 --- /dev/null +++ b/assets/icons/file_icons/replace.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/icons/file_icons/replace_all.svg b/assets/icons/file_icons/replace_all.svg new file mode 100644 index 0000000000000000000000000000000000000000..0b4a0c021d823b44e94921648d71c0c3a9915de5 --- /dev/null +++ b/assets/icons/file_icons/replace_all.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/file_icons/replace_next.svg b/assets/icons/file_icons/replace_next.svg new file mode 100644 index 0000000000000000000000000000000000000000..d0d343e6f42a3abf49cc9ed7bc367df4ef389d82 --- /dev/null +++ b/assets/icons/file_icons/replace_next.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/file_icons/rust.svg b/assets/icons/file_icons/rust.svg index 91982b3eeb9f23a108dd4fb484b8925d18b77437..ed015af87401aa2e6cb7a5c329ffa6f1cb612a70 100644 --- a/assets/icons/file_icons/rust.svg +++ b/assets/icons/file_icons/rust.svg @@ -1,4 +1,4 @@ - - + + diff --git a/assets/icons/file_icons/settings.svg b/assets/icons/file_icons/settings.svg index 35af7e1899ef8619249744502794452b074679ec..e6d35e415b3828a16585c6100d360117a88ac1b4 100644 --- a/assets/icons/file_icons/settings.svg +++ b/assets/icons/file_icons/settings.svg @@ -1,4 +1,4 @@ - + diff --git a/assets/icons/file_icons/toml.svg b/assets/icons/file_icons/toml.svg index 496c41e75562faf52ee4a7df5428d4d293f7e6d5..f2c2045cb1ab578b49eb5f48444575df1ce95450 100644 --- a/assets/icons/file_icons/toml.svg +++ b/assets/icons/file_icons/toml.svg @@ -1,5 +1,5 @@ - + diff --git a/assets/icons/file_icons/typescript.svg b/assets/icons/file_icons/typescript.svg index f7748a86c46bfa915bf3f86af4208f2f8712a8aa..a69f0e2dee11cbcfe733e83f68dd0ce1456f9aff 100644 --- a/assets/icons/file_icons/typescript.svg +++ b/assets/icons/file_icons/typescript.svg @@ -1,5 +1,5 @@ - + diff --git a/assets/icons/file_icons/video.svg b/assets/icons/file_icons/video.svg index c7ebf98af62ddfbe68073717379694449ee6e716..0f196ee995677720fa5549c0da7bac47666d24e7 100644 --- a/assets/icons/file_icons/video.svg +++ b/assets/icons/file_icons/video.svg @@ -1,4 +1,4 @@ - + diff --git a/crates/zed/resources/app-icon-preview.png b/crates/zed/resources/app-icon-preview.png index ce2a639e2cd9c77ee5bd56bb13fe397414110c0c..b76e57885835fdb4fdba114fb812fd16f9637001 100644 GIT binary patch literal 191163 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

8!`W( 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

st+#lG+CB&9^@`p`No{l9XDf|FUTR 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�-#0{aBGt0>_@sV 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

NhY|h}2O;y?42_JdIFA~Nh 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℞4F~@Bt2k>)tLf)0)*Cq6*lcKL_W{YuvWk& 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 diff --git a/crates/zed/resources/app-icon-preview@2x.png b/crates/zed/resources/app-icon-preview@2x.png index f22b8523f9fab4a66c5de3cd75ecbbacfb387766..6e08503927d89ecd76653bcc9ddc9ba03123daa0 100644 GIT binary patch literal 679362 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≤Agi}34XOn;K`hc)|XV3Z_1Mym*Ex=OFBi!YU?zMlSi^(UiVPZyF z`PeR<#V(&EJr4FCVeSLACLa9kW&FIU!YF|NvAR`S5dC~nkHKE4$6)<-tXg~u*(xl? z(ny=`0yv(g;HPYgEyhv8s{D+TP&D`diME`STB1!?cy)CD_%nau_Vw%6R~pMq2lx0| zk2!1bbKM2~>Z`AoXSxeO7ea0IUvOgfkoJ=fI{@~WT(G20W37JXXMQGx;H8&dB4vEt z0r2t1AG2QrcUC}fj=6FpL zfv1(m+~NUz=99N6SCY6!NTn=Nw@)3@`4d=Zf`Qy4OG}l@hIhQNWD7<>lM9`$v8Tw3 zqvKsAAyD`n4j5yd1YTR?{5ntC0}u2R`8Yn84N9}-+u-H?t0x5QRl4IEwb{e!z*0LS zZ|{A(ZOEDfC4!w0lI`o>=dV#~tgfz$#E`*V6zQx>1F@gv5SSV8c1K5vw;l+CI7m9i z344lKH#vT@ffeYaW_8c~8-T^#utcaI+)6VTAm}R`Bzr$J1Lqi^#TX%R<`(}tsme*y z250BZ#ME~U_+%_fbKfH5tqklcfuGko(+mRChq}X0#CinjJ4HRM1KNHDR*6bO-@wND z6nSdY*2qiqpV?-Ue}do0K}{#MuW>43hF;g7{xbVE;m0JU%RlI|3zL82({sr`wUaP= zlYi^~DBE$+iSkcLccfIQTX;6uZ+OdG85z`vz0*AF^#xH&IWa7PT(;99%G<<>jB4o9 z((^%j#P+|m{FMM7c@XN?gG$QSpV#I-mVK~tE#NM z3n$Xsv#PL_FabxE%amVNjCQkaKov76=kf&%%AQk9KXJ#`r%Lle{Fy)ZY5Mkm{0KFAWn+sO~YW%b@;6vJ3I_v=0Ut%|wxC1}~0P0Zy zo%yTL#t1`uC52s&4;xd)`a=w{|l49{}#1xbO-#=$X^L+g5{0=kRQR zwUte6N15A}8pAp18Pvnw<7O3>8b2`eusNLEq1;uIydljeI&fjgNWjT6-lH^iwcH#p zAE1M8TY1_(+beu!z^}eq1qh4P)wjp%k@TAbi-r{ioNL6ks~qa<+Yk;qweQP2r;Yyu zc-5`Ml#Ynw3v}oQ-#vQvAD=XPpPZtFii|6l8^6>+!C;ah*OqwW7ZQ2vsGyWx~4{$9#6 zg1_n6W+cbuL^}M5Xp?c}&hTw&*QVz^9Dg=6p6&Ns(cs3Ja>po~UTFu+Ip`6>0Drh` z6+Z>*H$#~K)0JcFbEu2wUTHY|;Sdw>37Sh082I_N+#E>YDq6{BM`8RkoNsT9Q1B!= zy(MpvsoaK3*tOPFruGk;h4jYiDs7skCo1gUxv5l$8b=v@j{;*7!^e=Fl3rOJ@Go_8 zi!Z>V&_Uq;WLG5K&{iK?q!Z2A#o9ldm9z0G4tT}zjy8#{ju`()heOavpc?bclZ$B( zBI`*pwaFODm=r)lbz@=wryqW#H#_C(fsqWq(NhEv?}j+0MOW#V_Sg3vTaa0xg%1Vfva{E_w*NCfNuXUbUuKYh z+l2f#D!b(GG}}I8u^bP2W+Q&1dUA9>Yv(uLsJ`q3Is?;-x)?T1$-i(dARkwL)4raZ zdD*w`Q#p3qw7}n4MaYBI4*0}E%a2>Tta6HXmv7$JW6V!K{dB3~-FM%OT0G{NP6X&! zNaFzLF#+5q?I<$yDVXJuPLmE30DDTxv=*(m+-td>+2Zx;e>vx(%&xOudIm<%|LfhD zZ@&3vdVy2~wfbh4uiU4zrlHs{b!vh9j9t4`*1!2(B4+yR{H4HgG2c>HuY;8uD$100 zHNF%1AWaq9^=n6T@44$#eIqoHsXM><#xXSy7L5&!m39AKFfXUoELC$`rde9x`Lk_P z=S8&S8_mS8%GE-+)^<)8#Ln-NvCrXB+9D zY2_z#4KCJ06?f#bsx*A?kT?k2w(yCX0SX!Y!nd$bYMd1t0DInnZ%1B-v~6MO=m~x8 zgCnF_BMXg8NIL*-5P$)dv;!zX!buLON*Q*2*YcdxDtL>sP29JeXvVJDUsCF0ky&1J z?zz)(N&dl^X28jdM0-KcahI<;i`?pVmxr+nOtW1+MijrVI%zFAi0NrzvbI3|3MXUdlPN2y5a~8G?(3Rfm?L@n}UTX7DOr_ zj($WfP`Tb{K9orzoH(pyT;{RL=va`+`erEqM4*=_>}x);*L$-6t1Hh980DSJb=OX_*@4QpW z=(QQT{lBEul^RX6(}%+}(tXnY>>XHi{oIEsN@8X2B##4xJuI1RmERz-#X6bH7>6Zr zU8viZ$_jzdy-z$H_0=!j=yp9b_4@aw#44OM#1wymQlA+o$ZrN16BE@JlnPNhqWL`1cq?yhJ1J%NZ$qIr31>}^K z&yF7p!73}#hMPf~#B={H;Wvdd$v_Jy1Q85o-5F(b$bnamCAR-L_@#*bNY)dy zAFxNWI_$uS(|MkpHgJ-eTX)(A5ndnrC-5}3IT7a=7|aISrCyuz47y}d>0tD79nM$O z-LeTa?RA=3*DlV9#-G1v_z%$%<{pL>5xH*j~=f-C(+4^Gnbmy0B} zrI+8RXUhHy`V+MS51$y2Uhe>MQz!p!M8HXoK@+!Nas?YE2q*{4DgVId{sDvDD*sF< zTs+BK{;8!;4!Sz|r>>ynj)8s4KN6~ke`fg)+vNEGUr)P~|Ek2clz;4Fn#+GLzb^kC z&m%ez>3-xJ#*mG5K#OD-Dg}*kor<#NPUWg0^#7 zSkd4!+W&UIO+$U0aDXeM2ShC#kmvSUSB9wRqv#~h>u@H?q9S7)?K`9VkMalp@MTCd zndR5(tUq|z(UjXfpZbxfs(ef}_+Pp4QZhwaMBggCC|XcsPEgf}Imw1sGs-kra;s)HVqn(tgrm0$>lx z?z=3E>rAX$Ui6HM-vFTL{{8!+Ghlb`-qjlbN>TmCw#?MDx?FbvED0bg&e3m916W@R zz9PTs$EU&Tb$(Q%RL4Lkm9Z~4l$C@v`}mCG#C4FR%4l^gxsY27+LTS0>Y1lhK$OPU zQ2*U`k3peVZI@f~h#CdlJja$oBONm4?~P@axeGpON3;^)&nv z-Ixz!)eD^grlbQn3^9m@ZjLRc%)sP^JviP$o=Lz-k#^&P4?G(7Vafp!h1(V~0xNk= zlM31fdp1cSK43CJR5@+jEa-L#2fDzFK$|9yob@}Q3mkXaQ6wBE0h}dT7Ib54e}y5z zK+X1C?}u?~k%u*N6b%D>Fz-|Owx^+Wtp_<7Y>JzHZ7%itK#o7|$Q?rD;256BAY{ zg|0j$e8hKV|Dk;&7{QYXtHH=&GdybSKY~GB?D*GUfC8`U06m-a$-7TO;OvR&EghA= z%ij@&Oq3vkUYkx56ki-BG&_>A!Hj0W#9KeO4%O1}?T}_o9}qSCUf`@Wei>iCex3W9 z0QA=yWp&%z(fF>@^D8M z3}kUSxo-7$N2QjXU@%(^a@hd@_P`wzZ`wCY(3Hg3&n&ft2*`!TB^~m5ouM>&UGYZK z!TCug(-|(LCFYSH7ciDaGeO6n&?G=PPD7Bm)w-K=iI%@L!oUpBFhsoxEJK++;n@RF z{&5Z;dCi>$cjjXN=f(t#P*WQkOM$*kN6dlnfRV#r5o(-iGG29uusmP66KmyG$otTq z7yxp@6>3+I#0O!N6Jmg0Ugd`LX>kb03mrUd=gRvxp9L=%KiUzZaLn?QF@eBv@~%+J zW8fQ#v@5FK6%?Nm^5TKm><&}%WsON%>-RP|FECR~5Jhx;uhZJYD4VD+j6VV$=Le^U<2|S zc+NcN;eB^3Hc1e|ZG9(w2S$12t(YSs1}8Y{Ospvf)6Q6oS`VFEd+L2^v@7~qP|g^j zJN>CSHbx!lp>jizfCkL-bK2xI=D@!^Uaf#XrEa&i?^$<#_n>Jt4;)LfzDwNui4DM| zp^sGgXKv&_;IK_8W20i!{kMx~Y{>85g^nN&%{B!aM z7?P0xXbqb@OXwKC0&yt+U}}r+0J@~MVG25i{Il;Ua8anfNKP!U@o^6FC94WL(loWa zJK%@%TyZwrz!hJTQ{AQCTm_wSNy95~WWC zHqzujS+(}&H~W}YM{UbrvPH21&uvoi!>2mP58;&(W6S$f7v8j86D)KHc1aWkeJa3% z%qibR*21M|U?jn4oMiCHM`iIcb~97GJMj>Yvy7=>da+Pe>T`JfdFx(VKRezJkh=9 zo^EUd6XTDVEo}{ntszLZ(v1kCQuo2HE96z}kN%Wvw!z_chJdUe85Dct4$vG2q_jDG zY!0|joXm{1e~E7JwGy0=fZAnVKX>$S3($s6VfeR8;aK=e7nc=;o?^{6A)pFVKR9;4 zV)igrj-oN#Baprfe4^2c$s2Fq`uF5pPwo9Q<-33-6z%eXV?BqbXX-d6g3t#@c53?p z`8F{3z6*zqf-9QID+eAhZGi8%i$Hz8ozrL~>A~qa%DkmHZD0S(=eI>(|M@t|$eSR6SjiE!B2yZB00-S&~wUbvItHde)+zi~y z_j2u<>n|xfBzIX%dHf;xZX%l&vYNpDyG(}er{;OnI6Mc1_TT#gb!$r*0xi%!mrh;+ zPFRtsuJy-y>?CZd`*!H(cP4Eh})h8 zeL(`4p;9E^F-qNqDRqdw`jh{Q`%nGT|IPnTA8T-P9p~t6XS(ZIB$-ghM6bU3s^Af6 z-vMw)`%8x%0Q*UTI{-AT8Jm&0^#%Y<>zOdU8?(xiNV#cGj{xWm0Mk=(LR9TRt^-9S_YYsd2`?HzZsfRY1Z{ad-JlsF?e+2lYN(@?VY$+Vuyyn5w`?%cde zjlp$CrJ_RLdFPmXP#KC@U_b#K*DY!IT>De2XFv%Ufls0PWL+e=!dD7Q7=NdnWu1O;SOz+ z-SF;8A5Niba(kx42#380z$d{!iA?RpoAV6?KTgxsIM+x!)OUg$kGOgBy>13w8?-{z z1-xK`fywB}`bus zgGkqWt(p!%lTDB#jeQ$;^sxx_9UX1u+K*GnUWmr|_VZR%$2mU3P6cngq!pWiu=xnrb{|VzV1RF`V zr}_Y9MUrVFf6V@g5A?JZbxT{_Bwp<>N^X*bLzlK{+<6)7EzJk{sQ?nF+kOA$IwkEk zOwtlHdfd5fSeMg{DDvS1_B7MSL=1h^w2#p~Cf-T!02I8Ol8|k5esdgJI7S-=s!D5D znuVP8qu1Y^+6J#$#MLL(;Mk=%%UN3Gqhpf`qT`2D^&}h>Dqy&S2RoG-`>%PXR3WAg z4PSe2iq-kIA#AiXKL=vi@fy+5bDxVK=Iez`-3484JM+Om-h%ehOD~o0x?8%UQxYB0 z{?cIrU{6W6tvK^)P>Y*4Z;D2_{KhxFQLX^IfB(J)!Qk~wSYi5i-g!s2zmx(NG=u4> z=kL$#WLHoBd}gy<9}2v0yhJJ65?zt_N{Jga)TOaf3cg6muD_=#&R@rwNpS~D!U??p z+|v#Iyh=Q^`0u_m(T5LmpcdMS-Qndh@@{a@0S5Q2B%dKoXT{9uDhG<;z>36o9E=9! zXcIWV&Fr>B#x!R_xSc=x!WA(n-G-v+{<}scPR98YABbq zYIr7Ega4&DXpKNS3yw}gOS6Pq@|t~~h{9DUIaeHpjDQY4Nh08Ii}$0qb1<0g2VpC2 z9S#p}nQi2Cg4&@s!k@0 z2V8}xpci~aVKW8#$cJP?$$w#4C3TG3GJf4%yM~?hqNA&^ydc8>yo=>O<631bqZeAm2F=t(C;nC$FLp48O^k!F7B1U{P;! z+lpKN#QjO{nZm=Ai!#v?LFqET2k`LsTH^hWCwlAsDV)b(Szu^d zkaUdXR|M)Js{X}M$V1wBI!plUAt}c?^XhLs0`Rr3eXWST&T_r*!VC1^!Go3F0HEjp z-+JpUJsYE2WHi`C37Vlov$}e_%$~VX?S*h8aQ$ca0dAH15iPfX#0vT2>WsP4H{(H) z0nY4-rq zC)1|1v(YE9D*2IvM?7uAH%xdyyBsq=Gws*#q5K=cj6TWV zb>*9J+!{9ygnSt7E&NOH++;AF2EL*n-7P5pWO&y;=;c3+8MRJsKsP;=o3O?B#yx-1z#s6G6qBrW1K!oKf=z1{;#P{AEw+*P<}-q{~`d~Wf|y4NpFXaI@`PZ z-10AHk$;Kp^>qgZ%D?0p{n*V>J4s;Rqu(0&m+Yj;%A+1`bflpCrz}VFrit21VTy8( zKILZQPn+f6bx35byte{*@W}wTzi$88`boqllg(&=WH&l~g0@vF#(`d}Ucr32Rss}Gw3a;L#%8}7I5~rP)Bpa)+ZU!hEU)*m;X5DZ!l60 zDncumfO0($v~v0~1G|9^&dw)P;x0zPPt2f0i~{T5-}&AYeCT=z$^401SIq~ICgw=x zNus%;ar~ej_$)nx=Rj9&xd!Qc5lszU67ajMgYQC(s1aSgsaFA(n*eldqdNdR>F(#! zoT-KYzIyd)6w^t7{uTg{-s3x@^QJ=#fITE*Sd9U|>%o6v+MoHEpAlv1k3RaSoOfBT z{))R%Nw=D2lXt4P^!qQ-^u0f_q#F~Jr5lRgtiYzqfnJ8LqY?0Gw407(!!S8xRT*a<69SF=K7 zZ4W8pIM!^AO4FIq=XrIQPgY6xouurt;p*(~bPfI%cMXjTT_$m$1n+{5lv_&~dCdDz ze0Pxmccd(ZoclWz43dbN&fwfKGKRhP36)q);?|9woE}C)ryFh{t+G4igcoR~rn4n= zo!2Y2Tsz5;S0B158zdmb6f5(19UDc{Q}=|P0%L-^1X34BgK7+NR6c?p(wHj~(fZ76 z1|ts<_K&oE=RE83=T0sW1Q-MwHu7e?0(|K_iyarO70?eb0HL5WkU4s%7835{-_QC= z4zyEta*`8y6r<52ubx%@dwD#a{F}}snbXv5l=n5*41`V44%dh5bT%qX&;!u>p)Ujj z8~{^A*C@J^Kz)fs_E$qu#EM)3$=YA(1&a@XQ3Y7!KP)BeM-o5b@3LY9Tczw&XqWS|6+$9Khr{Mt)~P7&*{&=t)9xvh_=*Hiu!b_{r8#3AH1|Z5n|rCk;4vd3@^+9@5J{ zaw%l828qn7KlzELYmA+B{?(C9!g{B89IYe!>Gps9C65oT8a8O3XG?*w1aSo@ z&6Aw)tbY$xt^K@fdX2d*YL?$OZ{Ea#ypDtT-o1NbHvzE5NLw$KiUtDIv6JqY)^U;P zxDhIcbdGeG0N6uPrJ<4k^}BBW*GJ0G%FHjl^is+5{PWK%^Os;4noua-fB$`6PXLHq zy8bfLIaBEGZcbOy(W=Uba|S-`MmTl>h^n&HVY&|XbuD!|w)u2bBIca=Hr9GQlmT1k zzkB-{1;|RQ2CvuO$>D~8_7^Z{X^Y+4Nd;e9gbLXHNh=%e7Z_YMvkl^Sxgj8mvuj`o z0=~faATN4VP!F-q$};sU!=W_s3n$>&YG_!*?58lABF%5C$7w5JIOfW~E-FT=(~%@; zG8PBW43RrSgt$P1sv(~IuaRtn-X~{UukHL z34{b!^@P!Fk;ZZd-_QgOOv~rhkEu>v3@BmMZsJ_KLOH1uUX)A(M3kU4OqzH$z(5S< z|VjB0*d)175*Du}6y-be}ZTW1C!vMy7gc_yFXCy&uG5l?80- zqe?^cItfBr{?Mhq^4`fmk-f8_oXKxY4iU!)sLKD8D`*~Q4Qdt~B!fV*?_wZ{fN?p2 z-EbO({KxSU4nB@SzGaU!P{TEM2c#SZDeOzT+o4v^-WH)6=^NzRw}{1#laB8l=1O4V zl%Z?SDF2-nIHmkopgH+RF|onOOF6SZc{>0>S0ol;*BaXy)J|Mck0VP5{c^C)jh&Ss zp7U(`Dsk-Xb9rR%Cg<124*)vYkk#qHNb8WX>QANbLGy(Mv*98s?+ii>^F5T9vNvU5 z|E(`YKz}8G-UkVu^j&jc@R~l1dR-3);Xt_=q;pOaxSEUpW@xhu0CP-yhrW%Ez6}C> z<#f+H(rn`q!pX^yRj-Oe@(p0q)RtcB-*3I2{T3__?Yw8lW6KV;J{Bn z(VHvudx%4kuZo?kpBUT~mSqP0LeUo?Bg}Nx)PP`(S9gYC(A*s->nO0!+pZp5IS6_X#eCpue@`j{o9=$J9 zXUo|X9C5VhI8YaA^AIX&`wd@hdQuRlXmK zV`BG#dp!*O-%hFq5vN=gjJ`DZ@k#mI-SLJF9jm3jqM%REpMes<|9SViIrp3c0V4bY zbaPmY(nWPwQPy4^)98EnG`T9EC**yQe|RQNFUo^GrKuM!B2P%{Yv)Jz%# z?W&9fk4_1b?dU@A5`fEJT#pjCz6$xL;G0rpa{fqq`U!-n5a@_Jz@E?fj&m}Apv&gC z_4a>mYiGM+-1llSF?J#~`orsPd=a5e;lL|t@@0Q^@T}gRe`m5EbdaRGl?`Lm5P-++ z^4|{F+my2|sERuWq~(q8ynEcBjEfKY`|i!F;iKcMS)syIcUP84T=Ub9jpi$R&n62# zxxmym)6sT0Oi~OM&~}vg(q%oyth<^?$2K=^+%Sx4(qquCzy5mp{=y3{lpO$?@G3wZ zOVJ_iB^@RJ_K>ZW7j zhQC~+oJy@`C9qD_FN~|M>IT0llxS6?G34Vkk!tAfed2mx5cZt&Q~zEEB}qh$VsDH` zugIG`G*3cvWj`BCgY_H@w52P<08bX`=gv?y#zf|28UsQtY@#{g`n*JxTl=Y9X_0h_ z+=;7Q#^K0{Q0JK1Rz>4hw`V8#NHH)|CY06|(B6qvS> z+pNX~iQ2VKcg8C;nXj$`U7JBPl(P`lCIcuSuvL#J&+ai!I!K5I4oIRmu=OP0$mZMX$gIV8@fOm9#ua)wyLT=esE)Qu|~lCjE@BIGm*CK&o=U<20CB zhL;r#MlGKog=yLr6E?QO0rKywnk+4^ISJVBQ)f0&$(0RZo31AW0+S#r;qdaYrf5$%twLWnj z@oeC|>kF?V`pu}+43v=(2l!Ibk2-wMBL6uMr*q4H(bR@uy**$D^6!1<`i}Aw<)6AT zVr_7JJ~1_uT|pSAMxw0sp&!MPYJ*%TQa=;Oza(i)j+om)Y3h1^KtaoPB0?vd>+Xs? z_5>4#BuJ%H;Z80|3U#`+9nBEik$RfSz7m8czU(^q+(brO{|DM!r&mzw)qXVq2gL z7dI586sApp#8OP1S*Mhw0jtqr^+osx?l(i+81_4QrLTevf;d@FC5W z^eC~ZxRI7?oFSQ&8ybT2`WE`6!%YT8tFOb2M}fK25E?dIy;Ke2~XLxdh40H+N!v@DOJP1-Fjc?t@i32=sF3pfv*u>!%Wp zyx}d*fs2(V7znl7`qp`mZDPmzBV;1_o&a{+&XR?}M`}dT28sS$e1zHN$3Ad6HC1-< zUk7{H_88;^ttx%JB0Li7{gyaOc9ipsKwSb8Ki+D#)xfFaC(eG8u8criqHR+S;JJrk zdRFyf4y=r4CR~jZkQ0}3vB9>krQC7(C4;h;^A=eG1(ahzU2dSQLNjt)MGrjE(zy2w}N zU8gcMG#`+kmk)Smd&3OS>E*xNQetgjiy;tool*WJx|##ubIJeI>RIng?6+1ne83}f z`KOK_pdW%fE!iu)6=T76a<(~QX7vV-Owk9<^R8!u-=VEOIpQ#6ayv+K(+;$+&4vlk z2__4eK>Zk8m;cf%m;agzW3Dv%4(cD;f1qu7G^HQV2tgQL&O+EG6rLEBdIgrJOvZLd zE%{oW^2}7$-}`h>)y$T`?|u~=cRy`}9rbhK2fWny5$msSuO|VXy4?D~Sk1jV*Xhl7 z-!?wCMHyX~JCbt5rpoo&U%%|dK{;8!yZxvW2(1FH{RpH%8$m)S{7Bj}r#gly0QGwF z?|=XMdJ}*zdX_5mIP_|@nqGS8CAoU_YFR9O@x>Q)!Bp%Bwd+4V!~xiCI_v=0ZQ{mI zuhV))tDOJ;@WT(w0}TN9+H0@zn(47nNS$8+c4~e+*kZF%VQ4K(3qksb`-Kyx6@6NU{B&!5QgO zZv*}HKSrW$%xAb!)2BYCM zOfbWb)d_+#Zi%zD){pvukz@(CYvy)IcU1gT<7{jiI-42keDA~`k z(bH$Lr*t9(+U|Y@l2j6TaB?J9LY?P3Z?rl_?nwdxCy6cMRytO9qOIU)k~?U2oma~r zLd|O04>SM)5=$?5Io(^5u>? zx#K=b@T==loM;H1@I1a9eWIAOh<2NU8G+(JN4RVy#U)7K{TX_qk^fi|%6`Xk$CQH| zA5cPum>NWxc0QDLfY$8(Ac?#|!!kC9Guc3XY+J}b`(%MnQo3w-oi6_zznl6TC$D5m z9?0{u6uegDpP&u?-uUrYf~TU-fOlb5HT$pWq*{wWW6vc20=Vo*{weJLp5z~zSKo1d zkDUhAx6ub}v4)J)RV`4CjQ{PZqVq*Lp5^L2SvqW^Gy}p!Adj)+LP@PdK>o9F8N?tD6{MH0RB7MEKjim|(S_Zz*j?pBd%i2;W^v|*X zdg6@W&+4Ca=f!7|6-6F3bO&cc->bp-z2v_tsUa z{4>R393xz@#fS-H+4wD#mEG&=F<(;mYHWel|7-j`;-*_d7xnGwpUL1kzW>7iJSGAB z2*B;zx9QHEJCQ|q0IbJItB*eVNRI*Vx4!kQm5!b8CIH@sHxB7k>97M}$H|=v-L|3( ztTR{|)Iy)V`s%Cn!V53Ry?gig!Gj0<`@jGDD-DLBI|KB+o&PVp0j}P-f6E}!Y|l_A zaPBM5XKrXo;`}C~H6jQuW4oHe1>*1uaFwoZ@IGR-Vo;5sA+!tvgAE3DOvjcQK3b-%^H9xSwyIUHf&{&z zZZ)7fLxzw=&h=G|e20F3n4#o|Kaqi(prIa3yx=6^yf&sV+HFo1tkQ*}Mil(!v}>+t z^i^7OfZ6y6yT-*lR`?{hiqk5$c9zKl$H^T5O4f^28VEY)?WnL;sVA&o`6##IREM6U zA8@s_e&?CyDXR>=YPPbF)vMM!bGUWq5Y1&nxEqiWVdV1UF6c)*YJyB)1QGiT_V+$w ztcyeKag?E4UE&;I78om#e{mk9qzW^r=T-KZGYK+_*mwIxablSK!T}88$gq1R=y9BR zTl!Mq=lYz3zBVB5`xa%>aCbVDH$bC2(m_G@rayuYIbzE&IQ`P-*wqYP^smc5ah%il z0i#SV6xr@v&E=LJ`rKrpl80OQH)avgd(pOHJH79H!jeOm)c0Op?k;dXsraracBbeX z(`gYQUlONN$-mQ72zZUoEdS237z}Zz@^3p{$m_7qVaXjkzKhBSubhHxeU0*O9q2k2 z^`gmaC2`Uv<)1pUECBF855MFC?7FjqEPySA?=qL{%SGxCIFU7layI{_W~#xqglbM^Ij zTd3=-Q9e&`)MW5{#Z5csxX?UF_k{;}M$e26Z@oXYrmIHOj;7tcb*-HkQ#>!3zFt+G zu(FA{atwy*czbouGq>BaaP)C}RhQRlH0MNyTzgyWD#pJL|Q|4NyD6h)>EJgA?e z0b5bSIpVrfe5?woPEFRl$7ZVZ_ZrTpp1VO!>bNhC0Q6~OsoYouZQ#$fYbbHf?`~DS z3=QC73dfY&-&iMga7XX)_Xx(w=yYwX-7T|xVc(>yyt9+l5i$@0|PLMqC zW%!ZsSY)_bmiC&dS!L_?q!cG z{BaI$q~k}YXXTT2#UOB)gc={naS8`qB9BCWQpF9qL$zh=llxJv<*WnYV+3x&vSwdcMITeo^VTAJFVZK6Bvf+^{LivJr0bPR! zV?aqLxP%?a1oAuqjgDcZU!vnuO-kY>aQ+?jN28nK$WQ8)N-Ju3B=m#zaP;x$_ZFdMOd}o5h#I-U`l6q#t!Pi9-JoZ@mU@=n z>z0<5$5YUEd--p>-dB!!+J*d6L+A6!f5L0Fw?}(B`M3JYRfxoSR6(-B)J>A|Z$|`j zVuf0JBoaPR(8gZ5o{0`H`n8i3wsXd^1?ht4oQEdR?mHY9^A?+p|CII%7bOJz`SHF8iOFiR416BC$ zyYH6!F(F6>(~alug9|`l>AGi3z2oPB$lRc%KJ5%tvy$x|B2is=s0O^O4p18RIDh9Z zoI1Hy-wKuTu`8FK@1dZr>A)^5%So-T`&_ zXU1jW_u?~ds+$>|Q9Up^;lAx1j~5CMmdPwXLwEMP)U}uBdojRDA+Pc_RH)~_Oc<`b-a6XceY@0h_wQ31sq+@68n$THA(d67B zYcvg`HDPAk2|(Eg=#Rtz#PKjEJ^mBi_D43Ltn~(694GX!SH5Yx5;y}<*?=Sldjk3b zyq&uA3VK5t=hE9=j%LJG`1(Bi+Up=f&nMxeQ|srS12^X#k*M4IDd<)D$LsWgQ|8Z^ zFTjBk&uputvu`v_2KD3U#9 zfCv09{RCO^zQf50W1}HMUT*u$oyh2C_#Ltc{fqtOJRAYn0xre2*XU~>JW=YL0_r&1 z6g+FIV{QXur+~MQ1qR{Juhw><zo`GJBG%`8|y_)v7 zv<{wxNsm(Ycrq%<`Q;yXREV5j{>fz#xejH|QJ1KLL6$@Q1?q${p{*_Ae%WnxjC$2^ zj43AyJww#WqDX^N?)0HNjzP&X)XPr5b9v!tYo!^3T_cM49*zCyV8@_6s9?mI5sknh zB_Vx3F9p-l40fj*6Xz}@d&w{%gKZ2tWa`I*(B*AjIpGm zh;m!PAJR7IFafaRq{c>PtY8NK>-Byf-SUMOUJ$?b;_ltMdLO0=1l#PG-vB_X%ePOs z0brydLFhoKa9_lS$H=r2e_Q7PB2Ep_xYWB{Jdtg=mRf?bx{m+u*u`7Z37%Ob8KjOV6D$pfz>Ra_|(ZFEZx#%B-9SiX=!ov)v3dpTYK-G6vJwcJHm;-jQff}W+(@8VVFglKJ{(XjP1k06FNv! zK6m(>g%GnOj^x&cx($9J*9!vtFdIk)rCScbcJ|I}@|NeHVjvGpSO+MQWu4?~WxNv9 zUCm$)2^jQ%Hg^NV7&LiB)V96kwEBE7=k0Ucn?Zfh7VCii^tvSLjX{~ffCy<5G@6=n zNVDvxxx7T1sDmxZ2hL9ki!zUK4)#w@gkZfC?a4{QmRG_h)fglsP5;DzlYxiC`7yTb zl<#x;x9tph6Bt|@J`!-+0kJglmvk5Wboxyl?Y+yPL=X>fb^275EDim*>+>8e1AVIMI?7A+fM$YK`c;%H>M0WuE+OPduuqE6Cz;sAEONR-7JtVsUpd>&4@Aq435I`~}e)G*Y z;|f4cwgUhdycfDnyubWTD4hxEv{EX2$ZMY-nLPt6Y0y8;fy}BJzIv3}hB;uwF~;9h zSC4YMMl{>GC1N`OwoYf&=$3ewn&h0goV8X#`(%StPTTG_w6%k{Dc!vc$kEYd)Ur~F z0SPjG3A2PqP#727iog!Yxl$yyc*<;Wl3=(I1$RQz%?T^f9Z$fOiNe3k#^chQbqmM1 ztRRAO)C^JpE}KItU{o=1SOXUZssaO2r%%ue47leZF=dT36v&5;9l5tK!`Fk^Mtewbo4nvpOZOP6V2O;I7yTX9wLcsJQP}K{s!xKluD$3@9-y}2ZhsE zE+N8Q9@y6QkMjF8HSOq~wbTt0)a&2d36L|(ztJ`)g|?CZmN&6Y z+}j0dh($OtG^R`b8@jq98}?P|Sd@QCBL?wBvN|^OIrKjaXCQxt8Nq0s2OUO3O}Dm* zoAk{CJklS_TNkpElMZp5jnZB<_#wV=COn8u4Q*YQw5U9ybU`&UU1%y-0Y2<(g?-h} z>+1=CyX7iCwuv68yBta4SfA>F$)jVs-yzkP5qsv&c8Y}MpHPNUFU~}jT;H!~yG3_d z{LNRc>td!{zka>MIn!sl=(!&Ilrhln|Nifnd~gJyjGMmt)vp#Hx|j-Msz=9?KY-~l z0kDU}wogTa0K)lyAN-Tv03a5H=9y=n5j_*rgOJNl4R!z^@AHOt^?jb>sUB$?Rn`nL z6Xg;6$!$qGYZ1)HbAY2WP1HmJupu7 zfXrxe0Bl#P>nA>w-Ve3E#^H)a)`#i%6X8IMq?g`hsYAiq6#ryTMmZn=ty10-Kz zLwvKN?K@{3Mc2*RC`pGI(@=-6(~M>V9;Q)Q3cPz7Vq3VOMW6CrvwgdNAMo{O$6KK9 ziTi%SK7qk;GqFR|j(++W@EZKBSY~bG8E>@Z8OpRPV91FD8_CE22^VxRUSd?d2tHfix`Qx>Qqm zB(up=qY2i~urlN;|9cxL%QZMa-+EBi4t^b!Ns=1d)$~hGMd@J446gJeahd1KcQQLM zKuoi|9BmP7Tu`UU_d}34{y7(fQ>70+PQBq{bx->9nq3nZ90PVsd#S{EHNmf8BWzM# z(yWBsI+K-vw3Q(QW|RB~TV#vpGYL3zlGP-=;V^mETWN5{v<<-LxP{Khm* zzVffTst?=$cb^Uu0DDSZ5Wq4S;J^Lci!#6N0MIir8XZ%g#aWr7D_b4`*z`U}302vo zfpo*jjT4@xu&5fz)mV<;ei8sYnsejO;8|Il5Ku1D^Zz-kJs+5U`0xTJ0J!;hViGzG z?K!mSZI{R05 z2&r2obtgnxbwR#ec0?Did$!^VdAUQO{A?zQvaNkS$G>;vk(Uz>YRNe8Tet_(=sq(3 zbT&@FI3Pfn&GE<>L=V~>1crw)#!Y%0`vfo<;G#|t0lBjVNe2({W8f)io@d)77$@;q z?CVCXBz_}rwYX)Sf;1a6KJ*#zArIRnEplUUS!e%U0DsDN=qO{m#V5^Wp-QNu?v&G= zJlyg~m%mmeEiN(#8+doZHj}-*%fHNIY&L-0s4@R0h$#rM;4>>BtuEvab8`GRS${q;oS$yP z972ydUa>x=?IF$6=_&QQ-c~4uCW> z--on|bhrj^hslGF;ox6`SyM>xh!!iY zVlT#|cq96cSv!qwu==nn9GjY?5JbwP%RLi&f~L27S;^gQ}w6M=GFcQ~8HuLde^K zwlrAIbWD-A*lN!)@XhJb!K4e=%9gh%;1CfE0tWfcEdR0_`KP-3N-zo@ce*TOOn}En z!|Az#5~oA7!|H>{J+vKcw9xk{@wITE!Y&VnzaI+&S~&%fNKqH_2*V~}``PuL(~3As z3D^##eC?m^y21L0xYL8=b#*B?Z~p3sA_Y5NQ2X_$Ys<-| zF!*0yZX)1gu}vCe{bnY>7Uw%3!*It8=i!aj(UC^{E90B>L_l*vr8n%m-~BG#yLT^M zy!`UZdJ{mYRTocnOl5XM4m$yMmkv7sc9_tiQ>N7!EDdI%vstgc`l?*IbV+pZugs1~ zcL3;?7#;j87!8=gC++~)CJCXiFn0zB4CLfqiaSP94N_GqX+)b@WC7JQSVr)mYC2(X z_vTfsHk>2-N^gB|LE4vzo>=vPxEs0SkH8(0%;U!0dd@!6>1%UOnTJdp${r%PJQq|4x=hLd$$ythRwDg_$;!@2tfBt1O^`F zu1Y#0(MD={H-5V^5O1J^6{tdhZrupX{61tZ5qQGHxf9-2C(awz_NCx6aID)?AXWY+gfH2s;PF|FDLVpn zH7J1$B7g5r{&UFL=NZaB_3}?N)2{%v+O@V00XaLJNW=B+8M^WcmX=T9ea~sF z&idg?p$0D?z4iXovI|oq*LQDTi^;3j4oL~&k$mSP|EA|1l!9 zPY5g*ZDS8kNV2+e9~L$F#*G_(6F{l%*=L_+Jr)h9>-b6h_B6ds&2|9LA?-FDCIEJv ze88S(dJR)YUjR{>}#T z3|s8eBH5=S$Rv%c2UWJdQ+kEsXHIEQclU{-D|p%aZ&^nUSOh;uPPEBcdiQC7kzROo zhx_A80#1PTu?&X=Rw1azIEC;Z6 zD*vtC+DiU6@{i;MjQ?Xi5rdE5>GWN~kYR_q&amIo0EKLk!S`3yzuaL^KUdJQp`IP_ zVN)Li9%;K=UXee=>lgo({S`E!PIQ{Or0HAkaAc$j(=0E~$w+b{NBm%?i)wu?c422_ zx~4k-j4%DlQqQ_VyR`m(T%b(R$1zD|-!ayfvyc0K4&Pz*`p$O)oPXfWw`{jF>lnu$ zj&1_bYOh|sS}L^hQ?Tt}<$w3-FafZmWJ1C&EV^aIw*TvSmWFdR=!NAi&pimB?EuiD z0_(S{Gfw~r*dx5xJa*Dr9!b1QDqDqCHZ)9aK{3bz!&KCcSty@9E_F;q1QQL)VEU)g zO`8O}5j5XcI{<#jX8>b6YdA7(U;Be}8vT0?I?>?!dj@ABC@j4jg$XN7%i=KsWH2ca z*VMVE4vr6wiTfCG40v!je4IRnSV}rKjbj9kQv~K}nt%qmVRFlx4)bVWH(ZhwSc$bd zxb+(A=hW7plLhIp*1@O{UcJ@85sK9-pWVk*^8{}&1=}@Pr3>)wgU}ZZT)PHT0+9wE zOl^HhQ?ED&I)Y70yeDbs>v%CTiDdtY5Y0xn{!FN)CCC(@N3puvI8#}s)bF2^G~kBb z65p|Y?33m_cYG*wI)>h6nYViyw2z>DLa-$i9LA;}tr(6JoIxB-<7?@O*5Q+UAuuu# zfJ-3gZGSWo;RPoJq+zdiK-DDy{2Th!zp3L@>G}%kI7vH*44M=4b=ST;(@ulFZ|Q;P zOUQr9Ufb@hLzd_rpz~S79|ZE);9`Gq7FmGql2x(GKfEVu=u6bS1G>5W$ucSbj2&2t zv^PI^UJqF8lhM>P!(ciucd|r;Ebi~7Y;Vw5a*##t5v8A#y(cBOY!0yy)4$u4JPL9b1Y=~B*3|njb$JXKmmB`)~)j0 zW1_wO`s)Q7jRByaI(}M@mBfz#7%m4++hICP0PHR?3d>i&`c+ouy?OJd=<5G_@4dIu z02gZ}FYljy_E|m4QjWCTxN)OQ2I%bAT1e!|PyFk*H`XL4AVO*Xt75=m5!*G_raZdA z*EFG4;5>%}#?y__N~-b28GTuqaVrXDDh|`}8s@btmo~OXBcry@r2Rx>H>D-oh-{x< zP9QLr+a~XhQg(~qOJ5P;X5& z@szlFYsg?{dvKy5X+QP+HIzFU7fz~rHh zR?yec2Z4)(vl(#3U`O8rJ0ML6JInN1^i|tfq!$t3>h%Mt?8lTXqK3m8w#5z&nVULT zP8Z9>R<{F6S&}wC;2nBTDCt|CSwP+?VPQYED7yT^@9f>GL#AZr;HOETZVLR7tEInM ztRYa#SJ{6=C~*2QQPLeh)fWkWB+nI504Jci*FQ~A2lQp|N7eBRd9dHIOf68vbINGB zD1!wh|K7Gd;{*WjV;Eck1`m0lzJ1A+0H=+2#ni{}xO4Mbv5U>_PG#%3VZ+`{QX)n;uLz}=A2E?6%U9l@ zw7Jyo`elL$Muy8M=Ezyn^um{KMS~&vRe%-)puE%L(z%*?AZ?#@hSbtInm^rIw1-WQkp}C3mx5N;Kj~O!_4OORNKqzGv8!D1(IV&{c<$y-bXPy-19sVN`^oJJ%&HjEAoUVuPsQ%$l| zvfRb4OV_D$s?OPK_@8r*%QwcF>)-pFvw4&EtlH=Q|Fz~EbIdWvbzZwSxAs*e<`lhj zW0;w6fL8Kpjt+MKXFv=|D#Ac3FBD&mmaw1A2S+xi7seq@gbtx1-|^OybQ<1XO!vO@ zQT1gp!6Ca(*_=KXsxDv*!elgNU&Vp%tT?Msh}f(@`}5Ho14iyCfO+_S_xeI<6o>R+ zDf{gV2<->n%{(;~B>z3=p)e38yT+L~mjZc$0QYY4q>h2T%Qj1CyCm9qfKmAc+p(#e zcW@i;7%;Kl&R&PVyEizPTWr0|hb;R}+_iad|ULedf{2 zal*ghHt4On6X|nbTmJEijo5@rEY_GQK8$oXyFs28dy(8anMg{m9opWozk74Ymg%K+ z722M5QGespjGMR1&J;=Q3YwGA8hAXoDtJjihCK2*z`hIoJpyUanO2&ELK#^t2`}H^OhF)>fX*UpFTu~G%sJ?trk<9_qV!5Zk*^LxTr%EK zcI0{K1~h1oJ2^GabWls3*|0 zD*&J&_6MODhvDgi6wFB#SeVN{YT1(oS$^nHUPS92 z19Yy7me5VZRnaLw+s3OrH(VQb_Hmr5&J#{LpSR7-bh$t}dG$+oZ~fN)>%9(9XJpD2 z06sfA>oL;XZ@ooDke6g#MZ<;dLmGI0GO~2DMq0 zwFT2{6jJk;vbB-_0b>MJeFeb8moQ}C$HPG7xcN>=jlexvCS zF4w%XI-%T-AvxNuOxsMR)K>~c%`o#|aNQxn{w1`J!+uLy*0n|^_P|jcFnz~pn8A;U zrb*|8>{OwnD~?WoZI0d=4-)CeG18Qh@hX!CMGN4ObLWSnJ0v@cn3Xy9+QEQ|16hM+ z7I;O_1&qnS3<`^tjy-5;GGSu~l}D^IMGyO7lOLsBb&9n9WXMV4IAHxQJ`fV`qWIeD zX!R|NcLfl}k`3HMBwr<&Oe&BD&t$ z2xD|c^h=SGoJ410Lb$-M*6&%57++iS0tbpd=-+`qeZVJR$E$d!Xge=^V6aN^m!b0h z&d021ID~dHrIqm6NK_Jp@X9aApOI%J28%<`@8C}Y&lG2l8OS3Z5Zjg}p%`39v6_^= zcbLkj`p8yZco}S$ATLPPZ;CSqn&dP1Oo^7pZVYgo}KAry$sU>eH* zMyYv*D5>4t^{x%dXu!IvehV;)n*O|XP+oXn0vA|HFnEWU5E4>Yl>MVw4 zF!q^cL>f3ee6GZ|n^-NVsya|{V{3%^VS;f)f)t)kJc@o8)Gd4boa8b!jIz=L zkj6w4`=16E9G}2H(2}f3h&=O-umU% zVE|x#ddPS>CeK9stnJY?UtEg5bG^P0tQHtNBd$k-M;IE{2Nnp`hiHDu?XTTix`%S{ zlz+YTC+^yqpI&+1-?SKLIT$Eg1#pOw5~#!MKQvQy6emu%nJL?5{nDO4ekv0s z3cr10oRtgY>*>Ksb8j3Cd|nLD%yF7| zV>!CbIz$^dtT82jmT4Qrlk!7y{3z{p7I4Z_I}CHoqj1~2C;_sS{#8*kj8&)q+v*B@M?*AJhcdvMZoe(wHh zf>CVPg_1zCsiI%=yg)tEIxp~UR`+=@@ck^`i{Sn|F!peH7Fr&o%Xz<#)lYQsy3gZ{ z7fBVzq!uUn_I{sN#|&P5b`0+G%0ewi$I4U!?7*2lzmk7C7tep0<^Olye@bt^_mqC^ zpFg2r|F1r!|L=D{q2KxbVG38&P{kdBVBv_;9%_SUKBA1`i`hRfGoXy|Lw0|`2LYh7 zaA1JY{`c?Ek_Z&rVEb?a#7EKfd4i+(xXkdDa1%-n{{fhOBcPSSQ9mKA7*^p(s)F+1 zLzGK+afM%=BMkGEIQlFPUUDv9AIXG7I<<~{oqQFA{r<-*J-EGi|EIC_Lwe=@O?v;~ zlL15b**bUW;8@!_vlvpXjz#(bx@iHTQ231$LsWsUOi7CCQheZ<=(qy#exgmf_R?qW ze)Q;3dfQe%w+Yae+PP@U;>&`#-2%|I0klH^zxAze^%0Y{vbs&Ke(h^tySfVSlG4=x zz~v-UAEj5)-9e_Ats#xq`* zWb%zJ8MySiba|T|bW2#E^V{O6ml>k*xCQt>^{?ITLH~c}Pu`%rHZ-WUeplFgv_Dpl(8ciF zQRhct+jqooua1lI%%1u^hU=_+#brjnSsRG<`EoDMF`RonGKX<2UCIBI{I}Ewh1=i1 z@h5Nk`(OL#pVI&3KluUuC%^d#{j(pOIbaLm#e4+^WcFVN19XdluP!2i1KT20Yd3Ug z@zfvfpJf4C+TO2T6{X3I#lZT|M7*=D7NW(lGJ?t&C}Qv(DUS9Nflarw7%UG{if|pr z;HbbQZ?ix@BJksw@h*b}Y%}7xI>73bk{^?GnYi~6^}FwiP>#FJw?Jxj9SLt%n)d0ZdrJ

WBw05_@Lj1+0w&@5BvWA{_f<~U9Q%BmSl^7 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%0AiVshv@A0Q*0M3C)}` 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 ~Wiw*g?F2q_RP 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 aN1cpG-kC~9V4{Tn5)faFDS4#RmcNC|^H;LMH} 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≠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%0AcA%%`FT%r{$SF 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�qM0TlWEYy}NyUGx4CSUXz@} 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

#QW~#AF3c@>TN5|3Z8nBm2&J&Ddfs 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,-P*7_$1#)##g_&@2$~VL}=G#(UY9$SUPQXuI_i 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 yzm9|Fxexeg6;su_$T#b*-x{%~$$2PWM@V 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

OXIWN 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

G7leJd7o7utAN*qQ%Ay@)N7|S}xQc*tvWO4% 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 From 6cd10f3d5e5430012b45fe72ec93e3a2525bda7e Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Wed, 26 Jul 2023 13:27:55 -0400 Subject: [PATCH 053/160] v0.98.x dev --- Cargo.lock | 2 +- crates/zed/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 623ebd982f38f88011e16a863cef53a7b871e23b..beecb775d43a52858a74391eb9ea9748fb27b87e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9536,7 +9536,7 @@ dependencies = [ [[package]] name = "zed" -version = "0.97.0" +version = "0.98.0" dependencies = [ "activity_indicator", "ai", diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 8c423eb51b8f1a3f85d6c5dc41d138a776a8229d..f246e4168160cfb25a16bbac7651ace31e9faab7 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.97.0" +version = "0.98.0" publish = false [lib] From 40fcec1495c36e4d06bc4216897fe5d7c910df07 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Wed, 26 Jul 2023 14:35:23 -0400 Subject: [PATCH 054/160] Follow naming convention for menu items --- crates/project_panel/src/project_panel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 3e20c4986e30e037c0b408dfffba8f192ce0b1d5..e6e1cff5981cf7450c154cd7173ab195c5190751 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -430,7 +430,7 @@ impl ProjectPanel { menu_entries.push(ContextMenuItem::action("Reveal in Finder", RevealInFinder)); if entry.is_dir() { menu_entries.push(ContextMenuItem::action( - "Search inside", + "Search Inside", NewSearchInDirectory, )); } From 98fde3683448c9057b94be1de13cd3d58f0a6351 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Wed, 26 Jul 2023 16:36:39 -0400 Subject: [PATCH 055/160] batch search queries in the vector database --- crates/search/src/project_search.rs | 3 + crates/semantic_index/src/db.rs | 72 ++++++++++++------- crates/semantic_index/src/semantic_index.rs | 76 +++++++++++++++------ 3 files changed, 106 insertions(+), 45 deletions(-) diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 52ee12c26de17274d5cd8c5d39a69843cbcb7869..7f1a639a6908940c4b7f11e9b84f8618fbf1bef5 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -30,6 +30,7 @@ use std::{ ops::{Not, Range}, path::PathBuf, sync::Arc, + time::Instant, }; use util::ResultExt as _; use workspace::{ @@ -192,6 +193,7 @@ impl ProjectSearch { exclude_files: Vec, cx: &mut ModelContext, ) { + let t0 = Instant::now(); let search = SemanticIndex::global(cx).map(|index| { index.update(cx, |semantic_index, cx| { semantic_index.search_project( @@ -208,6 +210,7 @@ impl ProjectSearch { self.match_ranges.clear(); self.pending_search = Some(cx.spawn(|this, mut cx| async move { let results = search?.await.log_err()?; + log::trace!("semantic search elapsed: {:?}", t0.elapsed().as_millis()); let (_task, mut match_ranges) = this.update(&mut cx, |this, cx| { this.excerpts.update(cx, |excerpts, cx| { diff --git a/crates/semantic_index/src/db.rs b/crates/semantic_index/src/db.rs index 4bc97da0f08e3d56dd249da72cd8deaff56f7e0f..85631e7fc62654ecb51c7cab88c7df68cfbd2711 100644 --- a/crates/semantic_index/src/db.rs +++ b/crates/semantic_index/src/db.rs @@ -267,41 +267,56 @@ impl VectorDatabase { pub fn top_k_search( &self, - worktree_ids: &[i64], query_embedding: &Vec, limit: usize, - include_globs: Vec, - exclude_globs: Vec, - ) -> Result)>> { + file_ids: &[i64], + ) -> Result> { let mut results = Vec::<(i64, f32)>::with_capacity(limit + 1); - self.for_each_document( - &worktree_ids, - include_globs, - exclude_globs, - |id, embedding| { - let similarity = dot(&embedding, &query_embedding); - let ix = match results.binary_search_by(|(_, s)| { - similarity.partial_cmp(&s).unwrap_or(Ordering::Equal) - }) { - Ok(ix) => ix, - Err(ix) => ix, - }; - results.insert(ix, (id, similarity)); - results.truncate(limit); - }, - )?; + self.for_each_document(file_ids, |id, embedding| { + let similarity = dot(&embedding, &query_embedding); + let ix = match results + .binary_search_by(|(_, s)| similarity.partial_cmp(&s).unwrap_or(Ordering::Equal)) + { + Ok(ix) => ix, + Err(ix) => ix, + }; + results.insert(ix, (id, similarity)); + results.truncate(limit); + })?; - let ids = results.into_iter().map(|(id, _)| id).collect::>(); - self.get_documents_by_ids(&ids) + Ok(results) } - fn for_each_document( + // pub fn top_k_search( + // &self, + // worktree_ids: &[i64], + // query_embedding: &Vec, + // limit: usize, + // file_ids: Vec, + // ) -> Result)>> { + // let mut results = Vec::<(i64, f32)>::with_capacity(limit + 1); + // self.for_each_document(&worktree_ids, file_ids, |id, embedding| { + // let similarity = dot(&embedding, &query_embedding); + // let ix = match results + // .binary_search_by(|(_, s)| similarity.partial_cmp(&s).unwrap_or(Ordering::Equal)) + // { + // Ok(ix) => ix, + // Err(ix) => ix, + // }; + // results.insert(ix, (id, similarity)); + // results.truncate(limit); + // })?; + + // let ids = results.into_iter().map(|(id, _)| id).collect::>(); + // self.get_documents_by_ids(&ids) + // } + + pub fn retrieve_included_file_ids( &self, worktree_ids: &[i64], include_globs: Vec, exclude_globs: Vec, - mut f: impl FnMut(i64, Vec), - ) -> Result<()> { + ) -> Result> { let mut file_query = self.db.prepare( " SELECT @@ -315,6 +330,7 @@ impl VectorDatabase { let mut file_ids = Vec::::new(); let mut rows = file_query.query([ids_to_sql(worktree_ids)])?; + while let Some(row) = rows.next()? { let file_id = row.get(0)?; let relative_path = row.get_ref(1)?.as_str()?; @@ -330,6 +346,10 @@ impl VectorDatabase { } } + Ok(file_ids) + } + + fn for_each_document(&self, file_ids: &[i64], mut f: impl FnMut(i64, Vec)) -> Result<()> { let mut query_statement = self.db.prepare( " SELECT @@ -350,7 +370,7 @@ impl VectorDatabase { Ok(()) } - fn get_documents_by_ids(&self, ids: &[i64]) -> Result)>> { + pub fn get_documents_by_ids(&self, ids: &[i64]) -> Result)>> { let mut statement = self.db.prepare( " SELECT diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index e4a307573aabc00336863b23a799138c52adc895..d2b69a0329314e4ec270eedc2fde017dab47cb3b 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -20,6 +20,7 @@ use postage::watch; use project::{Fs, Project, WorktreeId}; use smol::channel; use std::{ + cmp::Ordering, collections::HashMap, mem, ops::Range, @@ -704,27 +705,64 @@ impl SemanticIndex { let database_url = self.database_url.clone(); let fs = self.fs.clone(); cx.spawn(|this, mut cx| async move { - let documents = cx - .background() - .spawn(async move { - let database = VectorDatabase::new(fs, database_url).await?; + let database = VectorDatabase::new(fs.clone(), database_url.clone()).await?; - let phrase_embedding = embedding_provider - .embed_batch(vec![&phrase]) - .await? - .into_iter() - .next() - .unwrap(); + let phrase_embedding = embedding_provider + .embed_batch(vec![&phrase]) + .await? + .into_iter() + .next() + .unwrap(); - database.top_k_search( - &worktree_db_ids, - &phrase_embedding, - limit, - include_globs, - exclude_globs, - ) - }) - .await?; + let file_ids = database.retrieve_included_file_ids( + &worktree_db_ids, + include_globs, + exclude_globs, + )?; + + let batch_n = cx.background().num_cpus(); + let batch_size = file_ids.clone().len() / batch_n; + + let mut result_tasks = Vec::new(); + for batch in file_ids.chunks(batch_size) { + let batch = batch.into_iter().map(|v| *v).collect::>(); + let limit = limit.clone(); + let fs = fs.clone(); + let database_url = database_url.clone(); + let phrase_embedding = phrase_embedding.clone(); + let task = cx.background().spawn(async move { + let database = VectorDatabase::new(fs, database_url).await.log_err(); + if database.is_none() { + return Err(anyhow!("failed to acquire database connection")); + } else { + database + .unwrap() + .top_k_search(&phrase_embedding, limit, batch.as_slice()) + } + }); + result_tasks.push(task); + } + + let batch_results = futures::future::join_all(result_tasks).await; + + let mut results = Vec::new(); + for batch_result in batch_results { + if batch_result.is_ok() { + for (id, similarity) in batch_result.unwrap() { + let ix = match results.binary_search_by(|(_, s)| { + similarity.partial_cmp(&s).unwrap_or(Ordering::Equal) + }) { + Ok(ix) => ix, + Err(ix) => ix, + }; + results.insert(ix, (id, similarity)); + results.truncate(limit); + } + } + } + + let ids = results.into_iter().map(|(id, _)| id).collect::>(); + let documents = database.get_documents_by_ids(ids.as_slice())?; let mut tasks = Vec::new(); let mut ranges = Vec::new(); From 89bbcdfa4f0449f3e887118697aa0b0edfb8f941 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Wed, 26 Jul 2023 16:51:25 -0400 Subject: [PATCH 056/160] remove debug logging for project_search semantic search --- crates/search/src/project_search.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 7f1a639a6908940c4b7f11e9b84f8618fbf1bef5..d84f15a22f7965853f235ae8f23322e69e6335dd 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -193,7 +193,6 @@ impl ProjectSearch { exclude_files: Vec, cx: &mut ModelContext, ) { - let t0 = Instant::now(); let search = SemanticIndex::global(cx).map(|index| { index.update(cx, |semantic_index, cx| { semantic_index.search_project( @@ -210,7 +209,6 @@ impl ProjectSearch { self.match_ranges.clear(); self.pending_search = Some(cx.spawn(|this, mut cx| async move { let results = search?.await.log_err()?; - log::trace!("semantic search elapsed: {:?}", t0.elapsed().as_millis()); let (_task, mut match_ranges) = this.update(&mut cx, |this, cx| { this.excerpts.update(cx, |excerpts, cx| { From 5c48729c7c06efb585322f09a97299145ead13ff Mon Sep 17 00:00:00 2001 From: KCaverly Date: Wed, 26 Jul 2023 16:56:41 -0400 Subject: [PATCH 057/160] managed for small batch size edge case in semantic search --- crates/semantic_index/src/semantic_index.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index d2b69a0329314e4ec270eedc2fde017dab47cb3b..bd114de216a0a30b3271b56c2b627439a7e70a0e 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -721,7 +721,12 @@ impl SemanticIndex { )?; let batch_n = cx.background().num_cpus(); - let batch_size = file_ids.clone().len() / batch_n; + let ids_len = file_ids.clone().len(); + let batch_size = if ids_len <= batch_n { + ids_len + } else { + ids_len / batch_n + }; let mut result_tasks = Vec::new(); for batch in file_ids.chunks(batch_size) { From 06167889c3eb73226ff2071582378ac57eed5d2c Mon Sep 17 00:00:00 2001 From: KCaverly Date: Wed, 26 Jul 2023 16:59:19 -0400 Subject: [PATCH 058/160] remove default keymap for semantic search modal --- assets/keymaps/default.json | 1 - 1 file changed, 1 deletion(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 7553c199258a2b21337e4984ecca3c818de2ba7d..a2be44cbce951c86ef2b93a8da7e38a4c42995e5 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -411,7 +411,6 @@ "cmd-k cmd-t": "theme_selector::Toggle", "cmd-k cmd-s": "zed::OpenKeymap", "cmd-t": "project_symbols::Toggle", - "cmd-ctrl-t": "semantic_search::Toggle", "cmd-p": "file_finder::Toggle", "cmd-shift-p": "command_palette::Toggle", "cmd-shift-m": "diagnostics::Deploy", From e2b38f7a31592cce6438a2a7c1fba1460674bec0 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Wed, 26 Jul 2023 17:01:44 -0400 Subject: [PATCH 059/160] remove unused imports --- crates/search/src/project_search.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index d84f15a22f7965853f235ae8f23322e69e6335dd..52ee12c26de17274d5cd8c5d39a69843cbcb7869 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -30,7 +30,6 @@ use std::{ ops::{Not, Range}, path::PathBuf, sync::Arc, - time::Instant, }; use util::ResultExt as _; use workspace::{ From fbede4a5a38c43c22fe66c872f380d054aefd504 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Wed, 26 Jul 2023 17:11:30 -0400 Subject: [PATCH 060/160] removed old code --- crates/semantic_index/src/db.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/crates/semantic_index/src/db.rs b/crates/semantic_index/src/db.rs index 85631e7fc62654ecb51c7cab88c7df68cfbd2711..d180f5e8314291593b1b343cd96527b1aea1d838 100644 --- a/crates/semantic_index/src/db.rs +++ b/crates/semantic_index/src/db.rs @@ -287,30 +287,6 @@ impl VectorDatabase { Ok(results) } - // pub fn top_k_search( - // &self, - // worktree_ids: &[i64], - // query_embedding: &Vec, - // limit: usize, - // file_ids: Vec, - // ) -> Result)>> { - // let mut results = Vec::<(i64, f32)>::with_capacity(limit + 1); - // self.for_each_document(&worktree_ids, file_ids, |id, embedding| { - // let similarity = dot(&embedding, &query_embedding); - // let ix = match results - // .binary_search_by(|(_, s)| similarity.partial_cmp(&s).unwrap_or(Ordering::Equal)) - // { - // Ok(ix) => ix, - // Err(ix) => ix, - // }; - // results.insert(ix, (id, similarity)); - // results.truncate(limit); - // })?; - - // let ids = results.into_iter().map(|(id, _)| id).collect::>(); - // self.get_documents_by_ids(&ids) - // } - pub fn retrieve_included_file_ids( &self, worktree_ids: &[i64], From 354c02061276966e5d8dafe27b52624faaac5891 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Wed, 26 Jul 2023 14:57:46 -0700 Subject: [PATCH 061/160] Block extra drag events in original drag handlers --- crates/editor/src/element.rs | 8 ++++++++ crates/gpui/src/elements/resizable.rs | 3 +++ crates/terminal/src/terminal.rs | 2 +- crates/terminal_view/src/terminal_element.rs | 4 ++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index b48fa5b56dd831f82852f224370500027302f3af..b9bf74ee85f8bbc3c338a75b4cd1bf39bc0a53cb 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -172,6 +172,10 @@ impl EditorElement { .on_drag(MouseButton::Left, { let position_map = position_map.clone(); move |event, editor, cx| { + if event.end { + return; + } + if !Self::mouse_dragged( editor, event.platform_event, @@ -1235,6 +1239,10 @@ impl EditorElement { }) .on_drag(MouseButton::Left, { move |event, editor: &mut Editor, cx| { + if event.end { + return; + } + let y = event.prev_mouse_position.y(); let new_y = event.position.y(); if thumb_top < y && y < thumb_bottom { diff --git a/crates/gpui/src/elements/resizable.rs b/crates/gpui/src/elements/resizable.rs index da4b3473b3069ea343d7acdd0cc85c262e7a76cf..73bec5521cbca1987e945cd2974071eae2c9eac6 100644 --- a/crates/gpui/src/elements/resizable.rs +++ b/crates/gpui/src/elements/resizable.rs @@ -147,6 +147,9 @@ impl Element for Resizable { let max_size = side.relevant_component(constraint.max); let on_resize = self.on_resize.clone(); move |event, view: &mut V, cx| { + if event.end { + return; + } let new_size = min_size .max(prev_size + side.compute_delta(event)) .min(max_size) diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index e3109102d10bdb23de8594c51322df9958b3d83b..06befd5f4ef5b76a4cedccad0fdd526c7d6c0edc 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -78,7 +78,7 @@ lazy_static! { // * use more strict regex for `file://` protocol matching: original regex has `file:` inside, but we want to avoid matching `some::file::module` strings. static ref URL_REGEX: RegexSearch = RegexSearch::new(r#"(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file://|git://|ssh:|ftp://)[^\u{0000}-\u{001F}\u{007F}-\u{009F}<>"\s{-}\^⟨⟩`]+"#).unwrap(); - static ref WORD_REGEX: RegexSearch = RegexSearch::new("[\\w.:/@-~]+").unwrap(); + static ref WORD_REGEX: RegexSearch = RegexSearch::new(r#"[\w.:/@\-~]+"#).unwrap(); } ///Upward flowing events, for changing the title and such diff --git a/crates/terminal_view/src/terminal_element.rs b/crates/terminal_view/src/terminal_element.rs index e29beb3ad52592bee273a34c24aa25b60c172754..194b0a9259d4292aea67c94197a344e49eedf8d1 100644 --- a/crates/terminal_view/src/terminal_element.rs +++ b/crates/terminal_view/src/terminal_element.rs @@ -411,6 +411,10 @@ impl TerminalElement { }) // Update drag selections .on_drag(MouseButton::Left, move |event, _: &mut TerminalView, cx| { + if event.end { + return; + } + if cx.is_self_focused() { if let Some(conn_handle) = connection.upgrade(cx) { conn_handle.update(cx, |terminal, cx| { From d5c30709b37ec27c22c08ee3f8fc940bd5520e30 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Wed, 26 Jul 2023 15:44:06 -0700 Subject: [PATCH 062/160] Downgrade tree sitter elm to 5.6.4 --- Cargo.lock | 5 ++--- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index beecb775d43a52858a74391eb9ea9748fb27b87e..05c5faa787cf29f52b9150c4a224e98c653b2f2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8070,9 +8070,8 @@ dependencies = [ [[package]] name = "tree-sitter-elm" -version = "5.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95236155fa1cd5fcf92123e7e6aa7b6e8c6756b54b5d39afd792a23bd6c9eb7b" +version = "5.6.4" +source = "git+https://github.com/elm-tooling/tree-sitter-elm?rev=692c50c0b961364c40299e73c1306aecb5d20f40#692c50c0b961364c40299e73c1306aecb5d20f40" dependencies = [ "cc", "tree-sitter", diff --git a/Cargo.toml b/Cargo.toml index fc021bee79628cdcaa150d0704846ccf8b8623cc..7bcbc7e2dcf2a73b639311a00800afcb1275ccb1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,7 @@ tree-sitter-c = "0.20.1" tree-sitter-cpp = "0.20.0" tree-sitter-css = { git = "https://github.com/tree-sitter/tree-sitter-css", rev = "769203d0f9abe1a9a691ac2b9fe4bb4397a73c51" } tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "4ba9dab6e2602960d95b2b625f3386c27e08084e" } -tree-sitter-elm = "5.6.4" +tree-sitter-elm = { git = "https://github.com/elm-tooling/tree-sitter-elm", rev = "692c50c0b961364c40299e73c1306aecb5d20f40"} tree-sitter-embedded-template = "0.20.0" tree-sitter-glsl = { git = "https://github.com/theHamsta/tree-sitter-glsl", rev = "2a56fb7bc8bb03a1892b4741279dd0a8758b7fb3" } tree-sitter-go = { git = "https://github.com/tree-sitter/tree-sitter-go", rev = "aeb2f33b366fd78d5789ff104956ce23508b85db" } From 2e0d051a787fa04f7e59ea14798a458533b059cf Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 27 Jul 2023 12:34:03 +0200 Subject: [PATCH 063/160] Maintain cursor stack's position correctly when ascending the tree This fixes a bug that could cause the cursor to incorrectly report its start when using `slice` or `seek_forward`, and then calling `prev`. We didn't notice this because we were not testing those three methods together. I suppose this could explain some of the panics we've observed because we do use `slice`/`seek_forward` followed by `prev` calls in production. --- crates/sum_tree/src/cursor.rs | 1 + crates/sum_tree/src/sum_tree.rs | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/sum_tree/src/cursor.rs b/crates/sum_tree/src/cursor.rs index 59165283f6642fc2ea097113a61255cc98a6c25b..efd6ac145e0978ffc65cb5261bcd616b51aa71a6 100644 --- a/crates/sum_tree/src/cursor.rs +++ b/crates/sum_tree/src/cursor.rs @@ -438,6 +438,7 @@ where } => { if ascending { entry.index += 1; + entry.position = self.position.clone(); } for (child_tree, child_summary) in child_trees[entry.index..] diff --git a/crates/sum_tree/src/sum_tree.rs b/crates/sum_tree/src/sum_tree.rs index 8d219ca02110827d4c76fe170f6c541651148170..24a443051a4dede1a9b236c73c94b54c4ed9dd12 100644 --- a/crates/sum_tree/src/sum_tree.rs +++ b/crates/sum_tree/src/sum_tree.rs @@ -738,7 +738,7 @@ mod tests { for _ in 0..num_operations { let splice_end = rng.gen_range(0..tree.extent::(&()).0 + 1); let splice_start = rng.gen_range(0..splice_end + 1); - let count = rng.gen_range(0..3); + let count = rng.gen_range(0..10); let tree_end = tree.extent::(&()); let new_items = rng .sample_iter(distributions::Standard) @@ -805,10 +805,12 @@ mod tests { } assert_eq!(filter_cursor.item(), None); - let mut pos = rng.gen_range(0..tree.extent::(&()).0 + 1); let mut before_start = false; let mut cursor = tree.cursor::(); - cursor.seek(&Count(pos), Bias::Right, &()); + let start_pos = rng.gen_range(0..=reference_items.len()); + cursor.seek(&Count(start_pos), Bias::Right, &()); + let mut pos = rng.gen_range(start_pos..=reference_items.len()); + cursor.seek_forward(&Count(pos), Bias::Right, &()); for i in 0..10 { assert_eq!(cursor.start().0, pos); From 0ab1c6ac8ee896864ad3e3e45b30d0cf5b8c53f9 Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 27 Jul 2023 10:25:46 -0400 Subject: [PATCH 064/160] Make LSP status message match new font size of diagnostic message --- styles/src/style_tree/status_bar.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/src/style_tree/status_bar.ts b/styles/src/style_tree/status_bar.ts index 06afc378235ec843d64a28313a38c05d395f1962..6261939994ac4e7ae7e06090912218d5dcfb7f54 100644 --- a/styles/src/style_tree/status_bar.ts +++ b/styles/src/style_tree/status_bar.ts @@ -44,7 +44,7 @@ export default function status_bar(): any { icon_spacing: 4, icon_width: 14, height: 18, - message: text(layer, "sans"), + message: text(layer, "sans", { size: "xs" }), icon_color: foreground(layer), }, state: { From 8c9c8362ec1acfeb3f5e98215b961089f0cad336 Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 27 Jul 2023 12:19:07 -0400 Subject: [PATCH 065/160] Update Alacritty --- Cargo.lock | 338 +++++++++++++++++++++++-- crates/terminal/Cargo.toml | 2 +- crates/terminal/src/mappings/colors.rs | 6 +- 3 files changed, 316 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 05c5faa787cf29f52b9150c4a224e98c653b2f2f..bc47e4dc0b5e1d114535b5b0bf77b95d05ff30b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,50 +125,52 @@ dependencies = [ [[package]] name = "alacritty_config" -version = "0.1.1-dev" -source = "git+https://github.com/zed-industries/alacritty?rev=a51dbe25d67e84d6ed4261e640d3954fbdd9be45#a51dbe25d67e84d6ed4261e640d3954fbdd9be45" +version = "0.1.2-dev" +source = "git+https://github.com/alacritty/alacritty?rev=7b9f32300ee0a249c0872302c97635b460e45ba5#7b9f32300ee0a249c0872302c97635b460e45ba5" dependencies = [ "log", "serde", - "serde_yaml", + "toml 0.7.6", + "winit", ] [[package]] name = "alacritty_config_derive" -version = "0.2.1-dev" -source = "git+https://github.com/zed-industries/alacritty?rev=a51dbe25d67e84d6ed4261e640d3954fbdd9be45#a51dbe25d67e84d6ed4261e640d3954fbdd9be45" +version = "0.2.2-dev" +source = "git+https://github.com/alacritty/alacritty?rev=7b9f32300ee0a249c0872302c97635b460e45ba5#7b9f32300ee0a249c0872302c97635b460e45ba5" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.27", ] [[package]] name = "alacritty_terminal" -version = "0.17.1-dev" -source = "git+https://github.com/zed-industries/alacritty?rev=a51dbe25d67e84d6ed4261e640d3954fbdd9be45#a51dbe25d67e84d6ed4261e640d3954fbdd9be45" +version = "0.20.0-dev" +source = "git+https://github.com/alacritty/alacritty?rev=7b9f32300ee0a249c0872302c97635b460e45ba5#7b9f32300ee0a249c0872302c97635b460e45ba5" dependencies = [ "alacritty_config", "alacritty_config_derive", "base64 0.13.1", - "bitflags 1.3.2", - "dirs 4.0.0", + "bitflags 2.3.3", + "home", "libc", "log", "mio 0.6.23", "mio-anonymous-pipes", "mio-extras", "miow 0.3.7", - "nix", + "nix 0.26.2", "parking_lot 0.12.1", "regex-automata 0.1.10", "serde", "serde_yaml", "signal-hook", "signal-hook-mio", + "toml 0.7.6", "unicode-width", "vte", - "winapi 0.3.9", + "windows-sys", ] [[package]] @@ -192,7 +194,7 @@ dependencies = [ "alsa-sys", "bitflags 1.3.2", "libc", - "nix", + "nix 0.24.3", ] [[package]] @@ -211,6 +213,30 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec8ad6edb4840b78c5c3d88de606b22252d552b55f3a4699fbb10fc070ec3049" +[[package]] +name = "android-activity" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40bc1575e653f158cbdc6ebcd917b9564e66321c5325c232c3591269c257be69" +dependencies = [ + "android-properties", + "bitflags 1.3.2", + "cc", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum 0.6.1", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -860,6 +886,9 @@ name = "bitflags" version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +dependencies = [ + "serde", +] [[package]] name = "bitvec" @@ -897,6 +926,25 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-sys" +version = "0.1.0-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "block2" +version = "0.2.0-alpha.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" +dependencies = [ + "block-sys", + "objc2-encode", +] + [[package]] name = "blocking" version = "1.3.1" @@ -1078,6 +1126,20 @@ dependencies = [ "util", ] +[[package]] +name = "calloop" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8" +dependencies = [ + "bitflags 1.3.2", + "log", + "nix 0.25.1", + "slotmap", + "thiserror", + "vec_map", +] + [[package]] name = "cap-fs-ext" version = "0.24.4" @@ -1186,6 +1248,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chrono" version = "0.4.26" @@ -1462,7 +1530,7 @@ dependencies = [ "time 0.3.23", "tokio", "tokio-tungstenite", - "toml", + "toml 0.5.11", "tonic", "tower", "tracing", @@ -1987,6 +2055,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "cursor-icon" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740bb192a8e2d1350119916954f4409ee7f62f149b536911eeb78ba5a20526bf" +dependencies = [ + "serde", +] + [[package]] name = "dashmap" version = "5.5.0" @@ -2171,6 +2248,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + [[package]] name = "dlib" version = "0.5.2" @@ -3230,6 +3313,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + [[package]] name = "hound" version = "3.5.0" @@ -4399,7 +4491,7 @@ dependencies = [ "bitflags 1.3.2", "jni-sys", "ndk-sys", - "num_enum", + "num_enum 0.5.11", "raw-window-handle", "thiserror", ] @@ -4439,9 +4531,33 @@ dependencies = [ "bitflags 1.3.2", "cfg-if 1.0.0", "libc", +] + +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if 1.0.0", + "libc", "memoffset 0.6.5", ] +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags 1.3.2", + "cfg-if 1.0.0", + "libc", + "static_assertions", +] + [[package]] name = "node_runtime" version = "0.1.0" @@ -4595,7 +4711,16 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ - "num_enum_derive", + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", ] [[package]] @@ -4610,6 +4735,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.27", +] + [[package]] name = "nvim-rs" version = "0.5.0" @@ -4635,6 +4772,32 @@ dependencies = [ "objc_exception", ] +[[package]] +name = "objc-sys" +version = "0.2.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" + +[[package]] +name = "objc2" +version = "0.3.0-beta.3.patch-leaks.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" +dependencies = [ + "block2", + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "2.0.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" +dependencies = [ + "objc-sys", +] + [[package]] name = "objc_exception" version = "0.1.2" @@ -4753,6 +4916,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "orbclient" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "221d488cd70617f1bd599ed8ceb659df2147d9393717954d82a0f5e8032a6ab1" +dependencies = [ + "redox_syscall 0.3.5", +] + [[package]] name = "ordered-float" version = "2.10.0" @@ -5182,7 +5354,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml", + "toml 0.5.11", ] [[package]] @@ -5287,7 +5459,7 @@ dependencies = [ "terminal", "text", "thiserror", - "toml", + "toml 0.5.11", "unindent", "util", ] @@ -6623,6 +6795,15 @@ dependencies = [ "syn 2.0.27", ] +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -6669,7 +6850,7 @@ dependencies = [ "smallvec", "sqlez", "staff_mode", - "toml", + "toml 0.5.11", "tree-sitter", "tree-sitter-json 0.19.0", "unindent", @@ -6855,6 +7036,15 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + [[package]] name = "sluice" version = "0.5.5" @@ -6899,6 +7089,15 @@ dependencies = [ "pin-project-lite 0.1.12", ] +[[package]] +name = "smol_str" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" +dependencies = [ + "serde", +] + [[package]] name = "snippet" version = "0.1.0" @@ -7502,7 +7701,7 @@ dependencies = [ "serde_derive", "serde_json", "settings", - "toml", + "toml 0.5.11", "util", ] @@ -7817,11 +8016,26 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + [[package]] name = "toml_datetime" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -7830,6 +8044,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap 2.0.0", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] @@ -8589,6 +8805,12 @@ dependencies = [ "workspace", ] +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.4" @@ -8627,10 +8849,12 @@ dependencies = [ [[package]] name = "vte" -version = "0.10.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" +checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197" dependencies = [ + "log", + "serde", "utf8parse", "vte_generate_state_changes", ] @@ -8863,7 +9087,7 @@ dependencies = [ "rustix 0.33.7", "serde", "sha2 0.9.9", - "toml", + "toml 0.5.11", "winapi 0.3.9", "zstd", ] @@ -9051,6 +9275,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19353897b48e2c4d849a2d73cb0aeb16dc2be4e00c565abfc11eb65a806e47de" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", +] + [[package]] name = "webpki" version = "0.21.4" @@ -9366,6 +9601,42 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "winit" +version = "0.29.0-beta.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f1afaf8490cc3f1309520ebb53a4cd3fc3642c7df8064a4b074bb9867998d44" +dependencies = [ + "android-activity", + "atomic-waker", + "bitflags 2.3.3", + "calloop", + "cfg_aliases", + "core-foundation", + "core-graphics", + "cursor-icon", + "dispatch", + "js-sys", + "libc", + "log", + "ndk", + "ndk-sys", + "objc2", + "once_cell", + "orbclient", + "raw-window-handle", + "redox_syscall 0.3.5", + "serde", + "smol_str", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "web-time", + "windows-sys", + "xkbcommon-dl", +] + [[package]] name = "winnow" version = "0.5.1" @@ -9483,6 +9754,25 @@ dependencies = [ "libc", ] +[[package]] +name = "xkbcommon-dl" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6924668544c48c0133152e7eec86d644a056ca3d09275eb8d5cdb9855f9d8699" +dependencies = [ + "bitflags 2.3.3", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" + [[package]] name = "xmlparser" version = "0.13.5" @@ -9618,7 +9908,7 @@ dependencies = [ "theme_selector", "thiserror", "tiny_http", - "toml", + "toml 0.5.11", "tree-sitter", "tree-sitter-bash", "tree-sitter-c", diff --git a/crates/terminal/Cargo.toml b/crates/terminal/Cargo.toml index a2902234c5fc2909b9974de0beba72b2bc973d64..fbcf0ec4b9e57267a55d8a6d5a7dee490ba403a9 100644 --- a/crates/terminal/Cargo.toml +++ b/crates/terminal/Cargo.toml @@ -16,7 +16,7 @@ db = { path = "../db" } theme = { path = "../theme" } util = { path = "../util" } -alacritty_terminal = { git = "https://github.com/zed-industries/alacritty", rev = "a51dbe25d67e84d6ed4261e640d3954fbdd9be45" } +alacritty_terminal = { git = "https://github.com/alacritty/alacritty", rev = "7b9f32300ee0a249c0872302c97635b460e45ba5" } procinfo = { git = "https://github.com/zed-industries/wezterm", rev = "5cd757e5f2eb039ed0c6bb6512223e69d5efc64d", default-features = false } smallvec.workspace = true smol.workspace = true diff --git a/crates/terminal/src/mappings/colors.rs b/crates/terminal/src/mappings/colors.rs index 3f776251b52693893f58eb6868a53ad995f5ab84..5f34327ea0370e2621274a99cfc249fc6d3f0e5b 100644 --- a/crates/terminal/src/mappings/colors.rs +++ b/crates/terminal/src/mappings/colors.rs @@ -114,11 +114,7 @@ fn rgb_for_index(i: &u8) -> (u8, u8, u8) { //Convenience method to convert from a GPUI color to an alacritty Rgb pub fn to_alac_rgb(color: Color) -> AlacRgb { - AlacRgb { - r: color.r, - g: color.g, - b: color.g, - } + AlacRgb::new(color.r, color.g, color.g) } #[cfg(test)] From 85f193dd09a099741cfb2c527c925cc20f0b9f6b Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 27 Jul 2023 12:25:53 -0400 Subject: [PATCH 066/160] Extract syntax highlighting properties from tree-sitter highlight queries --- crates/zed/src/languages/lua/highlights.scm | 4 +- crates/zed/src/languages/php/highlights.scm | 4 +- .../src/languages/typescript/highlights.scm | 6 +- styles/src/style_tree/editor.ts | 30 +- styles/src/theme/create_theme.ts | 11 +- styles/src/theme/syntax.ts | 382 +++--------------- styles/src/theme/theme_config.ts | 4 +- styles/src/theme/tokens/theme.ts | 6 +- styles/src/themes/atelier/common.ts | 5 +- styles/src/themes/ayu/common.ts | 6 +- styles/src/themes/gruvbox/gruvbox-common.ts | 6 +- styles/src/themes/one/one-dark.ts | 4 +- styles/src/themes/one/one-light.ts | 2 - styles/src/themes/rose-pine/common.ts | 4 +- styles/src/types/extract_syntax_types.ts | 102 +++++ styles/src/types/syntax.ts | 203 ++++++++++ 16 files changed, 419 insertions(+), 360 deletions(-) create mode 100644 styles/src/types/extract_syntax_types.ts create mode 100644 styles/src/types/syntax.ts diff --git a/crates/zed/src/languages/lua/highlights.scm b/crates/zed/src/languages/lua/highlights.scm index f061bbf8f91651605a7bcf946dcb576a82045aa6..60ca9de36b15098e9c76eaddff20238d5056adea 100644 --- a/crates/zed/src/languages/lua/highlights.scm +++ b/crates/zed/src/languages/lua/highlights.scm @@ -158,7 +158,7 @@ [ "{" "}" -] @constructor) +] @method.constructor) ;; Functions @@ -195,4 +195,4 @@ (number) @number -(string) @string \ No newline at end of file +(string) @string diff --git a/crates/zed/src/languages/php/highlights.scm b/crates/zed/src/languages/php/highlights.scm index fcb087c47d14dbc036ed79a50be7ff1b57ebc4e8..cfb03cbccad037d207ff1a1388c12eec22644f48 100644 --- a/crates/zed/src/languages/php/highlights.scm +++ b/crates/zed/src/languages/php/highlights.scm @@ -47,8 +47,8 @@ ((name) @constant.builtin (#match? @constant.builtin "^__[A-Z][A-Z\d_]+__$")) -((name) @constructor - (#match? @constructor "^[A-Z]")) +((name) @method.constructor +(#match? @method.constructor "^[A-Z]")) ((name) @variable.builtin (#eq? @variable.builtin "this")) diff --git a/crates/zed/src/languages/typescript/highlights.scm b/crates/zed/src/languages/typescript/highlights.scm index bf086ea156f6ee9c2aca6bb9d2ebdd3f91997999..ba6b329e0e0def9c5d0c31d0df94525825ed2c45 100644 --- a/crates/zed/src/languages/typescript/highlights.scm +++ b/crates/zed/src/languages/typescript/highlights.scm @@ -43,8 +43,8 @@ ; Special identifiers -((identifier) @constructor - (#match? @constructor "^[A-Z]")) +((identifier) @method.constructor + (#match? @method.constructor "^[A-Z]")) ((identifier) @type (#match? @type "^[A-Z]")) @@ -218,4 +218,4 @@ "type" "readonly" "override" -] @keyword \ No newline at end of file +] @keyword diff --git a/styles/src/style_tree/editor.ts b/styles/src/style_tree/editor.ts index acf983e8bee13f24d2897191c283217e1ee2ee55..ccbb33e21dd8459f665531b9b4b19af8831946bd 100644 --- a/styles/src/style_tree/editor.ts +++ b/styles/src/style_tree/editor.ts @@ -9,9 +9,9 @@ import { } from "./components" import hover_popover from "./hover_popover" -import { build_syntax } from "../theme/syntax" import { interactive, toggleable } from "../element" import { useTheme } from "../theme" +import chroma from "chroma-js" export default function editor(): any { const theme = useTheme() @@ -48,16 +48,28 @@ export default function editor(): any { } } - const syntax = build_syntax() - return { - text_color: syntax.primary.color, + text_color: theme.syntax.primary.color, background: background(layer), active_line_background: with_opacity(background(layer, "on"), 0.75), highlighted_line_background: background(layer, "on"), // Inline autocomplete suggestions, Co-pilot suggestions, etc. - hint: syntax.hint, - suggestion: syntax.predictive, + hint: chroma + .mix( + theme.ramps.neutral(0.6).hex(), + theme.ramps.blue(0.4).hex(), + 0.45, + "lch" + ) + .hex(), + suggestion: chroma + .mix( + theme.ramps.neutral(0.4).hex(), + theme.ramps.blue(0.4).hex(), + 0.45, + "lch" + ) + .hex(), code_actions: { indicator: toggleable({ base: interactive({ @@ -255,8 +267,8 @@ export default function editor(): any { invalid_warning_diagnostic: diagnostic(theme.middle, "base"), hover_popover: hover_popover(), link_definition: { - color: syntax.link_uri.color, - underline: syntax.link_uri.underline, + color: theme.syntax.link_uri.color, + underline: theme.syntax.link_uri.underline, }, jump_icon: interactive({ base: { @@ -314,6 +326,6 @@ export default function editor(): any { color: border_color(layer), }, }, - syntax, + syntax: theme.syntax, } } diff --git a/styles/src/theme/create_theme.ts b/styles/src/theme/create_theme.ts index d2701f8341af973a3a4511c149c983cb221fa14d..e52c4dc95b361572d8cbdc388c04146cecc81e8c 100644 --- a/styles/src/theme/create_theme.ts +++ b/styles/src/theme/create_theme.ts @@ -1,12 +1,12 @@ import { Scale, Color } from "chroma-js" -import { Syntax, ThemeSyntax, SyntaxHighlightStyle } from "./syntax" -export { Syntax, ThemeSyntax, SyntaxHighlightStyle } import { ThemeConfig, ThemeAppearance, - ThemeConfigInputColors, + ThemeConfigInputColors } from "./theme_config" import { get_ramps } from "./ramps" +import { syntaxStyle } from "./syntax" +import { Syntax } from "../types/syntax" export interface Theme { name: string @@ -31,7 +31,7 @@ export interface Theme { modal_shadow: Shadow players: Players - syntax?: Partial + syntax: Syntax } export interface Meta { @@ -119,7 +119,6 @@ export function create_theme(theme: ThemeConfig): Theme { name, appearance, input_color, - override: { syntax }, } = theme const is_light = appearance === ThemeAppearance.Light @@ -162,6 +161,8 @@ export function create_theme(theme: ThemeConfig): Theme { "7": player(ramps.yellow), } + const syntax = syntaxStyle(ramps, theme.override.syntax ? theme.override.syntax : {}) + return { name, is_light, diff --git a/styles/src/theme/syntax.ts b/styles/src/theme/syntax.ts index 540a1d0ff9822d5a8c2cf292ddba5ace6839ac6d..d39496a412904647ea2deb8c74048c864ab31550 100644 --- a/styles/src/theme/syntax.ts +++ b/styles/src/theme/syntax.ts @@ -1,332 +1,80 @@ import deepmerge from "deepmerge" -import { FontWeight, font_weights, useTheme } from "../common" -import chroma from "chroma-js" +import { font_weights, ThemeConfigInputSyntax, RampSet } from "../common" +import { Syntax, SyntaxHighlightStyle, allSyntaxKeys } from "../types/syntax" -export interface SyntaxHighlightStyle { - color?: string - weight?: FontWeight - underline?: boolean - italic?: boolean -} - -export interface Syntax { - // == Text Styles ====== / - comment: SyntaxHighlightStyle - // elixir: doc comment - "comment.doc": SyntaxHighlightStyle - primary: SyntaxHighlightStyle - predictive: SyntaxHighlightStyle - hint: SyntaxHighlightStyle - - // === Formatted Text ====== / - emphasis: SyntaxHighlightStyle - "emphasis.strong": SyntaxHighlightStyle - title: SyntaxHighlightStyle - link_uri: SyntaxHighlightStyle - link_text: SyntaxHighlightStyle - /** md: indented_code_block, fenced_code_block, code_span */ - "text.literal": SyntaxHighlightStyle - - // == Punctuation ====== / - punctuation: SyntaxHighlightStyle - /** Example: `(`, `[`, `{`...*/ - "punctuation.bracket": SyntaxHighlightStyle - /**., ;*/ - "punctuation.delimiter": SyntaxHighlightStyle - // js, ts: ${, } in a template literal - // yaml: *, &, ---, ... - "punctuation.special": SyntaxHighlightStyle - // md: list_marker_plus, list_marker_dot, etc - "punctuation.list_marker": SyntaxHighlightStyle - - // == Strings ====== / - - string: SyntaxHighlightStyle - // css: color_value - // js: this, super - // toml: offset_date_time, local_date_time... - "string.special": SyntaxHighlightStyle - // elixir: atom, quoted_atom, keyword, quoted_keyword - // ruby: simple_symbol, delimited_symbol... - "string.special.symbol"?: SyntaxHighlightStyle - // elixir, python, yaml...: escape_sequence - "string.escape"?: SyntaxHighlightStyle - // Regular expressions - "string.regex"?: SyntaxHighlightStyle - - // == Types ====== / - // We allow Function here because all JS objects literals have this property - constructor: SyntaxHighlightStyle | Function // eslint-disable-line @typescript-eslint/ban-types - variant: SyntaxHighlightStyle - type: SyntaxHighlightStyle - // js: predefined_type - "type.builtin"?: SyntaxHighlightStyle - - // == Values - variable: SyntaxHighlightStyle - // this, ... - // css: -- (var(--foo)) - // lua: self - "variable.special"?: SyntaxHighlightStyle - // c: statement_identifier, - label: SyntaxHighlightStyle - // css: tag_name, nesting_selector, universal_selector... - tag: SyntaxHighlightStyle - // css: attribute, pseudo_element_selector (tag_name), - attribute: SyntaxHighlightStyle - // css: class_name, property_name, namespace_name... - property: SyntaxHighlightStyle - // true, false, null, nullptr - constant: SyntaxHighlightStyle - // css: @media, @import, @supports... - // js: declare, implements, interface, keyof, public... - keyword: SyntaxHighlightStyle - // note: js enum is currently defined as a keyword - enum: SyntaxHighlightStyle - // -, --, ->, !=, &&, ||, <=... - operator: SyntaxHighlightStyle - number: SyntaxHighlightStyle - boolean: SyntaxHighlightStyle - // elixir: __MODULE__, __DIR__, __ENV__, etc - // go: nil, iota - "constant.builtin"?: SyntaxHighlightStyle - - // == Functions ====== / - - function: SyntaxHighlightStyle - // lua: assert, error, loadfile, tostring, unpack... - "function.builtin"?: SyntaxHighlightStyle - // go: call_expression, method_declaration - // js: call_expression, method_definition, pair (key, arrow function) - // rust: function_item name: (identifier) - "function.definition"?: SyntaxHighlightStyle - // rust: macro_definition name: (identifier) - "function.special.definition"?: SyntaxHighlightStyle - "function.method"?: SyntaxHighlightStyle - // ruby: identifier/"defined?" // Nate note: I don't fully understand this one. - "function.method.builtin"?: SyntaxHighlightStyle - - // == Unsorted ====== / - // lua: hash_bang_line - preproc: SyntaxHighlightStyle - // elixir, python: interpolation (ex: foo in ${foo}) - // js: template_substitution - embedded: SyntaxHighlightStyle -} - -export type ThemeSyntax = Partial +// Apply defaults to any missing syntax properties that are not defined manually +function apply_defaults(ramps: RampSet, syntax_highlights: Partial): Syntax { + const restKeys: (keyof Syntax)[] = allSyntaxKeys.filter(key => !syntax_highlights[key]) -const default_syntax_highlight_style: Omit = { - weight: "normal", - underline: false, - italic: false, -} - -function build_default_syntax(): Syntax { - const theme = useTheme() + const completeSyntax: Syntax = {} as Syntax - // Make a temporary object that is allowed to be missing - // the "color" property for each style - const syntax: { - [key: string]: Omit - } = {} + const defaults: SyntaxHighlightStyle = { + color: ramps.neutral(1).hex(), + } - // then spread the default to each style - for (const key of Object.keys({} as Syntax)) { - syntax[key as keyof Syntax] = { - ...default_syntax_highlight_style, + for (const key of restKeys) { + { + completeSyntax[key] = { + ...defaults, + } } } - // Mix the neutral and blue colors to get a - // predictive color distinct from any other color in the theme - const predictive = chroma - .mix( - theme.ramps.neutral(0.4).hex(), - theme.ramps.blue(0.4).hex(), - 0.45, - "lch" - ) - .hex() - // Mix the neutral and green colors to get a - // hint color distinct from any other color in the theme - const hint = chroma - .mix( - theme.ramps.neutral(0.6).hex(), - theme.ramps.blue(0.4).hex(), - 0.45, - "lch" - ) - .hex() + const mergedBaseSyntax = Object.assign(completeSyntax, syntax_highlights) - const color = { - primary: theme.ramps.neutral(1).hex(), - comment: theme.ramps.neutral(0.71).hex(), - punctuation: theme.ramps.neutral(0.86).hex(), - predictive: predictive, - hint: hint, - emphasis: theme.ramps.blue(0.5).hex(), - string: theme.ramps.orange(0.5).hex(), - function: theme.ramps.yellow(0.5).hex(), - type: theme.ramps.cyan(0.5).hex(), - constructor: theme.ramps.blue(0.5).hex(), - variant: theme.ramps.blue(0.5).hex(), - property: theme.ramps.blue(0.5).hex(), - enum: theme.ramps.orange(0.5).hex(), - operator: theme.ramps.orange(0.5).hex(), - number: theme.ramps.green(0.5).hex(), - boolean: theme.ramps.green(0.5).hex(), - constant: theme.ramps.green(0.5).hex(), - keyword: theme.ramps.blue(0.5).hex(), - } - - // Then assign colors and use Syntax to enforce each style getting it's own color - const default_syntax: Syntax = { - ...syntax, - comment: { - color: color.comment, - }, - "comment.doc": { - color: color.comment, - }, - primary: { - color: color.primary, - }, - predictive: { - color: color.predictive, - italic: true, - }, - hint: { - color: color.hint, - weight: font_weights.bold, - }, - emphasis: { - color: color.emphasis, - }, - "emphasis.strong": { - color: color.emphasis, - weight: font_weights.bold, - }, - title: { - color: color.primary, - weight: font_weights.bold, - }, - link_uri: { - color: theme.ramps.green(0.5).hex(), - underline: true, - }, - link_text: { - color: theme.ramps.orange(0.5).hex(), - italic: true, - }, - "text.literal": { - color: color.string, - }, - punctuation: { - color: color.punctuation, - }, - "punctuation.bracket": { - color: color.punctuation, - }, - "punctuation.delimiter": { - color: color.punctuation, - }, - "punctuation.special": { - color: theme.ramps.neutral(0.86).hex(), - }, - "punctuation.list_marker": { - color: color.punctuation, - }, - string: { - color: color.string, - }, - "string.special": { - color: color.string, - }, - "string.special.symbol": { - color: color.string, - }, - "string.escape": { - color: color.comment, - }, - "string.regex": { - color: color.string, - }, - constructor: { - color: theme.ramps.blue(0.5).hex(), - }, - variant: { - color: theme.ramps.blue(0.5).hex(), - }, - type: { - color: color.type, - }, - variable: { - color: color.primary, - }, - label: { - color: theme.ramps.blue(0.5).hex(), - }, - tag: { - color: theme.ramps.blue(0.5).hex(), - }, - attribute: { - color: theme.ramps.blue(0.5).hex(), - }, - property: { - color: theme.ramps.blue(0.5).hex(), - }, - constant: { - color: color.constant, - }, - keyword: { - color: color.keyword, - }, - enum: { - color: color.enum, - }, - operator: { - color: color.operator, - }, - number: { - color: color.number, - }, - boolean: { - color: color.boolean, - }, - function: { - color: color.function, - }, - preproc: { - color: color.primary, - }, - embedded: { - color: color.primary, - }, - } - - return default_syntax + return mergedBaseSyntax } -export function build_syntax(): Syntax { - const theme = useTheme() - - const default_syntax: Syntax = build_default_syntax() +// Merge the base syntax with the theme syntax overrides +// This is a deep merge, so any nested properties will be merged as well +// This allows for a theme to only override a single property of a syntax highlight style +const merge_syntax = (baseSyntax: Syntax, theme_syntax_overrides: ThemeConfigInputSyntax): Syntax => { + return deepmerge(baseSyntax, theme_syntax_overrides, { + arrayMerge: (destinationArray, sourceArray) => [ + ...destinationArray, + ...sourceArray, + ], + }) +} - if (!theme.syntax) { - return default_syntax +/** Returns a complete Syntax object of the combined styles of a theme's syntax overrides and the default syntax styles */ +export const syntaxStyle = (ramps: RampSet, theme_syntax_overrides: ThemeConfigInputSyntax): Syntax => { + const syntax_highlights: Partial = { + "comment": { color: ramps.neutral(0.71).hex() }, + "comment.doc": { color: ramps.neutral(0.71).hex() }, + primary: { color: ramps.neutral(1).hex() }, + emphasis: { color: ramps.blue(0.5).hex() }, + "emphasis.strong": { color: ramps.blue(0.5).hex(), weight: font_weights.bold }, + link_uri: { color: ramps.green(0.5).hex(), underline: true }, + link_text: { color: ramps.orange(0.5).hex(), italic: true }, + "text.literal": { color: ramps.orange(0.5).hex() }, + punctuation: { color: ramps.neutral(0.86).hex() }, + "punctuation.bracket": { color: ramps.neutral(0.86).hex() }, + "punctuation.special": { color: ramps.neutral(0.86).hex() }, + "punctuation.delimiter": { color: ramps.neutral(0.86).hex() }, + "punctuation.list_marker": { color: ramps.neutral(0.86).hex() }, + string: { color: ramps.orange(0.5).hex() }, + "string.special": { color: ramps.orange(0.5).hex() }, + "string.special.symbol": { color: ramps.orange(0.5).hex() }, + "string.escape": { color: ramps.neutral(0.71).hex() }, + "string.regex": { color: ramps.orange(0.5).hex() }, + "method.constructor": { color: ramps.blue(0.5).hex() }, + type: { color: ramps.cyan(0.5).hex() }, + variable: { color: ramps.neutral(1).hex() }, + label: { color: ramps.blue(0.5).hex() }, + attribute: { color: ramps.blue(0.5).hex() }, + property: { color: ramps.blue(0.5).hex() }, + constant: { color: ramps.green(0.5).hex() }, + keyword: { color: ramps.blue(0.5).hex() }, + operator: { color: ramps.orange(0.5).hex() }, + number: { color: ramps.green(0.5).hex() }, + boolean: { color: ramps.green(0.5).hex() }, + function: { color: ramps.yellow(0.5).hex() }, + preproc: { color: ramps.neutral(1).hex() }, + embedded: { color: ramps.neutral(1).hex() }, } - const syntax = deepmerge>( - default_syntax, - theme.syntax, - { - arrayMerge: (destinationArray, sourceArray) => [ - ...destinationArray, - ...sourceArray, - ], - } - ) - - return syntax + const baseSyntax = apply_defaults(ramps, syntax_highlights) + const mergedSyntax = merge_syntax(baseSyntax, theme_syntax_overrides) + return mergedSyntax } diff --git a/styles/src/theme/theme_config.ts b/styles/src/theme/theme_config.ts index bc8f07425f9e676a27d36ec929ea9a116006c694..8473bbb600608cac6157f894f3e9ac5d91c31a31 100644 --- a/styles/src/theme/theme_config.ts +++ b/styles/src/theme/theme_config.ts @@ -1,5 +1,5 @@ import { Scale, Color } from "chroma-js" -import { Syntax } from "./syntax" +import { SyntaxHighlightStyle, SyntaxProperty } from "../types/syntax" interface ThemeMeta { /** The name of the theme */ @@ -55,7 +55,7 @@ export type ThemeConfigInputColorsKeys = keyof ThemeConfigInputColors * } * ``` */ -export type ThemeConfigInputSyntax = Partial +export type ThemeConfigInputSyntax = Partial>> interface ThemeConfigOverrides { syntax: ThemeConfigInputSyntax diff --git a/styles/src/theme/tokens/theme.ts b/styles/src/theme/tokens/theme.ts index f759bc813910416d88a2097134dc95654d6ab3b3..f9e83e0512012e0c5d699ac432869a70520a9839 100644 --- a/styles/src/theme/tokens/theme.ts +++ b/styles/src/theme/tokens/theme.ts @@ -6,15 +6,13 @@ import { } from "@tokens-studio/types" import { Shadow, - SyntaxHighlightStyle, - ThemeSyntax, } from "../create_theme" import { LayerToken, layer_token } from "./layer" import { PlayersToken, players_token } from "./players" import { color_token } from "./token" -import { Syntax } from "../syntax" import editor from "../../style_tree/editor" import { useTheme } from "../../../src/common" +import { Syntax, SyntaxHighlightStyle } from "../../types/syntax" interface ThemeTokens { name: SingleOtherToken @@ -51,7 +49,7 @@ const modal_shadow_token = (): SingleBoxShadowToken => { return create_shadow_token(shadow, "modal_shadow") } -type ThemeSyntaxColorTokens = Record +type ThemeSyntaxColorTokens = Record function syntax_highlight_style_color_tokens( syntax: Syntax diff --git a/styles/src/themes/atelier/common.ts b/styles/src/themes/atelier/common.ts index b76ccc5b607a2f149a35114a519ddaaf2d1b254d..09226b336c0aae3d42a4e99130e1c46875d6065b 100644 --- a/styles/src/themes/atelier/common.ts +++ b/styles/src/themes/atelier/common.ts @@ -1,4 +1,4 @@ -import { ThemeLicenseType, ThemeSyntax, ThemeFamilyMeta } from "../../common" +import { ThemeLicenseType, ThemeFamilyMeta, ThemeConfigInputSyntax } from "../../common" export interface Variant { colors: { @@ -29,7 +29,7 @@ export const meta: ThemeFamilyMeta = { "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/", } -export const build_syntax = (variant: Variant): ThemeSyntax => { +export const build_syntax = (variant: Variant): ThemeConfigInputSyntax => { const { colors } = variant return { primary: { color: colors.base06 }, @@ -50,7 +50,6 @@ export const build_syntax = (variant: Variant): ThemeSyntax => { property: { color: colors.base08 }, variable: { color: colors.base06 }, "variable.special": { color: colors.base0E }, - variant: { color: colors.base0A }, keyword: { color: colors.base0E }, } } diff --git a/styles/src/themes/ayu/common.ts b/styles/src/themes/ayu/common.ts index 2bd0bbf259aef2d9fc6c084f1da3c72379927026..870445588646b57f347fe9e90e07b286b3b73790 100644 --- a/styles/src/themes/ayu/common.ts +++ b/styles/src/themes/ayu/common.ts @@ -3,8 +3,8 @@ import { chroma, color_ramp, ThemeLicenseType, - ThemeSyntax, ThemeFamilyMeta, + ThemeConfigInputSyntax, } from "../../common" export const ayu = { @@ -27,7 +27,7 @@ export const build_theme = (t: typeof dark, light: boolean) => { purple: t.syntax.constant.hex(), } - const syntax: ThemeSyntax = { + const syntax: ThemeConfigInputSyntax = { constant: { color: t.syntax.constant.hex() }, "string.regex": { color: t.syntax.regexp.hex() }, string: { color: t.syntax.string.hex() }, @@ -61,7 +61,7 @@ export const build_theme = (t: typeof dark, light: boolean) => { } } -export const build_syntax = (t: typeof dark): ThemeSyntax => { +export const build_syntax = (t: typeof dark): ThemeConfigInputSyntax => { return { constant: { color: t.syntax.constant.hex() }, "string.regex": { color: t.syntax.regexp.hex() }, diff --git a/styles/src/themes/gruvbox/gruvbox-common.ts b/styles/src/themes/gruvbox/gruvbox-common.ts index 2fa6b58faadb91b5689c5eac93baf706f6faa391..95e45efa95122ec3ca37d2dc57360ca55ec83e85 100644 --- a/styles/src/themes/gruvbox/gruvbox-common.ts +++ b/styles/src/themes/gruvbox/gruvbox-common.ts @@ -4,8 +4,8 @@ import { ThemeAppearance, ThemeLicenseType, ThemeConfig, - ThemeSyntax, ThemeFamilyMeta, + ThemeConfigInputSyntax, } from "../../common" const meta: ThemeFamilyMeta = { @@ -214,7 +214,7 @@ const build_variant = (variant: Variant): ThemeConfig => { magenta: color_ramp(chroma(variant.colors.gray)), } - const syntax: ThemeSyntax = { + const syntax: ThemeConfigInputSyntax = { primary: { color: neutral[is_light ? 0 : 8] }, "text.literal": { color: colors.blue }, comment: { color: colors.gray }, @@ -229,7 +229,7 @@ const build_variant = (variant: Variant): ThemeConfig => { "string.special.symbol": { color: colors.aqua }, "string.regex": { color: colors.orange }, type: { color: colors.yellow }, - enum: { color: colors.orange }, + // enum: { color: colors.orange }, tag: { color: colors.aqua }, constant: { color: colors.yellow }, keyword: { color: colors.red }, diff --git a/styles/src/themes/one/one-dark.ts b/styles/src/themes/one/one-dark.ts index f672b892ee040e60745f3d0f8bd6875c743ed46a..97f3922f36f57c7452c8face077a8b2bc8997858 100644 --- a/styles/src/themes/one/one-dark.ts +++ b/styles/src/themes/one/one-dark.ts @@ -54,7 +54,6 @@ export const theme: ThemeConfig = { syntax: { boolean: { color: color.orange }, comment: { color: color.grey }, - enum: { color: color.red }, "emphasis.strong": { color: color.orange }, function: { color: color.blue }, keyword: { color: color.purple }, @@ -73,8 +72,7 @@ export const theme: ThemeConfig = { "text.literal": { color: color.green }, type: { color: color.teal }, "variable.special": { color: color.orange }, - variant: { color: color.blue }, - constructor: { color: color.blue }, + "method.constructor": { color: color.blue }, }, }, } diff --git a/styles/src/themes/one/one-light.ts b/styles/src/themes/one/one-light.ts index c3de7826c96679fb1c1f2b1a9d81324687d919b9..655428757898a7f07f4524377721ab62ef1f5b53 100644 --- a/styles/src/themes/one/one-light.ts +++ b/styles/src/themes/one/one-light.ts @@ -55,7 +55,6 @@ export const theme: ThemeConfig = { syntax: { boolean: { color: color.orange }, comment: { color: color.grey }, - enum: { color: color.red }, "emphasis.strong": { color: color.orange }, function: { color: color.blue }, keyword: { color: color.purple }, @@ -73,7 +72,6 @@ export const theme: ThemeConfig = { "text.literal": { color: color.green }, type: { color: color.teal }, "variable.special": { color: color.orange }, - variant: { color: color.blue }, }, }, } diff --git a/styles/src/themes/rose-pine/common.ts b/styles/src/themes/rose-pine/common.ts index 5c5482a754a634bd2338af2613327554ec36d13c..decccc0a6dc8b1062ec8d5a88a699350a79bf322 100644 --- a/styles/src/themes/rose-pine/common.ts +++ b/styles/src/themes/rose-pine/common.ts @@ -1,4 +1,4 @@ -import { ThemeSyntax } from "../../common" +import { ThemeConfigInputSyntax } from "../../common" export const color = { default: { @@ -54,7 +54,7 @@ export const color = { }, } -export const syntax = (c: typeof color.default): Partial => { +export const syntax = (c: typeof color.default): ThemeConfigInputSyntax => { return { comment: { color: c.muted }, operator: { color: c.pine }, diff --git a/styles/src/types/extract_syntax_types.ts b/styles/src/types/extract_syntax_types.ts new file mode 100644 index 0000000000000000000000000000000000000000..3bf089518233a8b264e71853ad83e2634f9c1ab3 --- /dev/null +++ b/styles/src/types/extract_syntax_types.ts @@ -0,0 +1,102 @@ +import fs from 'fs' +import path from 'path' +import readline from 'readline' + +function escapeTypeName(name: string): string { + return `'${name.replace('@', '').toLowerCase()}'` +} + +const generatedNote = `// This file is generated by extract_syntax_types.ts +// Do not edit this file directly +// It is generated from the highlight.scm files in the zed crate + +// To regenerate this file manually: +// 'npm run extract-syntax-types' from ./styles` + +const defaultTextProperty = ` /** Default text color */ + | 'primary'` + +const main = async () => { + const pathFromRoot = 'crates/zed/src/languages' + const directoryPath = path.join(__dirname, '../../../', pathFromRoot) + const stylesMap: Record> = {} + const propertyLanguageMap: Record> = {} + + const processFile = async (filePath: string, language: string) => { + const fileStream = fs.createReadStream(filePath) + const rl = readline.createInterface({ + input: fileStream, + crlfDelay: Infinity, + }) + + for await (const line of rl) { + const cleanedLine = line.replace(/"@[a-zA-Z0-9_.]*"/g, "") + const match = cleanedLine.match(/@(\w+\.*)*/g) + if (match) { + match.forEach((property) => { + const formattedProperty = escapeTypeName(property) + // Only add non-empty properties + if (formattedProperty !== "''") { + if (!propertyLanguageMap[formattedProperty]) { + propertyLanguageMap[formattedProperty] = new Set() + } + propertyLanguageMap[formattedProperty].add(language) + } + }) + } + } + } + + const directories = fs.readdirSync(directoryPath, { withFileTypes: true }) + .filter(dirent => dirent.isDirectory()) + .map(dirent => dirent.name) + + for (const dir of directories) { + const highlightsFilePath = path.join(directoryPath, dir, 'highlights.scm') + if (fs.existsSync(highlightsFilePath)) { + await processFile(highlightsFilePath, dir) + } + } + + for (const [language, properties] of Object.entries(stylesMap)) { + console.log(`${language}: ${Array.from(properties).join(', ')}`) + } + + const sortedProperties = Object.entries(propertyLanguageMap).sort(([propA], [propB]) => propA.localeCompare(propB)) + + const outStream = fs.createWriteStream(path.join(__dirname, 'syntax.ts')) + let allProperties = "" + const syntaxKeys = [] + for (const [property, languages] of sortedProperties) { + let languagesArray = Array.from(languages) + const moreThanSeven = languagesArray.length > 7 + // Limit to the first 7 languages, append "..." if more than 7 + languagesArray = languagesArray.slice(0, 7) + if (moreThanSeven) { + languagesArray.push('...') + } + const languagesString = languagesArray.join(', ') + const comment = `/** ${languagesString} */` + allProperties += ` ${comment}\n | ${property} \n` + syntaxKeys.push(property) + } + outStream.write(`${generatedNote} + +export type SyntaxHighlightStyle = { + color: string, + fade_out?: number, + italic?: boolean, + underline?: boolean, + weight?: string, +} + +export type Syntax = Record +export type SyntaxOverride = Partial + +export type SyntaxProperty = \n${defaultTextProperty}\n\n${allProperties} + +export const allSyntaxKeys: SyntaxProperty[] = [\n ${syntaxKeys.join(',\n ')}\n]`) + outStream.end() +} + +main().catch(console.error) diff --git a/styles/src/types/syntax.ts b/styles/src/types/syntax.ts new file mode 100644 index 0000000000000000000000000000000000000000..b74edfdf8463e510c40fee84c35e5d22d6586d83 --- /dev/null +++ b/styles/src/types/syntax.ts @@ -0,0 +1,203 @@ +// This file is generated by extract_syntax_types.ts +// Do not edit this file directly +// It is generated from the highlight.scm files in the zed crate + +// To regenerate this file manually: +// 'npm run extract-syntax-types' from ./styles + +export type SyntaxHighlightStyle = { + color: string, + fade_out?: number, + italic?: boolean, + underline?: boolean, + weight?: string, +} + +export type Syntax = Record +export type SyntaxOverride = Partial + +export type SyntaxProperty = + /** Default text color */ + | 'primary' + + /** elixir */ + | '__attribute__' + /** elixir */ + | '__name__' + /** elixir */ + | '_sigil_name' + /** css, heex, lua */ + | 'attribute' + /** javascript, lua, tsx, typescript, yaml */ + | 'boolean' + /** elixir */ + | 'comment.doc' + /** elixir */ + | 'comment.unused' + /** bash, c, cpp, css, elixir, elm, erb, ... */ + | 'comment' + /** elixir, go, javascript, lua, php, python, racket, ... */ + | 'constant.builtin' + /** bash, c, cpp, elixir, elm, glsl, heex, ... */ + | 'constant' + /** glsl */ + | 'delimiter' + /** bash, elixir, javascript, python, ruby, tsx, typescript */ + | 'embedded' + /** markdown */ + | 'emphasis.strong' + /** markdown */ + | 'emphasis' + /** go, python, racket, ruby, scheme */ + | 'escape' + /** lua */ + | 'field' + /** lua, php, python */ + | 'function.builtin' + /** elm, lua, rust */ + | 'function.definition' + /** ruby */ + | 'function.method.builtin' + /** go, javascript, php, python, ruby, rust, tsx, ... */ + | 'function.method' + /** rust */ + | 'function.special.definition' + /** c, cpp, glsl, rust */ + | 'function.special' + /** bash, c, cpp, css, elixir, elm, glsl, ... */ + | 'function' + /** elm */ + | 'identifier' + /** glsl */ + | 'keyword.function' + /** bash, c, cpp, css, elixir, elm, erb, ... */ + | 'keyword' + /** c, cpp, glsl */ + | 'label' + /** markdown */ + | 'link_text' + /** markdown */ + | 'link_uri' + /** lua, php, tsx, typescript */ + | 'method.constructor' + /** lua */ + | 'method' + /** heex */ + | 'module' + /** svelte */ + | 'none' + /** bash, c, cpp, css, elixir, glsl, go, ... */ + | 'number' + /** bash, c, cpp, css, elixir, elm, glsl, ... */ + | 'operator' + /** lua */ + | 'parameter' + /** lua */ + | 'preproc' + /** bash, c, cpp, css, glsl, go, html, ... */ + | 'property' + /** c, cpp, elixir, elm, heex, html, javascript, ... */ + | 'punctuation.bracket' + /** c, cpp, css, elixir, elm, heex, javascript, ... */ + | 'punctuation.delimiter' + /** markdown */ + | 'punctuation.list_marker' + /** elixir, javascript, python, ruby, tsx, typescript, yaml */ + | 'punctuation.special' + /** elixir */ + | 'punctuation' + /** glsl */ + | 'storageclass' + /** elixir, elm, yaml */ + | 'string.escape' + /** elixir, javascript, racket, ruby, tsx, typescript */ + | 'string.regex' + /** elixir, ruby */ + | 'string.special.symbol' + /** css, elixir, toml */ + | 'string.special' + /** bash, c, cpp, css, elixir, elm, glsl, ... */ + | 'string' + /** svelte */ + | 'tag.delimiter' + /** css, heex, php, svelte */ + | 'tag' + /** markdown */ + | 'text.literal' + /** markdown */ + | 'title' + /** javascript, php, rust, tsx, typescript */ + | 'type.builtin' + /** glsl */ + | 'type.qualifier' + /** c, cpp, css, elixir, elm, glsl, go, ... */ + | 'type' + /** glsl, php */ + | 'variable.builtin' + /** cpp, css, javascript, lua, racket, ruby, rust, ... */ + | 'variable.special' + /** c, cpp, elm, glsl, go, javascript, lua, ... */ + | 'variable' + + +export const allSyntaxKeys: SyntaxProperty[] = [ + '__attribute__', + '__name__', + '_sigil_name', + 'attribute', + 'boolean', + 'comment.doc', + 'comment.unused', + 'comment', + 'constant.builtin', + 'constant', + 'delimiter', + 'embedded', + 'emphasis.strong', + 'emphasis', + 'escape', + 'field', + 'function.builtin', + 'function.definition', + 'function.method.builtin', + 'function.method', + 'function.special.definition', + 'function.special', + 'function', + 'identifier', + 'keyword.function', + 'keyword', + 'label', + 'link_text', + 'link_uri', + 'method.constructor', + 'method', + 'module', + 'none', + 'number', + 'operator', + 'parameter', + 'preproc', + 'property', + 'punctuation.bracket', + 'punctuation.delimiter', + 'punctuation.list_marker', + 'punctuation.special', + 'punctuation', + 'storageclass', + 'string.escape', + 'string.regex', + 'string.special.symbol', + 'string.special', + 'string', + 'tag.delimiter', + 'tag', + 'text.literal', + 'title', + 'type.builtin', + 'type.qualifier', + 'type', + 'variable.builtin', + 'variable.special', + 'variable' +] \ No newline at end of file From 86fa27eb54838e69292307c30ac611e0d32993c5 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 27 Jul 2023 12:41:19 -0400 Subject: [PATCH 067/160] Update uses of `#` to `.` in our scheme files where they are interchangeable. uses of `#` cause ERRORs in our scheme highlighting --- crates/zed/src/languages/bash/highlights.scm | 2 +- crates/zed/src/languages/c/highlights.scm | 3 +-- crates/zed/src/languages/c/injections.scm | 4 ++-- crates/zed/src/languages/cpp/highlights.scm | 4 ++-- crates/zed/src/languages/cpp/injections.scm | 4 ++-- crates/zed/src/languages/css/highlights.scm | 2 +- crates/zed/src/languages/elixir/embedding.scm | 6 +++--- crates/zed/src/languages/elixir/highlights.scm | 18 +++++++++--------- crates/zed/src/languages/elixir/injections.scm | 4 ++-- crates/zed/src/languages/elixir/outline.scm | 4 ++-- crates/zed/src/languages/elm/injections.scm | 2 +- crates/zed/src/languages/erb/injections.scm | 8 ++++---- crates/zed/src/languages/glsl/highlights.scm | 4 ++-- crates/zed/src/languages/heex/injections.scm | 6 +++--- crates/zed/src/languages/html/injections.scm | 4 ++-- .../src/languages/javascript/highlights.scm | 6 +++--- crates/zed/src/languages/lua/highlights.scm | 6 +++--- crates/zed/src/languages/php/highlights.scm | 8 ++++---- crates/zed/src/languages/php/injections.scm | 4 ++-- crates/zed/src/languages/python/highlights.scm | 8 ++++---- crates/zed/src/languages/racket/highlights.scm | 7 +++---- crates/zed/src/languages/racket/outline.scm | 4 ++-- crates/zed/src/languages/ruby/brackets.scm | 2 +- crates/zed/src/languages/ruby/highlights.scm | 8 ++++---- crates/zed/src/languages/rust/highlights.scm | 4 ++-- crates/zed/src/languages/rust/injections.scm | 4 ++-- crates/zed/src/languages/scheme/highlights.scm | 4 ++-- crates/zed/src/languages/scheme/outline.scm | 4 ++-- crates/zed/src/languages/svelte/injections.scm | 14 +++++++------- .../src/languages/typescript/highlights.scm | 6 +++--- 30 files changed, 81 insertions(+), 83 deletions(-) diff --git a/crates/zed/src/languages/bash/highlights.scm b/crates/zed/src/languages/bash/highlights.scm index a72c5468edd911b60b31c8ae07041c3f733f3497..f3e0c9529a1d7c19777e40c28f934c0b57e10941 100644 --- a/crates/zed/src/languages/bash/highlights.scm +++ b/crates/zed/src/languages/bash/highlights.scm @@ -54,5 +54,5 @@ ( (command (_) @constant) - (#match? @constant "^-") + (.match? @constant "^-") ) diff --git a/crates/zed/src/languages/c/highlights.scm b/crates/zed/src/languages/c/highlights.scm index 064ec61a378beb00417e6b6716a6f1358daa5cbf..5245e53a052578a62f8d4cddab8141bb0d80d288 100644 --- a/crates/zed/src/languages/c/highlights.scm +++ b/crates/zed/src/languages/c/highlights.scm @@ -86,7 +86,7 @@ (identifier) @variable ((identifier) @constant - (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) + (.match? @constant "^_*[A-Z][A-Z\\d_]*$")) (call_expression function: (identifier) @function) @@ -106,4 +106,3 @@ (primitive_type) (sized_type_specifier) ] @type - diff --git a/crates/zed/src/languages/c/injections.scm b/crates/zed/src/languages/c/injections.scm index 845a63bd1bd4e700df0fd1eb3c5d10d31e2ab0e4..fbc7d83f8211836067a08cf05fae1b7b66170d12 100644 --- a/crates/zed/src/languages/c/injections.scm +++ b/crates/zed/src/languages/c/injections.scm @@ -1,7 +1,7 @@ (preproc_def value: (preproc_arg) @content - (#set! "language" "c")) + (.set! "language" "c")) (preproc_function_def value: (preproc_arg) @content - (#set! "language" "c")) \ No newline at end of file + (.set! "language" "c")) diff --git a/crates/zed/src/languages/cpp/highlights.scm b/crates/zed/src/languages/cpp/highlights.scm index bcfa01ca5c6aca231d444026af94c7f6c6b32f51..a040b1d053cd714a5576c8a6d9f13304c6c1392c 100644 --- a/crates/zed/src/languages/cpp/highlights.scm +++ b/crates/zed/src/languages/cpp/highlights.scm @@ -31,13 +31,13 @@ declarator: (field_identifier) @function) ((namespace_identifier) @type - (#match? @type "^[A-Z]")) + (.match? @type "^[A-Z]")) (auto) @type (type_identifier) @type ((identifier) @constant - (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) + (.match? @constant "^_*[A-Z][A-Z\\d_]*$")) (field_identifier) @property (statement_identifier) @label diff --git a/crates/zed/src/languages/cpp/injections.scm b/crates/zed/src/languages/cpp/injections.scm index eca372d577be30c352a2b7f7d93505a3b869e293..3c94ba4061f6942fd88c7b09279b4f40a1709d14 100644 --- a/crates/zed/src/languages/cpp/injections.scm +++ b/crates/zed/src/languages/cpp/injections.scm @@ -1,7 +1,7 @@ (preproc_def value: (preproc_arg) @content - (#set! "language" "c++")) + (.set! "language" "c++")) (preproc_function_def value: (preproc_arg) @content - (#set! "language" "c++")) \ No newline at end of file + (.set! "language" "c++")) diff --git a/crates/zed/src/languages/css/highlights.scm b/crates/zed/src/languages/css/highlights.scm index e271d8583c661b62f1a0bf5f4c848ca34cdbdc9d..83f99861c59e19b9e60335f2f4cc10231d00e31b 100644 --- a/crates/zed/src/languages/css/highlights.scm +++ b/crates/zed/src/languages/css/highlights.scm @@ -46,7 +46,7 @@ (property_name) (plain_value) ] @variable.special - (#match? @variable.special "^--") + (.match? @variable.special "^--") ) [ diff --git a/crates/zed/src/languages/elixir/embedding.scm b/crates/zed/src/languages/elixir/embedding.scm index 16ad20746d4b0c8697ff126fcc5150636cb8b794..3c523c248767dff3b855f9c623e66e5b3e03a4ae 100644 --- a/crates/zed/src/languages/elixir/embedding.scm +++ b/crates/zed/src/languages/elixir/embedding.scm @@ -3,7 +3,7 @@ operator: "@" operand: (call target: (identifier) @unary - (#match? @unary "^(doc)$")) + (.match? @unary "^(doc)$")) ) @context . (call @@ -18,10 +18,10 @@ target: (identifier) @name) operator: "when") ]) - (#match? @name "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item + (.match? @name "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item ) (call target: (identifier) @name (arguments (alias) @name) - (#match? @name "^(defmodule|defprotocol)$")) @item + (.match? @name "^(defmodule|defprotocol)$")) @item diff --git a/crates/zed/src/languages/elixir/highlights.scm b/crates/zed/src/languages/elixir/highlights.scm index 0e779d195c5e6e03404c783d9675fc223232c84d..a8fd7eb45a6c04de64f1c7aa00fbeeecb535a316 100644 --- a/crates/zed/src/languages/elixir/highlights.scm +++ b/crates/zed/src/languages/elixir/highlights.scm @@ -54,13 +54,13 @@ (sigil_name) @__name__ quoted_start: _ @string quoted_end: _ @string - (#match? @__name__ "^[sS]$")) @string + (.match? @__name__ "^[sS]$")) @string (sigil (sigil_name) @__name__ quoted_start: _ @string.regex quoted_end: _ @string.regex - (#match? @__name__ "^[rR]$")) @string.regex + (.match? @__name__ "^[rR]$")) @string.regex (sigil (sigil_name) @__name__ @@ -69,7 +69,7 @@ ( (identifier) @comment.unused - (#match? @comment.unused "^_") + (.match? @comment.unused "^_") ) (call @@ -91,7 +91,7 @@ operator: "|>" right: (identifier)) ]) - (#match? @keyword "^(def|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp|defp)$")) + (.match? @keyword "^(def|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp|defp)$")) (binary_operator operator: "|>" @@ -99,15 +99,15 @@ (call target: (identifier) @keyword - (#match? @keyword "^(def|defdelegate|defexception|defguard|defguardp|defimpl|defmacro|defmacrop|defmodule|defn|defnp|defoverridable|defp|defprotocol|defstruct)$")) + (.match? @keyword "^(def|defdelegate|defexception|defguard|defguardp|defimpl|defmacro|defmacrop|defmodule|defn|defnp|defoverridable|defp|defprotocol|defstruct)$")) (call target: (identifier) @keyword - (#match? @keyword "^(alias|case|cond|else|for|if|import|quote|raise|receive|require|reraise|super|throw|try|unless|unquote|unquote_splicing|use|with)$")) + (.match? @keyword "^(alias|case|cond|else|for|if|import|quote|raise|receive|require|reraise|super|throw|try|unless|unquote|unquote_splicing|use|with)$")) ( (identifier) @constant.builtin - (#match? @constant.builtin "^(__MODULE__|__DIR__|__ENV__|__CALLER__|__STACKTRACE__)$") + (.match? @constant.builtin "^(__MODULE__|__DIR__|__ENV__|__CALLER__|__STACKTRACE__)$") ) (unary_operator @@ -121,7 +121,7 @@ (sigil) (boolean) ] @comment.doc)) - (#match? @__attribute__ "^(moduledoc|typedoc|doc)$")) + (.match? @__attribute__ "^(moduledoc|typedoc|doc)$")) (comment) @comment @@ -150,4 +150,4 @@ ((sigil (sigil_name) @_sigil_name (quoted_content) @embedded) - (#eq? @_sigil_name "H")) + (.eq? @_sigil_name "H")) diff --git a/crates/zed/src/languages/elixir/injections.scm b/crates/zed/src/languages/elixir/injections.scm index 4de229f1046ca39264ffb23dc98e565bfd74185b..5d445a7b820ed480a9545c638ba6e685be7c244a 100644 --- a/crates/zed/src/languages/elixir/injections.scm +++ b/crates/zed/src/languages/elixir/injections.scm @@ -3,5 +3,5 @@ ((sigil (sigil_name) @_sigil_name (quoted_content) @content) - (#eq? @_sigil_name "H") - (#set! language "heex")) + (.eq? @_sigil_name "H") + (.set! language "heex")) diff --git a/crates/zed/src/languages/elixir/outline.scm b/crates/zed/src/languages/elixir/outline.scm index a3311fb6d4640aa4ff5469c638022c1fde02e912..756d39651039c002ef79ec818ba63aee20523c20 100644 --- a/crates/zed/src/languages/elixir/outline.scm +++ b/crates/zed/src/languages/elixir/outline.scm @@ -1,7 +1,7 @@ (call target: (identifier) @context (arguments (alias) @name) - (#match? @context "^(defmodule|defprotocol)$")) @item + (.match? @context "^(defmodule|defprotocol)$")) @item (call target: (identifier) @context @@ -23,4 +23,4 @@ ")" @context.extra)) operator: "when") ]) - (#match? @context "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item + (.match? @context "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item diff --git a/crates/zed/src/languages/elm/injections.scm b/crates/zed/src/languages/elm/injections.scm index 0567320675a89c6649a191fdef950c6670d65707..3456f59a04af62c95fc26c7cec085123eb8b567d 100644 --- a/crates/zed/src/languages/elm/injections.scm +++ b/crates/zed/src/languages/elm/injections.scm @@ -1,2 +1,2 @@ ((glsl_content) @content - (#set! "language" "glsl")) + (.set! "language" "glsl")) diff --git a/crates/zed/src/languages/erb/injections.scm b/crates/zed/src/languages/erb/injections.scm index 7a69a818ef31d7fa3822466209b08c15280c6f5b..d9801015b7ca1f41f94b8be516f79b4c3c9365f6 100644 --- a/crates/zed/src/languages/erb/injections.scm +++ b/crates/zed/src/languages/erb/injections.scm @@ -1,7 +1,7 @@ ((code) @content - (#set! "language" "ruby") - (#set! "combined")) + (.set! "language" "ruby") + (.set! "combined")) ((content) @content - (#set! "language" "html") - (#set! "combined")) + (.set! "language" "html") + (.set! "combined")) diff --git a/crates/zed/src/languages/glsl/highlights.scm b/crates/zed/src/languages/glsl/highlights.scm index e4503c6fbba298afb1f2eddb82ce960af74b03c0..2378b8449b594d883ba19a0e5515369f5725522f 100644 --- a/crates/zed/src/languages/glsl/highlights.scm +++ b/crates/zed/src/languages/glsl/highlights.scm @@ -74,7 +74,7 @@ (sized_type_specifier) @type ((identifier) @constant - (#match? @constant "^[A-Z][A-Z\\d_]*$")) + (.match? @constant "^[A-Z][A-Z\\d_]*$")) (identifier) @variable @@ -114,5 +114,5 @@ ( (identifier) @variable.builtin - (#match? @variable.builtin "^gl_") + (.match? @variable.builtin "^gl_") ) diff --git a/crates/zed/src/languages/heex/injections.scm b/crates/zed/src/languages/heex/injections.scm index b503bcb28dc10911b9e57e74f7217a21ece549fb..1b63005cbfa02189e19a6a202c5beea0112c0946 100644 --- a/crates/zed/src/languages/heex/injections.scm +++ b/crates/zed/src/languages/heex/injections.scm @@ -5,9 +5,9 @@ (expression_value) (ending_expression_value) ] @content) - (#set! language "elixir") - (#set! combined) + (.set! language "elixir") + (.set! combined) ) ((expression (expression_value) @content) - (#set! language "elixir")) + (.set! language "elixir")) diff --git a/crates/zed/src/languages/html/injections.scm b/crates/zed/src/languages/html/injections.scm index 9084e373f217b95cf70bad9cc907d5d9cd127391..7d2ed0a225e7555c6f12a9b902863a2e9e2e0939 100644 --- a/crates/zed/src/languages/html/injections.scm +++ b/crates/zed/src/languages/html/injections.scm @@ -1,7 +1,7 @@ (script_element (raw_text) @content - (#set! "language" "javascript")) + (.set! "language" "javascript")) (style_element (raw_text) @content - (#set! "language" "css")) + (.set! "language" "css")) diff --git a/crates/zed/src/languages/javascript/highlights.scm b/crates/zed/src/languages/javascript/highlights.scm index 36ab21ca1ec854566ad716a13f5ab5725fa1acc9..7761bbb3a2dbdf0a66536f233be1df85c0724a11 100644 --- a/crates/zed/src/languages/javascript/highlights.scm +++ b/crates/zed/src/languages/javascript/highlights.scm @@ -44,7 +44,7 @@ ; Special identifiers ((identifier) @type - (#match? @type "^[A-Z]")) + (.match? @type "^[A-Z]")) (type_identifier) @type (predefined_type) @type.builtin @@ -53,7 +53,7 @@ (shorthand_property_identifier) (shorthand_property_identifier_pattern) ] @constant - (#match? @constant "^_*[A-Z_][A-Z\\d_]*$")) +(.match? @constant "^_*[A-Z_][A-Z\\d_]*$")) ; Literals @@ -214,4 +214,4 @@ "type" "readonly" "override" -] @keyword \ No newline at end of file +] @keyword diff --git a/crates/zed/src/languages/lua/highlights.scm b/crates/zed/src/languages/lua/highlights.scm index 60ca9de36b15098e9c76eaddff20238d5056adea..e00d0b9557c86bb6a6d395a727dae2a1f2593210 100644 --- a/crates/zed/src/languages/lua/highlights.scm +++ b/crates/zed/src/languages/lua/highlights.scm @@ -127,7 +127,7 @@ (identifier) @variable ((identifier) @variable.special - (#eq? @variable.special "self")) + (.eq? @variable.special "self")) (variable_list attribute: (attribute @@ -137,7 +137,7 @@ ;; Constants ((identifier) @constant - (#match? @constant "^[A-Z][A-Z_0-9]*$")) + (.match? @constant "^[A-Z][A-Z_0-9]*$")) (vararg_expression) @constant @@ -180,7 +180,7 @@ (function_call (identifier) @function.builtin - (#any-of? @function.builtin + (.any-of? @function.builtin ;; built-in functions in Lua 5.1 "assert" "collectgarbage" "dofile" "error" "getfenv" "getmetatable" "ipairs" "load" "loadfile" "loadstring" "module" "next" "pairs" "pcall" "print" diff --git a/crates/zed/src/languages/php/highlights.scm b/crates/zed/src/languages/php/highlights.scm index cfb03cbccad037d207ff1a1388c12eec22644f48..fb85d997fad6585066ac621253fe9694467e8517 100644 --- a/crates/zed/src/languages/php/highlights.scm +++ b/crates/zed/src/languages/php/highlights.scm @@ -43,15 +43,15 @@ (relative_scope) @variable.builtin ((name) @constant - (#match? @constant "^_?[A-Z][A-Z\\d_]+$")) + (.match? @constant "^_?[A-Z][A-Z\\d_]+$")) ((name) @constant.builtin - (#match? @constant.builtin "^__[A-Z][A-Z\d_]+__$")) + (.match? @constant.builtin "^__[A-Z][A-Z\d_]+__$")) ((name) @method.constructor -(#match? @method.constructor "^[A-Z]")) +(.match? @method.constructor "^[A-Z]")) ((name) @variable.builtin - (#eq? @variable.builtin "this")) + (.eq? @variable.builtin "this")) (variable_name) @variable diff --git a/crates/zed/src/languages/php/injections.scm b/crates/zed/src/languages/php/injections.scm index 57abd8ea2b0576e7b936788b4a9880bc57fea798..725729337b240a9e58b1e392ab645809d235314e 100644 --- a/crates/zed/src/languages/php/injections.scm +++ b/crates/zed/src/languages/php/injections.scm @@ -1,3 +1,3 @@ ((text) @content - (#set! "language" "html") - (#set! "combined")) + (.set! "language" "html") + (.set! "combined")) diff --git a/crates/zed/src/languages/python/highlights.scm b/crates/zed/src/languages/python/highlights.scm index 71ab963d82664db4dd9a66b9e9ac0e85449caf57..b31bddaeb501158c8bf6370ca0de37a1d73b7a6a 100644 --- a/crates/zed/src/languages/python/highlights.scm +++ b/crates/zed/src/languages/python/highlights.scm @@ -18,16 +18,16 @@ ; Identifier naming conventions ((identifier) @type - (#match? @type "^[A-Z]")) + (.match? @type "^[A-Z]")) ((identifier) @constant - (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) + (.match? @constant "^_*[A-Z][A-Z\\d_]*$")) ; Builtin functions ((call function: (identifier) @function.builtin) - (#match? + (.match? @function.builtin "^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__)$")) @@ -122,4 +122,4 @@ "yield" "match" "case" -] @keyword \ No newline at end of file +] @keyword diff --git a/crates/zed/src/languages/racket/highlights.scm b/crates/zed/src/languages/racket/highlights.scm index 2c0caf89357cfbe8f966bffbbc712272b3c1e59d..304b10a018b23eebcea9248d33e0f43edd50ea29 100644 --- a/crates/zed/src/languages/racket/highlights.scm +++ b/crates/zed/src/languages/racket/highlights.scm @@ -22,7 +22,7 @@ (lang_name) @variable.special ((symbol) @operator - (#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$")) + (.match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$")) (list . @@ -31,10 +31,9 @@ (list . (symbol) @keyword - (#match? @keyword + (.match? @keyword "^(unit-from-context|for/last|syntax-case|match-let\\*-values|define-for-syntax|define/subexpression-pos-prop|set-field!|class-field-accessor|invoke-unit|#%stratified-body|for\\*/and|for\\*/weak-set|flat-rec-contract|for\\*/stream|planet|for/mutable-seteqv|log-error|delay|#%declare|prop:dict/contract|->d|lib|override\\*|define-local-member-name|send-generic|for\\*/hasheq|define-syntax|submod|except|include-at/relative-to/reader|public\\*|define-member-name|define/public|let\\*|for/and|for\\*/first|for|delay/strict|define-values-for-export|==|match-define-values|for/weak-seteq|for\\*/async|for/stream|for/weak-seteqv|set!-values|lambda|for\\*/product|augment-final\\*|pubment\\*|command-line|contract|case|struct-field-index|contract-struct|unless|for/hasheq|for/seteqv|with-method|define-values-for-syntax|for-template|pubment|for\\*/list|syntax-case\\*|init-field|define-serializable-class|=>|for/foldr/derived|letrec-syntaxes|overment\\*|unquote-splicing|_|inherit-field|for\\*|stream-lazy|match-lambda\\*|contract-pos/neg-doubling|unit/c|match-define|for\\*/set|unit/s|nor|#%expression|class/c|this%|place/context|super-make-object|when|set!|parametric->/c|syntax-id-rules|include/reader|compound-unit|override-final|get-field|gen:dict|for\\*/seteqv|for\\*/hash|#%provide|combine-out|link|with-contract-continuation-mark|define-struct/derived|stream\\*|λ|rename-out|define-serializable-class\\*|augment|define/augment|let|define-signature-form|letrec-syntax|abstract|define-namespace-anchor|#%module-begin|#%top-interaction|for\\*/weak-seteqv|do|define/subexpression-pos-prop/name|absent|send/apply|with-handlers\\*|all-from-out|provide-signature-elements|gen:stream|define/override-final|for\\*/mutable-seteqv|rename|quasisyntax/loc|instantiate|for/list|extends|include-at/relative-to|mixin|define/pubment|#%plain-lambda|except-out|#%plain-module-begin|init|for\\*/last|relative-in|define-unit/new-import-export|->dm|member-name-key|nand|interface\\*|struct|define/override|else|define/augment-final|failure-cont|open|log-info|define/final-prop|all-defined-out|for/sum|for\\*/sum|recursive-contract|define|define-logger|match\\*|log-debug|rename-inner|->|struct/derived|unit|class\\*|prefix-out|any|define/overment|define-signature|match-letrec-values|let-syntaxes|for/mutable-set|define/match|cond|super-instantiate|define-contract-struct|import|hash/dc|define-custom-set-types|public-final|for/vector|for-label|prefix-in|for\\*/foldr/derived|define-unit-binding|object-contract|syntax-rules|augride|for\\*/mutable-seteq|quasisyntax|inner|for-syntax|overment|send/keyword-apply|generic|let\\*-values|->m|define-values|struct-copy|init-depend|struct/ctc|match-lambda|#%printing-module-begin|match\\*/derived|case->m|this|file|stream-cons|inspect|field|for/weak-set|struct\\*|gen:custom-write|thunk\\*|combine-in|unquote|for/lists|define/private|for\\*/foldr|define-unit/s|with-continuation-mark|begin|prefix|quote-syntax/prune|object/c|interface|match/derived|for/hasheqv|current-contract-region|define-compound-unit|override|define/public-final|recontract-out|let/cc|augride\\*|inherit|send|define-values/invoke-unit|for/mutable-seteq|#%datum|for/first|match-let\\*|invoke-unit/infer|define/contract|syntax/loc|for\\*/hasheqv|define-sequence-syntax|let/ec|for/product|for\\*/fold/derived|define-syntax-rule|lazy|unconstrained-domain->|augment-final|private|class|define-splicing-for-clause-syntax|for\\*/fold|prompt-tag/c|contract-out|match/values|public-final\\*|case-lambda|for/fold|unsyntax|for/set|begin0|#%require|time|public|define-struct|include|define-values/invoke-unit/infer|only-space-in|struct/c|only-meta-in|unit/new-import-export|place|begin-for-syntax|shared|inherit/super|quote|for/or|struct/contract|export|inherit/inner|struct-out|let-syntax|augment\\*|for\\*/vector|rename-in|match-let|define-unit|:do-in|~@|for\\*/weak-seteq|private\\*|and|except-in|log-fatal|gen:equal\\+hash|provide|require|thunk|invariant-assertion|define-match-expander|init-rest|->\\*|class/derived|super-new|for/fold/derived|for\\*/mutable-set|match-lambda\\*\\*|only|with-contract|~\\?|opt/c|let-values|delay/thread|->i|for/foldr|for-meta|only-in|send\\+|\\.\\.\\.|struct-guard/c|->\\*m|gen:set|struct/dc|define-syntaxes|if|parameterize|module\\*|module|send\\*|#%variable-reference|compound-unit/infer|#%plain-app|for/hash|contracted|case->|match|for\\*/lists|#%app|letrec-values|log-warning|super|define/augride|local-require|provide/contract|define-struct/contract|match-let-values|quote-syntax|for\\*/seteq|define-compound-unit/infer|parameterize\\*|values/drop|for/seteq|tag|stream|delay/idle|module\\+|define-custom-hash-types|cons/dc|define-module-boundary-contract|or|protect-out|define-opt/c|implies|letrec-syntaxes\\+values|for\\*/or|unsyntax-splicing|override-final\\*|for/async|parameterize-break|syntax|place\\*|for-space|quasiquote|with-handlers|delay/sync|define-unit-from-context|match-letrec|#%top|define-unit/contract|delay/name|new|field-bound\\?|letrec|class-field-mutator|with-syntax|flat-murec-contract|rename-super|local)$" )) ((symbol) @comment - (#match? @comment "^#[cC][iIsS]$")) - + (.match? @comment "^#[cC][iIsS]$")) diff --git a/crates/zed/src/languages/racket/outline.scm b/crates/zed/src/languages/racket/outline.scm index 604e052a63f71badbe98ec1debc96a519dc49256..188067078de2676ebaeaba90fe98d508dc7d19e0 100644 --- a/crates/zed/src/languages/racket/outline.scm +++ b/crates/zed/src/languages/racket/outline.scm @@ -6,5 +6,5 @@ (symbol) @name (list . (symbol) @name) ] - (#match? @start-symbol "^define") -) @item \ No newline at end of file + (.match? @start-symbol "^define") +) @item diff --git a/crates/zed/src/languages/ruby/brackets.scm b/crates/zed/src/languages/ruby/brackets.scm index 957b20ecdb4524920ba30b9d202d94d101215ed5..f5129f8f310ce4b533c29c5e3fdb465844e5e68e 100644 --- a/crates/zed/src/languages/ruby/brackets.scm +++ b/crates/zed/src/languages/ruby/brackets.scm @@ -11,4 +11,4 @@ (begin "begin" @open "end" @close) (module "module" @open "end" @close) (_ . "def" @open "end" @close) -(_ . "class" @open "end" @close) \ No newline at end of file +(_ . "class" @open "end" @close) diff --git a/crates/zed/src/languages/ruby/highlights.scm b/crates/zed/src/languages/ruby/highlights.scm index 2610cfa1ccf07254c68c87d2e8013741d7d6969f..93cf2608f4ee7829c55718c42075b6cb986805a1 100644 --- a/crates/zed/src/languages/ruby/highlights.scm +++ b/crates/zed/src/languages/ruby/highlights.scm @@ -33,12 +33,12 @@ (identifier) @variable ((identifier) @keyword - (#match? @keyword "^(private|protected|public)$")) + (.match? @keyword "^(private|protected|public)$")) ; Function calls ((identifier) @function.method.builtin - (#eq? @function.method.builtin "require")) + (.eq? @function.method.builtin "require")) "defined?" @function.method.builtin @@ -60,7 +60,7 @@ ] @property ((identifier) @constant.builtin - (#match? @constant.builtin "^__(FILE|LINE|ENCODING)__$")) + (.match? @constant.builtin "^__(FILE|LINE|ENCODING)__$")) (file) @constant.builtin (line) @constant.builtin @@ -71,7 +71,7 @@ ) @constant.builtin ((constant) @constant - (#match? @constant "^[A-Z\\d_]+$")) + (.match? @constant "^[A-Z\\d_]+$")) (constant) @type diff --git a/crates/zed/src/languages/rust/highlights.scm b/crates/zed/src/languages/rust/highlights.scm index 7240173a89260b22a9508a9984e40dc8b1ab7410..54dbfa00bd3195efadc965d3dca490d8c00b74bd 100644 --- a/crates/zed/src/languages/rust/highlights.scm +++ b/crates/zed/src/languages/rust/highlights.scm @@ -38,11 +38,11 @@ ; Assume uppercase names are types/enum-constructors ((identifier) @type - (#match? @type "^[A-Z]")) + (.match? @type "^[A-Z]")) ; Assume all-caps names are constants ((identifier) @constant - (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) + (.match? @constant "^_*[A-Z][A-Z\\d_]*$")) [ "(" diff --git a/crates/zed/src/languages/rust/injections.scm b/crates/zed/src/languages/rust/injections.scm index 57ebea8539345c72145eaa44cffb09845f913406..78fde3752fd9722e33daf4ad747b4e557044d353 100644 --- a/crates/zed/src/languages/rust/injections.scm +++ b/crates/zed/src/languages/rust/injections.scm @@ -1,7 +1,7 @@ (macro_invocation (token_tree) @content - (#set! "language" "rust")) + (.set! "language" "rust")) (macro_rule (token_tree) @content - (#set! "language" "rust")) \ No newline at end of file + (.set! "language" "rust")) diff --git a/crates/zed/src/languages/scheme/highlights.scm b/crates/zed/src/languages/scheme/highlights.scm index 40ba61cd055948195023e2aa25db6f032acd674e..201b0e9276870afeb4f3ed7eb68de302af929b33 100644 --- a/crates/zed/src/languages/scheme/highlights.scm +++ b/crates/zed/src/languages/scheme/highlights.scm @@ -14,7 +14,7 @@ (directive)] @comment ((symbol) @operator - (#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$")) + (.match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$")) (list . @@ -23,6 +23,6 @@ (list . (symbol) @keyword - (#match? @keyword + (.match? @keyword "^(define-syntax|let\\*|lambda|λ|case|=>|quote-splicing|unquote-splicing|set!|let|letrec|letrec-syntax|let-values|let\\*-values|do|else|define|cond|syntax-rules|unquote|begin|quote|let-syntax|and|if|quasiquote|letrec|delay|or|when|unless|identifier-syntax|assert|library|export|import|rename|only|except|prefix)$" )) diff --git a/crates/zed/src/languages/scheme/outline.scm b/crates/zed/src/languages/scheme/outline.scm index 604e052a63f71badbe98ec1debc96a519dc49256..188067078de2676ebaeaba90fe98d508dc7d19e0 100644 --- a/crates/zed/src/languages/scheme/outline.scm +++ b/crates/zed/src/languages/scheme/outline.scm @@ -6,5 +6,5 @@ (symbol) @name (list . (symbol) @name) ] - (#match? @start-symbol "^define") -) @item \ No newline at end of file + (.match? @start-symbol "^define") +) @item diff --git a/crates/zed/src/languages/svelte/injections.scm b/crates/zed/src/languages/svelte/injections.scm index 8c1ac9fcd0bb16cf59e792487985ac64d6a43f88..17719b325c0c3632e1f6d9bbf7cd131ed9362dcb 100755 --- a/crates/zed/src/languages/svelte/injections.scm +++ b/crates/zed/src/languages/svelte/injections.scm @@ -2,27 +2,27 @@ ; -------------- (script_element (raw_text) @content - (#set! "language" "javascript")) + (.set! "language" "javascript")) ((script_element (start_tag (attribute (quoted_attribute_value (attribute_value) @_language))) (raw_text) @content) - (#eq? @_language "ts") - (#set! "language" "typescript")) + (.eq? @_language "ts") + (.set! "language" "typescript")) ((script_element (start_tag (attribute (quoted_attribute_value (attribute_value) @_language))) (raw_text) @content) - (#eq? @_language "typescript") - (#set! "language" "typescript")) + (.eq? @_language "typescript") + (.set! "language" "typescript")) (style_element (raw_text) @content - (#set! "language" "css")) + (.set! "language" "css")) ((raw_text_expr) @content - (#set! "language" "javascript")) + (.set! "language" "javascript")) diff --git a/crates/zed/src/languages/typescript/highlights.scm b/crates/zed/src/languages/typescript/highlights.scm index ba6b329e0e0def9c5d0c31d0df94525825ed2c45..9272108670ac2729dd39f4b54f90b81eeb3218a4 100644 --- a/crates/zed/src/languages/typescript/highlights.scm +++ b/crates/zed/src/languages/typescript/highlights.scm @@ -44,10 +44,10 @@ ; Special identifiers ((identifier) @method.constructor - (#match? @method.constructor "^[A-Z]")) + (.match? @method.constructor "^[A-Z]")) ((identifier) @type - (#match? @type "^[A-Z]")) + (.match? @type "^[A-Z]")) (type_identifier) @type (predefined_type) @type.builtin @@ -56,7 +56,7 @@ (shorthand_property_identifier) (shorthand_property_identifier_pattern) ] @constant - (#match? @constant "^_*[A-Z_][A-Z\\d_]*$")) +(.match? @constant "^_*[A-Z_][A-Z\\d_]*$")) ; Literals From 0b7e75c25a6d98649e92aa5d6e4f709f7bd754d2 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 27 Jul 2023 12:55:32 -0400 Subject: [PATCH 068/160] Add the `generate-syntax` action --- styles/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/styles/package.json b/styles/package.json index 16e95d90d5bebb18e7cfffe88e8d0098b48eb00f..3a50ac537166bcde6c30b0bc822481a823cfc8a2 100644 --- a/styles/package.json +++ b/styles/package.json @@ -8,6 +8,7 @@ "build-licenses": "ts-node ./src/build_licenses.ts", "build-tokens": "ts-node ./src/build_tokens.ts", "build-types": "ts-node ./src/build_types.ts", + "generate-syntax": "ts-node ./src/types/extract_syntax_types.ts", "test": "vitest" }, "author": "Zed Industries (https://github.com/zed-industries/)", From b9d5cc5828617fb0e973c121f09645cb7e98fb62 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 27 Jul 2023 12:56:54 -0400 Subject: [PATCH 069/160] Format --- styles/src/build_themes.ts | 9 +- styles/src/build_tokens.ts | 4 +- styles/src/component/icon_button.ts | 5 +- styles/src/component/tab_bar_button.ts | 67 +++--- styles/src/component/text_button.ts | 5 +- styles/src/style_tree/app.ts | 2 +- styles/src/style_tree/assistant.ts | 69 ++++--- styles/src/style_tree/editor.ts | 2 +- styles/src/style_tree/feedback.ts | 2 +- styles/src/style_tree/picker.ts | 2 +- styles/src/style_tree/project_panel.ts | 16 +- styles/src/style_tree/status_bar.ts | 10 +- styles/src/style_tree/titlebar.ts | 4 +- styles/src/theme/create_theme.ts | 25 ++- styles/src/theme/syntax.ts | 42 ++-- styles/src/theme/theme_config.ts | 4 +- styles/src/theme/tokens/theme.ts | 4 +- styles/src/themes/atelier/common.ts | 6 +- styles/src/types/extract_syntax_types.ts | 41 ++-- styles/src/types/syntax.ts | 253 +++++++++++------------ styles/tsconfig.json | 4 +- 21 files changed, 299 insertions(+), 277 deletions(-) diff --git a/styles/src/build_themes.ts b/styles/src/build_themes.ts index 17575663a1f88b17870b1b146b47e7086bf3e2ba..4d262f8146ed907035e384dbefd28c0b838a467a 100644 --- a/styles/src/build_themes.ts +++ b/styles/src/build_themes.ts @@ -21,9 +21,7 @@ function clear_themes(theme_directory: string) { } } -const all_themes: Theme[] = themes.map((theme) => - create_theme(theme) -) +const all_themes: Theme[] = themes.map((theme) => create_theme(theme)) function write_themes(themes: Theme[], output_directory: string) { clear_themes(output_directory) @@ -34,10 +32,7 @@ function write_themes(themes: Theme[], output_directory: string) { const style_tree = app() const style_tree_json = JSON.stringify(style_tree, null, 2) const temp_path = path.join(temp_directory, `${theme.name}.json`) - const out_path = path.join( - output_directory, - `${theme.name}.json` - ) + const out_path = path.join(output_directory, `${theme.name}.json`) fs.writeFileSync(temp_path, style_tree_json) fs.renameSync(temp_path, out_path) console.log(`- ${out_path} created`) diff --git a/styles/src/build_tokens.ts b/styles/src/build_tokens.ts index fd6aa18ced50af53b6bcf4c3c386d1774c7ab00d..3c52b6d989640a93025ac5eafe5a959b8bc83163 100644 --- a/styles/src/build_tokens.ts +++ b/styles/src/build_tokens.ts @@ -83,8 +83,6 @@ function write_tokens(themes: Theme[], tokens_directory: string) { console.log(`- ${METADATA_FILE} created`) } -const all_themes: Theme[] = themes.map((theme) => - create_theme(theme) -) +const all_themes: Theme[] = themes.map((theme) => create_theme(theme)) write_tokens(all_themes, TOKENS_DIRECTORY) diff --git a/styles/src/component/icon_button.ts b/styles/src/component/icon_button.ts index 6887fc7c30e1f234fd043bb115c2658039b5f806..13dfce6d7762aaf2abc59f298fb6e22583435cf1 100644 --- a/styles/src/component/icon_button.ts +++ b/styles/src/component/icon_button.ts @@ -10,10 +10,7 @@ export type Margin = { } interface IconButtonOptions { - layer?: - | Theme["lowest"] - | Theme["middle"] - | Theme["highest"] + layer?: Theme["lowest"] | Theme["middle"] | Theme["highest"] color?: keyof Theme["lowest"] margin?: Partial } diff --git a/styles/src/component/tab_bar_button.ts b/styles/src/component/tab_bar_button.ts index 0c43e7010e5469c10f959e00f4df8d177963392f..9e7f9acfc314be75850128690d8d066dde520182 100644 --- a/styles/src/component/tab_bar_button.ts +++ b/styles/src/component/tab_bar_button.ts @@ -12,44 +12,47 @@ type TabBarButtonProps = TabBarButtonOptions & { state?: Partial>> } -export function tab_bar_button(theme: Theme, { icon, color = "base" }: TabBarButtonProps) { +export function tab_bar_button( + theme: Theme, + { icon, color = "base" }: TabBarButtonProps +) { const button_spacing = 8 - return ( - interactive({ - base: { - icon: { - color: foreground(theme.middle, color), - asset: icon, - dimensions: { - width: 15, - height: 15, - }, + return interactive({ + base: { + icon: { + color: foreground(theme.middle, color), + asset: icon, + dimensions: { + width: 15, + height: 15, }, - container: { - corner_radius: 4, - padding: { - top: 4, bottom: 4, left: 4, right: 4 - }, - margin: { - left: button_spacing / 2, - right: button_spacing / 2, - }, + }, + container: { + corner_radius: 4, + padding: { + top: 4, + bottom: 4, + left: 4, + right: 4, + }, + margin: { + left: button_spacing / 2, + right: button_spacing / 2, }, }, - state: { - hovered: { - container: { - background: background(theme.middle, color, "hovered"), - - } + }, + state: { + hovered: { + container: { + background: background(theme.middle, color, "hovered"), }, - clicked: { - container: { - background: background(theme.middle, color, "pressed"), - } + }, + clicked: { + container: { + background: background(theme.middle, color, "pressed"), }, }, - }) - ) + }, + }) } diff --git a/styles/src/component/text_button.ts b/styles/src/component/text_button.ts index 58b2a1cbf2ff31a8e4fc50b9e1165bca78ec6b4a..68ec01c92bf1ba12907675dbd4ee87a4f51e4b9c 100644 --- a/styles/src/component/text_button.ts +++ b/styles/src/component/text_button.ts @@ -9,10 +9,7 @@ import { useTheme, Theme } from "../theme" import { Margin } from "./icon_button" interface TextButtonOptions { - layer?: - | Theme["lowest"] - | Theme["middle"] - | Theme["highest"] + layer?: Theme["lowest"] | Theme["middle"] | Theme["highest"] color?: keyof Theme["lowest"] margin?: Partial text_properties?: TextProperties diff --git a/styles/src/style_tree/app.ts b/styles/src/style_tree/app.ts index ccfdd60a981f4d5e763ce35902b0456bf0d703cd..ee0aa133a04bd35202d381835e257ddca2b284cc 100644 --- a/styles/src/style_tree/app.ts +++ b/styles/src/style_tree/app.ts @@ -57,6 +57,6 @@ export default function app(): any { tooltip: tooltip(), terminal: terminal(), assistant: assistant(), - feedback: feedback() + feedback: feedback(), } } diff --git a/styles/src/style_tree/assistant.ts b/styles/src/style_tree/assistant.ts index cfc1f8d813648654a8fee608ea4d00dc30893b75..7df5434f91010f778d47dfc9170ef80b909df0cf 100644 --- a/styles/src/style_tree/assistant.ts +++ b/styles/src/style_tree/assistant.ts @@ -8,50 +8,48 @@ type RoleCycleButton = TextStyle & { } // TODO: Replace these with zed types type RemainingTokens = TextStyle & { - background: string, - margin: { top: number, right: number }, + background: string + margin: { top: number; right: number } padding: { - right: number, - left: number, - top: number, - bottom: number, - }, - corner_radius: number, + right: number + left: number + top: number + bottom: number + } + corner_radius: number } export default function assistant(): any { const theme = useTheme() - const interactive_role = (color: StyleSets): Interactive => { - return ( - interactive({ - base: { + const interactive_role = ( + color: StyleSets + ): Interactive => { + return interactive({ + base: { + ...text(theme.highest, "sans", color, { size: "sm" }), + }, + state: { + hovered: { ...text(theme.highest, "sans", color, { size: "sm" }), + background: background(theme.highest, color, "hovered"), }, - state: { - hovered: { - ...text(theme.highest, "sans", color, { size: "sm" }), - background: background(theme.highest, color, "hovered"), - }, - clicked: { - ...text(theme.highest, "sans", color, { size: "sm" }), - background: background(theme.highest, color, "pressed"), - } + clicked: { + ...text(theme.highest, "sans", color, { size: "sm" }), + background: background(theme.highest, color, "pressed"), }, - }) - ) + }, + }) } const tokens_remaining = (color: StyleSets): RemainingTokens => { - return ( - { - ...text(theme.highest, "mono", color, { size: "xs" }), - background: background(theme.highest, "on", "default"), - margin: { top: 12, right: 20 }, - padding: { right: 4, left: 4, top: 1, bottom: 1 }, - corner_radius: 6, - } - ) + return { + ...text(theme.highest, "mono", color, { size: "xs" }), + background: background(theme.highest, "on", "default"), + margin: { top: 12, right: 20 }, + padding: { right: 4, left: 4, top: 1, bottom: 1 }, + corner_radius: 6, + } } return { @@ -93,7 +91,10 @@ export default function assistant(): any { base: { background: background(theme.middle), padding: { top: 4, bottom: 4 }, - border: border(theme.middle, "default", { top: true, overlay: true }), + border: border(theme.middle, "default", { + top: true, + overlay: true, + }), }, state: { hovered: { @@ -101,7 +102,7 @@ export default function assistant(): any { }, clicked: { background: background(theme.middle, "pressed"), - } + }, }, }), saved_at: { diff --git a/styles/src/style_tree/editor.ts b/styles/src/style_tree/editor.ts index ccbb33e21dd8459f665531b9b4b19af8831946bd..832e77626491ff94f183d5ce1fe195f5a55a3780 100644 --- a/styles/src/style_tree/editor.ts +++ b/styles/src/style_tree/editor.ts @@ -318,7 +318,7 @@ export default function editor(): any { ? with_opacity(theme.ramps.green(0.5).hex(), 0.8) : with_opacity(theme.ramps.green(0.4).hex(), 0.8), }, - selections: foreground(layer, "accent") + selections: foreground(layer, "accent"), }, composition_mark: { underline: { diff --git a/styles/src/style_tree/feedback.ts b/styles/src/style_tree/feedback.ts index b1bd96e165466521804f86d547664c209c7c4671..0349359533041d4425df3d0c72d120ed18499a30 100644 --- a/styles/src/style_tree/feedback.ts +++ b/styles/src/style_tree/feedback.ts @@ -37,7 +37,7 @@ export default function feedback(): any { ...text(theme.highest, "mono", "on", "disabled"), background: background(theme.highest, "on", "disabled"), border: border(theme.highest, "on", "disabled"), - } + }, }, }), button_margin: 8, diff --git a/styles/src/style_tree/picker.ts b/styles/src/style_tree/picker.ts index 28ae85478794a22211dc67cb6ec56cce4bc805f1..317f600b1e2fca3f6b8756c3ba033fa22e6b0220 100644 --- a/styles/src/style_tree/picker.ts +++ b/styles/src/style_tree/picker.ts @@ -152,7 +152,7 @@ export default function picker(): any { 0.5 ), }, - } + }, }), } } diff --git a/styles/src/style_tree/project_panel.ts b/styles/src/style_tree/project_panel.ts index e239f9a84023088d988f74e709c6485ade8a9510..51958af145b50afd25510788ff0a530cc77a5a1d 100644 --- a/styles/src/style_tree/project_panel.ts +++ b/styles/src/style_tree/project_panel.ts @@ -64,17 +64,17 @@ export default function project_panel(): any { const unselected_default_style = merge( base_properties, unselected?.default ?? {}, - {}, + {} ) const unselected_hovered_style = merge( base_properties, { background: background(theme.middle, "hovered") }, - unselected?.hovered ?? {}, + unselected?.hovered ?? {} ) const unselected_clicked_style = merge( base_properties, { background: background(theme.middle, "pressed") }, - unselected?.clicked ?? {}, + unselected?.clicked ?? {} ) const selected_default_style = merge( base_properties, @@ -82,7 +82,7 @@ export default function project_panel(): any { background: background(theme.lowest), text: text(theme.lowest, "sans", { size: "sm" }), }, - selected_style?.default ?? {}, + selected_style?.default ?? {} ) const selected_hovered_style = merge( base_properties, @@ -90,7 +90,7 @@ export default function project_panel(): any { background: background(theme.lowest, "hovered"), text: text(theme.lowest, "sans", { size: "sm" }), }, - selected_style?.hovered ?? {}, + selected_style?.hovered ?? {} ) const selected_clicked_style = merge( base_properties, @@ -98,7 +98,7 @@ export default function project_panel(): any { background: background(theme.lowest, "pressed"), text: text(theme.lowest, "sans", { size: "sm" }), }, - selected_style?.clicked ?? {}, + selected_style?.clicked ?? {} ) return toggleable({ @@ -175,7 +175,7 @@ export default function project_panel(): any { default: { icon_color: foreground(theme.middle, "variant"), }, - }, + } ), cut_entry: entry( { @@ -190,7 +190,7 @@ export default function project_panel(): any { size: "sm", }), }, - }, + } ), filename_editor: { background: background(theme.middle, "on"), diff --git a/styles/src/style_tree/status_bar.ts b/styles/src/style_tree/status_bar.ts index 06afc378235ec843d64a28313a38c05d395f1962..8f50896207ca6853c49ff008d6252d01f44f6911 100644 --- a/styles/src/style_tree/status_bar.ts +++ b/styles/src/style_tree/status_bar.ts @@ -34,10 +34,14 @@ export default function status_bar(): any { ...text(layer, "mono", "variant", { size: "xs" }), }, active_language: text_button({ - color: "variant" + color: "variant", + }), + auto_update_progress_message: text(layer, "sans", "variant", { + size: "xs", + }), + auto_update_done_message: text(layer, "sans", "variant", { + size: "xs", }), - auto_update_progress_message: text(layer, "sans", "variant", { size: "xs" }), - auto_update_done_message: text(layer, "sans", "variant", { size: "xs" }), lsp_status: interactive({ base: { ...diagnostic_status_container, diff --git a/styles/src/style_tree/titlebar.ts b/styles/src/style_tree/titlebar.ts index 177a8c5bd8db0fa2290eda5e25c4160531d81e4b..fe0c53e87dac61bdfc93688eea13e74d583017a9 100644 --- a/styles/src/style_tree/titlebar.ts +++ b/styles/src/style_tree/titlebar.ts @@ -183,10 +183,10 @@ export function titlebar(): any { project_name_divider: text(theme.lowest, "sans", "variant"), project_menu_button: toggleable_text_button(theme, { - color: 'base', + color: "base", }), git_menu_button: toggleable_text_button(theme, { - color: 'variant', + color: "variant", }), // Collaborators diff --git a/styles/src/theme/create_theme.ts b/styles/src/theme/create_theme.ts index e52c4dc95b361572d8cbdc388c04146cecc81e8c..6df36d7077b934f2acc45f21422159872c6f551a 100644 --- a/styles/src/theme/create_theme.ts +++ b/styles/src/theme/create_theme.ts @@ -2,7 +2,7 @@ import { Scale, Color } from "chroma-js" import { ThemeConfig, ThemeAppearance, - ThemeConfigInputColors + ThemeConfigInputColors, } from "./theme_config" import { get_ramps } from "./ramps" import { syntaxStyle } from "./syntax" @@ -13,16 +13,16 @@ export interface Theme { is_light: boolean /** - * App background, other elements that should sit directly on top of the background. - */ + * App background, other elements that should sit directly on top of the background. + */ lowest: Layer /** - * Panels, tabs, other UI surfaces that sit on top of the background. - */ + * Panels, tabs, other UI surfaces that sit on top of the background. + */ middle: Layer /** - * Editors like code buffers, conversation editors, etc. - */ + * Editors like code buffers, conversation editors, etc. + */ highest: Layer ramps: RampSet @@ -115,11 +115,7 @@ export interface Style { } export function create_theme(theme: ThemeConfig): Theme { - const { - name, - appearance, - input_color, - } = theme + const { name, appearance, input_color } = theme const is_light = appearance === ThemeAppearance.Light const color_ramps: ThemeConfigInputColors = input_color @@ -161,7 +157,10 @@ export function create_theme(theme: ThemeConfig): Theme { "7": player(ramps.yellow), } - const syntax = syntaxStyle(ramps, theme.override.syntax ? theme.override.syntax : {}) + const syntax = syntaxStyle( + ramps, + theme.override.syntax ? theme.override.syntax : {} + ) return { name, diff --git a/styles/src/theme/syntax.ts b/styles/src/theme/syntax.ts index d39496a412904647ea2deb8c74048c864ab31550..b1bf5ed9307b87036656d902b892c56b627022a0 100644 --- a/styles/src/theme/syntax.ts +++ b/styles/src/theme/syntax.ts @@ -3,8 +3,13 @@ import { font_weights, ThemeConfigInputSyntax, RampSet } from "../common" import { Syntax, SyntaxHighlightStyle, allSyntaxKeys } from "../types/syntax" // Apply defaults to any missing syntax properties that are not defined manually -function apply_defaults(ramps: RampSet, syntax_highlights: Partial): Syntax { - const restKeys: (keyof Syntax)[] = allSyntaxKeys.filter(key => !syntax_highlights[key]) +function apply_defaults( + ramps: RampSet, + syntax_highlights: Partial +): Syntax { + const restKeys: (keyof Syntax)[] = allSyntaxKeys.filter( + (key) => !syntax_highlights[key] + ) const completeSyntax: Syntax = {} as Syntax @@ -28,23 +33,36 @@ function apply_defaults(ramps: RampSet, syntax_highlights: Partial): Syn // Merge the base syntax with the theme syntax overrides // This is a deep merge, so any nested properties will be merged as well // This allows for a theme to only override a single property of a syntax highlight style -const merge_syntax = (baseSyntax: Syntax, theme_syntax_overrides: ThemeConfigInputSyntax): Syntax => { - return deepmerge(baseSyntax, theme_syntax_overrides, { - arrayMerge: (destinationArray, sourceArray) => [ - ...destinationArray, - ...sourceArray, - ], - }) +const merge_syntax = ( + baseSyntax: Syntax, + theme_syntax_overrides: ThemeConfigInputSyntax +): Syntax => { + return deepmerge( + baseSyntax, + theme_syntax_overrides, + { + arrayMerge: (destinationArray, sourceArray) => [ + ...destinationArray, + ...sourceArray, + ], + } + ) } /** Returns a complete Syntax object of the combined styles of a theme's syntax overrides and the default syntax styles */ -export const syntaxStyle = (ramps: RampSet, theme_syntax_overrides: ThemeConfigInputSyntax): Syntax => { +export const syntaxStyle = ( + ramps: RampSet, + theme_syntax_overrides: ThemeConfigInputSyntax +): Syntax => { const syntax_highlights: Partial = { - "comment": { color: ramps.neutral(0.71).hex() }, + comment: { color: ramps.neutral(0.71).hex() }, "comment.doc": { color: ramps.neutral(0.71).hex() }, primary: { color: ramps.neutral(1).hex() }, emphasis: { color: ramps.blue(0.5).hex() }, - "emphasis.strong": { color: ramps.blue(0.5).hex(), weight: font_weights.bold }, + "emphasis.strong": { + color: ramps.blue(0.5).hex(), + weight: font_weights.bold, + }, link_uri: { color: ramps.green(0.5).hex(), underline: true }, link_text: { color: ramps.orange(0.5).hex(), italic: true }, "text.literal": { color: ramps.orange(0.5).hex() }, diff --git a/styles/src/theme/theme_config.ts b/styles/src/theme/theme_config.ts index 8473bbb600608cac6157f894f3e9ac5d91c31a31..f5f83590743278508ba16b7245c2e7fc8e4d2650 100644 --- a/styles/src/theme/theme_config.ts +++ b/styles/src/theme/theme_config.ts @@ -55,7 +55,9 @@ export type ThemeConfigInputColorsKeys = keyof ThemeConfigInputColors * } * ``` */ -export type ThemeConfigInputSyntax = Partial>> +export type ThemeConfigInputSyntax = Partial< + Record> +> interface ThemeConfigOverrides { syntax: ThemeConfigInputSyntax diff --git a/styles/src/theme/tokens/theme.ts b/styles/src/theme/tokens/theme.ts index f9e83e0512012e0c5d699ac432869a70520a9839..d93079366961a1079df0858ceef980a0b9b59aec 100644 --- a/styles/src/theme/tokens/theme.ts +++ b/styles/src/theme/tokens/theme.ts @@ -4,9 +4,7 @@ import { SingleOtherToken, TokenTypes, } from "@tokens-studio/types" -import { - Shadow, -} from "../create_theme" +import { Shadow } from "../create_theme" import { LayerToken, layer_token } from "./layer" import { PlayersToken, players_token } from "./players" import { color_token } from "./token" diff --git a/styles/src/themes/atelier/common.ts b/styles/src/themes/atelier/common.ts index 09226b336c0aae3d42a4e99130e1c46875d6065b..9a0029581c565b0eb820e7bc8686f62e5e3627b2 100644 --- a/styles/src/themes/atelier/common.ts +++ b/styles/src/themes/atelier/common.ts @@ -1,4 +1,8 @@ -import { ThemeLicenseType, ThemeFamilyMeta, ThemeConfigInputSyntax } from "../../common" +import { + ThemeLicenseType, + ThemeFamilyMeta, + ThemeConfigInputSyntax, +} from "../../common" export interface Variant { colors: { diff --git a/styles/src/types/extract_syntax_types.ts b/styles/src/types/extract_syntax_types.ts index 3bf089518233a8b264e71853ad83e2634f9c1ab3..eb21d2418b9c830099cffc0c03f9ecf4c88ba7ed 100644 --- a/styles/src/types/extract_syntax_types.ts +++ b/styles/src/types/extract_syntax_types.ts @@ -1,9 +1,9 @@ -import fs from 'fs' -import path from 'path' -import readline from 'readline' +import fs from "fs" +import path from "path" +import readline from "readline" function escapeTypeName(name: string): string { - return `'${name.replace('@', '').toLowerCase()}'` + return `'${name.replace("@", "").toLowerCase()}'` } const generatedNote = `// This file is generated by extract_syntax_types.ts @@ -17,8 +17,8 @@ const defaultTextProperty = ` /** Default text color */ | 'primary'` const main = async () => { - const pathFromRoot = 'crates/zed/src/languages' - const directoryPath = path.join(__dirname, '../../../', pathFromRoot) + const pathFromRoot = "crates/zed/src/languages" + const directoryPath = path.join(__dirname, "../../../", pathFromRoot) const stylesMap: Record> = {} const propertyLanguageMap: Record> = {} @@ -47,24 +47,31 @@ const main = async () => { } } - const directories = fs.readdirSync(directoryPath, { withFileTypes: true }) - .filter(dirent => dirent.isDirectory()) - .map(dirent => dirent.name) + const directories = fs + .readdirSync(directoryPath, { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => dirent.name) for (const dir of directories) { - const highlightsFilePath = path.join(directoryPath, dir, 'highlights.scm') + const highlightsFilePath = path.join( + directoryPath, + dir, + "highlights.scm" + ) if (fs.existsSync(highlightsFilePath)) { await processFile(highlightsFilePath, dir) } } for (const [language, properties] of Object.entries(stylesMap)) { - console.log(`${language}: ${Array.from(properties).join(', ')}`) + console.log(`${language}: ${Array.from(properties).join(", ")}`) } - const sortedProperties = Object.entries(propertyLanguageMap).sort(([propA], [propB]) => propA.localeCompare(propB)) + const sortedProperties = Object.entries(propertyLanguageMap).sort( + ([propA], [propB]) => propA.localeCompare(propB) + ) - const outStream = fs.createWriteStream(path.join(__dirname, 'syntax.ts')) + const outStream = fs.createWriteStream(path.join(__dirname, "syntax.ts")) let allProperties = "" const syntaxKeys = [] for (const [property, languages] of sortedProperties) { @@ -73,9 +80,9 @@ const main = async () => { // Limit to the first 7 languages, append "..." if more than 7 languagesArray = languagesArray.slice(0, 7) if (moreThanSeven) { - languagesArray.push('...') + languagesArray.push("...") } - const languagesString = languagesArray.join(', ') + const languagesString = languagesArray.join(", ") const comment = `/** ${languagesString} */` allProperties += ` ${comment}\n | ${property} \n` syntaxKeys.push(property) @@ -95,7 +102,9 @@ export type SyntaxOverride = Partial export type SyntaxProperty = \n${defaultTextProperty}\n\n${allProperties} -export const allSyntaxKeys: SyntaxProperty[] = [\n ${syntaxKeys.join(',\n ')}\n]`) +export const allSyntaxKeys: SyntaxProperty[] = [\n ${syntaxKeys.join( + ",\n " + )}\n]`) outStream.end() } diff --git a/styles/src/types/syntax.ts b/styles/src/types/syntax.ts index b74edfdf8463e510c40fee84c35e5d22d6586d83..9b23dbde3cc799090e1dd848706f2b96a88e7ba6 100644 --- a/styles/src/types/syntax.ts +++ b/styles/src/types/syntax.ts @@ -6,198 +6,197 @@ // 'npm run extract-syntax-types' from ./styles export type SyntaxHighlightStyle = { - color: string, - fade_out?: number, - italic?: boolean, - underline?: boolean, - weight?: string, + color: string + fade_out?: number + italic?: boolean + underline?: boolean + weight?: string } export type Syntax = Record export type SyntaxOverride = Partial -export type SyntaxProperty = +export type SyntaxProperty = /** Default text color */ - | 'primary' + | "primary" /** elixir */ - | '__attribute__' + | "__attribute__" /** elixir */ - | '__name__' + | "__name__" /** elixir */ - | '_sigil_name' + | "_sigil_name" /** css, heex, lua */ - | 'attribute' + | "attribute" /** javascript, lua, tsx, typescript, yaml */ - | 'boolean' + | "boolean" /** elixir */ - | 'comment.doc' + | "comment.doc" /** elixir */ - | 'comment.unused' + | "comment.unused" /** bash, c, cpp, css, elixir, elm, erb, ... */ - | 'comment' + | "comment" /** elixir, go, javascript, lua, php, python, racket, ... */ - | 'constant.builtin' + | "constant.builtin" /** bash, c, cpp, elixir, elm, glsl, heex, ... */ - | 'constant' + | "constant" /** glsl */ - | 'delimiter' + | "delimiter" /** bash, elixir, javascript, python, ruby, tsx, typescript */ - | 'embedded' + | "embedded" /** markdown */ - | 'emphasis.strong' + | "emphasis.strong" /** markdown */ - | 'emphasis' + | "emphasis" /** go, python, racket, ruby, scheme */ - | 'escape' + | "escape" /** lua */ - | 'field' + | "field" /** lua, php, python */ - | 'function.builtin' + | "function.builtin" /** elm, lua, rust */ - | 'function.definition' + | "function.definition" /** ruby */ - | 'function.method.builtin' + | "function.method.builtin" /** go, javascript, php, python, ruby, rust, tsx, ... */ - | 'function.method' + | "function.method" /** rust */ - | 'function.special.definition' + | "function.special.definition" /** c, cpp, glsl, rust */ - | 'function.special' + | "function.special" /** bash, c, cpp, css, elixir, elm, glsl, ... */ - | 'function' + | "function" /** elm */ - | 'identifier' + | "identifier" /** glsl */ - | 'keyword.function' + | "keyword.function" /** bash, c, cpp, css, elixir, elm, erb, ... */ - | 'keyword' + | "keyword" /** c, cpp, glsl */ - | 'label' + | "label" /** markdown */ - | 'link_text' + | "link_text" /** markdown */ - | 'link_uri' + | "link_uri" /** lua, php, tsx, typescript */ - | 'method.constructor' + | "method.constructor" /** lua */ - | 'method' + | "method" /** heex */ - | 'module' + | "module" /** svelte */ - | 'none' + | "none" /** bash, c, cpp, css, elixir, glsl, go, ... */ - | 'number' + | "number" /** bash, c, cpp, css, elixir, elm, glsl, ... */ - | 'operator' + | "operator" /** lua */ - | 'parameter' + | "parameter" /** lua */ - | 'preproc' + | "preproc" /** bash, c, cpp, css, glsl, go, html, ... */ - | 'property' + | "property" /** c, cpp, elixir, elm, heex, html, javascript, ... */ - | 'punctuation.bracket' + | "punctuation.bracket" /** c, cpp, css, elixir, elm, heex, javascript, ... */ - | 'punctuation.delimiter' + | "punctuation.delimiter" /** markdown */ - | 'punctuation.list_marker' + | "punctuation.list_marker" /** elixir, javascript, python, ruby, tsx, typescript, yaml */ - | 'punctuation.special' + | "punctuation.special" /** elixir */ - | 'punctuation' + | "punctuation" /** glsl */ - | 'storageclass' + | "storageclass" /** elixir, elm, yaml */ - | 'string.escape' + | "string.escape" /** elixir, javascript, racket, ruby, tsx, typescript */ - | 'string.regex' + | "string.regex" /** elixir, ruby */ - | 'string.special.symbol' + | "string.special.symbol" /** css, elixir, toml */ - | 'string.special' + | "string.special" /** bash, c, cpp, css, elixir, elm, glsl, ... */ - | 'string' + | "string" /** svelte */ - | 'tag.delimiter' + | "tag.delimiter" /** css, heex, php, svelte */ - | 'tag' + | "tag" /** markdown */ - | 'text.literal' + | "text.literal" /** markdown */ - | 'title' + | "title" /** javascript, php, rust, tsx, typescript */ - | 'type.builtin' + | "type.builtin" /** glsl */ - | 'type.qualifier' + | "type.qualifier" /** c, cpp, css, elixir, elm, glsl, go, ... */ - | 'type' + | "type" /** glsl, php */ - | 'variable.builtin' + | "variable.builtin" /** cpp, css, javascript, lua, racket, ruby, rust, ... */ - | 'variable.special' + | "variable.special" /** c, cpp, elm, glsl, go, javascript, lua, ... */ - | 'variable' - + | "variable" export const allSyntaxKeys: SyntaxProperty[] = [ - '__attribute__', - '__name__', - '_sigil_name', - 'attribute', - 'boolean', - 'comment.doc', - 'comment.unused', - 'comment', - 'constant.builtin', - 'constant', - 'delimiter', - 'embedded', - 'emphasis.strong', - 'emphasis', - 'escape', - 'field', - 'function.builtin', - 'function.definition', - 'function.method.builtin', - 'function.method', - 'function.special.definition', - 'function.special', - 'function', - 'identifier', - 'keyword.function', - 'keyword', - 'label', - 'link_text', - 'link_uri', - 'method.constructor', - 'method', - 'module', - 'none', - 'number', - 'operator', - 'parameter', - 'preproc', - 'property', - 'punctuation.bracket', - 'punctuation.delimiter', - 'punctuation.list_marker', - 'punctuation.special', - 'punctuation', - 'storageclass', - 'string.escape', - 'string.regex', - 'string.special.symbol', - 'string.special', - 'string', - 'tag.delimiter', - 'tag', - 'text.literal', - 'title', - 'type.builtin', - 'type.qualifier', - 'type', - 'variable.builtin', - 'variable.special', - 'variable' -] \ No newline at end of file + "__attribute__", + "__name__", + "_sigil_name", + "attribute", + "boolean", + "comment.doc", + "comment.unused", + "comment", + "constant.builtin", + "constant", + "delimiter", + "embedded", + "emphasis.strong", + "emphasis", + "escape", + "field", + "function.builtin", + "function.definition", + "function.method.builtin", + "function.method", + "function.special.definition", + "function.special", + "function", + "identifier", + "keyword.function", + "keyword", + "label", + "link_text", + "link_uri", + "method.constructor", + "method", + "module", + "none", + "number", + "operator", + "parameter", + "preproc", + "property", + "punctuation.bracket", + "punctuation.delimiter", + "punctuation.list_marker", + "punctuation.special", + "punctuation", + "storageclass", + "string.escape", + "string.regex", + "string.special.symbol", + "string.special", + "string", + "tag.delimiter", + "tag", + "text.literal", + "title", + "type.builtin", + "type.qualifier", + "type", + "variable.builtin", + "variable.special", + "variable", +] diff --git a/styles/tsconfig.json b/styles/tsconfig.json index 281bd74b215bd16426bb6a8f9d68ddeb5a5bea43..a1913027b705df7d349c78bcc6b74bb96851fe8c 100644 --- a/styles/tsconfig.json +++ b/styles/tsconfig.json @@ -24,7 +24,5 @@ "useUnknownInCatchVariables": false, "baseUrl": "." }, - "exclude": [ - "node_modules" - ] + "exclude": ["node_modules"] } From b08a2770b867951c38a4286ebf96223578f0fc4a Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 27 Jul 2023 13:02:40 -0400 Subject: [PATCH 070/160] Remove redundant `syntax_highlights` --- styles/src/theme/syntax.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/styles/src/theme/syntax.ts b/styles/src/theme/syntax.ts index b1bf5ed9307b87036656d902b892c56b627022a0..db8f98de663bcb3afa8e84ea851363a3f83cbd0c 100644 --- a/styles/src/theme/syntax.ts +++ b/styles/src/theme/syntax.ts @@ -78,7 +78,6 @@ export const syntaxStyle = ( "string.regex": { color: ramps.orange(0.5).hex() }, "method.constructor": { color: ramps.blue(0.5).hex() }, type: { color: ramps.cyan(0.5).hex() }, - variable: { color: ramps.neutral(1).hex() }, label: { color: ramps.blue(0.5).hex() }, attribute: { color: ramps.blue(0.5).hex() }, property: { color: ramps.blue(0.5).hex() }, @@ -88,8 +87,6 @@ export const syntaxStyle = ( number: { color: ramps.green(0.5).hex() }, boolean: { color: ramps.green(0.5).hex() }, function: { color: ramps.yellow(0.5).hex() }, - preproc: { color: ramps.neutral(1).hex() }, - embedded: { color: ramps.neutral(1).hex() }, } const baseSyntax = apply_defaults(ramps, syntax_highlights) From d8352743061ebf73e382b724b80aeec236a67763 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 27 Jul 2023 11:11:24 -0700 Subject: [PATCH 071/160] Downgrade our dependency on treesitter-cpp --- Cargo.lock | 17 +++++++++++++---- Cargo.toml | 2 +- crates/language/src/language.rs | 20 ++++++++++---------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 05c5faa787cf29f52b9150c4a224e98c653b2f2f..674765f00cbe98c8a4284378b060f89b0b7509ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6513,7 +6513,7 @@ dependencies = [ "theme", "tiktoken-rs 0.5.0", "tree-sitter", - "tree-sitter-cpp", + "tree-sitter-cpp 0.20.2", "tree-sitter-elixir 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tree-sitter-json 0.19.0", "tree-sitter-rust", @@ -8032,9 +8032,18 @@ dependencies = [ [[package]] name = "tree-sitter-cpp" -version = "0.20.1" +version = "0.20.0" +source = "git+https://github.com/tree-sitter/tree-sitter-cpp?rev=f44509141e7e483323d2ec178f2d2e6c0fc041c1#f44509141e7e483323d2ec178f2d2e6c0fc041c1" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-cpp" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dbedbf4066bfab725b3f9e2a21530507419a7d2f98621d3c13213502b734ec0" +checksum = "1c88fd925d0333e63ac64e521f5bd79c53019e569ffbbccfeef346a326f459e9" dependencies = [ "cc", "tree-sitter", @@ -9622,7 +9631,7 @@ dependencies = [ "tree-sitter", "tree-sitter-bash", "tree-sitter-c", - "tree-sitter-cpp", + "tree-sitter-cpp 0.20.0", "tree-sitter-css", "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=4ba9dab6e2602960d95b2b625f3386c27e08084e)", "tree-sitter-elm", diff --git a/Cargo.toml b/Cargo.toml index 7bcbc7e2dcf2a73b639311a00800afcb1275ccb1..fc46286de0c78f286e9d110aed41fe41bf3902d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -109,7 +109,7 @@ pretty_assertions = "1.3.0" tree-sitter-bash = { git = "https://github.com/tree-sitter/tree-sitter-bash", rev = "1b0321ee85701d5036c334a6f04761cdc672e64c" } tree-sitter-c = "0.20.1" -tree-sitter-cpp = "0.20.0" +tree-sitter-cpp = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev="f44509141e7e483323d2ec178f2d2e6c0fc041c1" } tree-sitter-css = { git = "https://github.com/tree-sitter/tree-sitter-css", rev = "769203d0f9abe1a9a691ac2b9fe4bb4397a73c51" } tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "4ba9dab6e2602960d95b2b625f3386c27e08084e" } tree-sitter-elm = { git = "https://github.com/elm-tooling/tree-sitter-elm", rev = "692c50c0b961364c40299e73c1306aecb5d20f40"} diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index e34358c7c5def79e8141e86e54693bcc99188da0..b265bba7b56267c63af402db361be338fbebd27d 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -844,8 +844,8 @@ impl LanguageRegistry { } } } - Err(err) => { - log::error!("failed to load language {name} - {err}"); + Err(e) => { + log::error!("failed to load language {name}:\n{:?}", e); let mut state = this.state.write(); state.mark_language_loaded(id); if let Some(mut txs) = state.loading_languages.remove(&id) { @@ -853,7 +853,7 @@ impl LanguageRegistry { let _ = tx.send(Err(anyhow!( "failed to load language {}: {}", name, - err + e ))); } } @@ -1188,25 +1188,25 @@ impl Language { pub fn with_queries(mut self, queries: LanguageQueries) -> Result { if let Some(query) = queries.highlights { - self = self.with_highlights_query(query.as_ref())?; + self = self.with_highlights_query(query.as_ref()).context("Error loading highlights query")?; } if let Some(query) = queries.brackets { - self = self.with_brackets_query(query.as_ref())?; + self = self.with_brackets_query(query.as_ref()).context("Error loading brackets query")?; } if let Some(query) = queries.indents { - self = self.with_indents_query(query.as_ref())?; + self = self.with_indents_query(query.as_ref()).context("Error loading indents query")?; } if let Some(query) = queries.outline { - self = self.with_outline_query(query.as_ref())?; + self = self.with_outline_query(query.as_ref()).context("Error loading outline query")?; } if let Some(query) = queries.embedding { - self = self.with_embedding_query(query.as_ref())?; + self = self.with_embedding_query(query.as_ref()).context("Error loading embedding query")?; } if let Some(query) = queries.injections { - self = self.with_injection_query(query.as_ref())?; + self = self.with_injection_query(query.as_ref()).context("Error loading injection query")?; } if let Some(query) = queries.overrides { - self = self.with_override_query(query.as_ref())?; + self = self.with_override_query(query.as_ref()).context("Error loading override query")?; } Ok(self) } From a829b5be01659953d133c3b6ee284770fa1f3879 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 27 Jul 2023 11:14:21 -0700 Subject: [PATCH 072/160] fmt --- crates/language/src/language.rs | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index b265bba7b56267c63af402db361be338fbebd27d..125e14d445f3872e9718cb2759016a09b0c28439 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -1188,25 +1188,39 @@ impl Language { pub fn with_queries(mut self, queries: LanguageQueries) -> Result { if let Some(query) = queries.highlights { - self = self.with_highlights_query(query.as_ref()).context("Error loading highlights query")?; + self = self + .with_highlights_query(query.as_ref()) + .context("Error loading highlights query")?; } if let Some(query) = queries.brackets { - self = self.with_brackets_query(query.as_ref()).context("Error loading brackets query")?; + self = self + .with_brackets_query(query.as_ref()) + .context("Error loading brackets query")?; } if let Some(query) = queries.indents { - self = self.with_indents_query(query.as_ref()).context("Error loading indents query")?; + self = self + .with_indents_query(query.as_ref()) + .context("Error loading indents query")?; } if let Some(query) = queries.outline { - self = self.with_outline_query(query.as_ref()).context("Error loading outline query")?; + self = self + .with_outline_query(query.as_ref()) + .context("Error loading outline query")?; } if let Some(query) = queries.embedding { - self = self.with_embedding_query(query.as_ref()).context("Error loading embedding query")?; + self = self + .with_embedding_query(query.as_ref()) + .context("Error loading embedding query")?; } if let Some(query) = queries.injections { - self = self.with_injection_query(query.as_ref()).context("Error loading injection query")?; + self = self + .with_injection_query(query.as_ref()) + .context("Error loading injection query")?; } if let Some(query) = queries.overrides { - self = self.with_override_query(query.as_ref()).context("Error loading override query")?; + self = self + .with_override_query(query.as_ref()) + .context("Error loading override query")?; } Ok(self) } From 7a9af7c663e7669fd1147bca7aecb89f969d1e89 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Thu, 27 Jul 2023 15:17:13 -0400 Subject: [PATCH 073/160] Publish preview releases to discord --- .github/workflows/release_actions.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/release_actions.yml b/.github/workflows/release_actions.yml index 71909ae1771637ed099e532266d740dfe3361a2f..6c3b3d57c0b49453c66597b133b2893e898f398e 100644 --- a/.github/workflows/release_actions.yml +++ b/.github/workflows/release_actions.yml @@ -8,7 +8,6 @@ jobs: steps: - name: Discord Webhook Action uses: tsickert/discord-webhook@v5.3.0 - if: ${{ ! github.event.release.prerelease }} with: webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} content: | From 39794544852192000ec524d6aa94179732ff6fb9 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Thu, 27 Jul 2023 17:13:37 -0400 Subject: [PATCH 074/160] Follow naming convention for menu items --- crates/collab_ui/src/collab_titlebar_item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/collab_ui/src/collab_titlebar_item.rs b/crates/collab_ui/src/collab_titlebar_item.rs index ce8d10d655d76b018aef855a934c95e1d7b1640c..a54c0e9e7950634f64fe123cfb560e1e1f1f28dc 100644 --- a/crates/collab_ui/src/collab_titlebar_item.rs +++ b/crates/collab_ui/src/collab_titlebar_item.rs @@ -374,7 +374,7 @@ impl CollabTitlebarItem { "Share Feedback", feedback::feedback_editor::GiveFeedback, ), - ContextMenuItem::action("Sign out", SignOut), + ContextMenuItem::action("Sign Out", SignOut), ] } else { vec![ From fc9687d16334ac33f482630f9a9330bc24bd8edb Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 27 Jul 2023 18:27:36 -0400 Subject: [PATCH 075/160] Avoid panic by accessing view handle by global in wrong window View handles are window specific but this global will be doing things in all windows, that would cause a panic when it attempted to update a status bar mode indicator in a background window Co-Authored-By: Mikayla Maki --- crates/vim/src/mode_indicator.rs | 61 +++++++++++++++++++++---- crates/vim/src/test.rs | 14 +++--- crates/vim/src/test/vim_test_context.rs | 4 ++ crates/vim/src/vim.rs | 51 +++------------------ crates/zed/src/zed.rs | 2 + 5 files changed, 72 insertions(+), 60 deletions(-) diff --git a/crates/vim/src/mode_indicator.rs b/crates/vim/src/mode_indicator.rs index e0d2b65955489ae72742febd13de1b0c5e1e5e41..84e3e5868a42f8b3f360af2d7b0e17a8f17fc015 100644 --- a/crates/vim/src/mode_indicator.rs +++ b/crates/vim/src/mode_indicator.rs @@ -1,20 +1,60 @@ -use gpui::{elements::Label, AnyElement, Element, Entity, View, ViewContext}; +use gpui::{ + elements::{Empty, Label}, + AnyElement, Element, Entity, Subscription, View, ViewContext, +}; +use settings::SettingsStore; use workspace::{item::ItemHandle, StatusItemView}; -use crate::state::Mode; +use crate::{state::Mode, Vim, VimEvent, VimModeSetting}; pub struct ModeIndicator { - pub mode: Mode, + pub mode: Option, + _subscription: Subscription, } impl ModeIndicator { - pub fn new(mode: Mode) -> Self { - Self { mode } + pub fn new(cx: &mut ViewContext) -> Self { + let handle = cx.handle().downgrade(); + + let _subscription = cx.subscribe_global::(move |&event, cx| { + if let Some(mode_indicator) = handle.upgrade(cx) { + match event { + VimEvent::ModeChanged { mode } => { + cx.update_window(mode_indicator.window_id(), |cx| { + mode_indicator.update(cx, move |mode_indicator, cx| { + mode_indicator.set_mode(mode, cx); + }) + }); + } + } + } + }); + + cx.observe_global::(move |mode_indicator, cx| { + if settings::get::(cx).0 { + mode_indicator.mode = cx + .has_global::() + .then(|| cx.global::().state.mode); + } else { + mode_indicator.mode.take(); + } + }) + .detach(); + + // Vim doesn't exist in some tests + let mode = cx + .has_global::() + .then(|| cx.global::().state.mode); + + Self { + mode, + _subscription, + } } pub fn set_mode(&mut self, mode: Mode, cx: &mut ViewContext) { - if mode != self.mode { - self.mode = mode; + if self.mode != Some(mode) { + self.mode = Some(mode); cx.notify(); } } @@ -30,11 +70,16 @@ impl View for ModeIndicator { } fn render(&mut self, cx: &mut ViewContext) -> AnyElement { + let Some(mode) = self.mode.as_ref() else { + return Empty::new().into_any(); + }; + let theme = &theme::current(cx).workspace.status_bar; + // we always choose text to be 12 monospace characters // so that as the mode indicator changes, the rest of the // UI stays still. - let text = match self.mode { + let text = match mode { Mode::Normal => "-- NORMAL --", Mode::Insert => "-- INSERT --", Mode::Visual { line: false } => "-- VISUAL --", diff --git a/crates/vim/src/test.rs b/crates/vim/src/test.rs index 96d6a2b69019d47ef7d131f1ef66d6c218089ec1..98d8cb8749996909757367c36e2591817030bebe 100644 --- a/crates/vim/src/test.rs +++ b/crates/vim/src/test.rs @@ -215,7 +215,7 @@ async fn test_status_indicator( assert_eq!( cx.workspace(|_, cx| mode_indicator.read(cx).mode), - Mode::Normal + Some(Mode::Normal) ); // shows the correct mode @@ -223,7 +223,7 @@ async fn test_status_indicator( deterministic.run_until_parked(); assert_eq!( cx.workspace(|_, cx| mode_indicator.read(cx).mode), - Mode::Insert + Some(Mode::Insert) ); // shows even in search @@ -231,7 +231,7 @@ async fn test_status_indicator( deterministic.run_until_parked(); assert_eq!( cx.workspace(|_, cx| mode_indicator.read(cx).mode), - Mode::Visual { line: false } + Some(Mode::Visual { line: false }) ); // hides if vim mode is disabled @@ -239,15 +239,15 @@ async fn test_status_indicator( deterministic.run_until_parked(); cx.workspace(|workspace, cx| { let status_bar = workspace.status_bar().read(cx); - let mode_indicator = status_bar.item_of_type::(); - assert!(mode_indicator.is_none()); + let mode_indicator = status_bar.item_of_type::().unwrap(); + assert!(mode_indicator.read(cx).mode.is_none()); }); cx.enable_vim(); deterministic.run_until_parked(); cx.workspace(|workspace, cx| { let status_bar = workspace.status_bar().read(cx); - let mode_indicator = status_bar.item_of_type::(); - assert!(mode_indicator.is_some()); + let mode_indicator = status_bar.item_of_type::().unwrap(); + assert!(mode_indicator.read(cx).mode.is_some()); }); } diff --git a/crates/vim/src/test/vim_test_context.rs b/crates/vim/src/test/vim_test_context.rs index 56ca654644c5277fc8eca5e8fcd769815a6a356c..ea09e550916c4355b10d12b6d3a5a2207112dd16 100644 --- a/crates/vim/src/test/vim_test_context.rs +++ b/crates/vim/src/test/vim_test_context.rs @@ -43,6 +43,10 @@ impl<'a> VimTestContext<'a> { toolbar.add_item(project_search_bar, cx); }) }); + workspace.status_bar().update(cx, |status_bar, cx| { + let vim_mode_indicator = cx.add_view(ModeIndicator::new); + status_bar.add_right_item(vim_mode_indicator, cx); + }); }); Self { cx } diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index d8edf1a667ff06a17e50c4ef69f95e82c1570ba2..22bd196c678d72b40949ffc8171afa3444c4e447 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -43,6 +43,11 @@ struct Number(u8); actions!(vim, [Tab, Enter]); impl_actions!(vim, [Number, SwitchMode, PushOperator]); +#[derive(Copy, Clone, Debug)] +enum VimEvent { + ModeChanged { mode: Mode }, +} + pub fn init(cx: &mut AppContext) { settings::register::(cx); @@ -121,8 +126,6 @@ pub fn observe_keystrokes(cx: &mut WindowContext) { pub struct Vim { active_editor: Option>, editor_subscription: Option, - mode_indicator: Option>, - enabled: bool, state: VimState, } @@ -181,9 +184,7 @@ impl Vim { self.state.mode = mode; self.state.operator_stack.clear(); - if let Some(mode_indicator) = &self.mode_indicator { - mode_indicator.update(cx, |mode_indicator, cx| mode_indicator.set_mode(mode, cx)) - } + cx.emit_global(VimEvent::ModeChanged { mode }); // Sync editor settings like clip mode self.sync_vim_settings(cx); @@ -271,44 +272,6 @@ impl Vim { } } - fn sync_mode_indicator(cx: &mut WindowContext) { - let Some(workspace) = cx.root_view() - .downcast_ref::() - .map(|workspace| workspace.downgrade()) else { - return; - }; - - cx.spawn(|mut cx| async move { - workspace.update(&mut cx, |workspace, cx| { - Vim::update(cx, |vim, cx| { - workspace.status_bar().update(cx, |status_bar, cx| { - let current_position = status_bar.position_of_item::(); - - if vim.enabled && current_position.is_none() { - if vim.mode_indicator.is_none() { - vim.mode_indicator = - Some(cx.add_view(|_| ModeIndicator::new(vim.state.mode))); - }; - let mode_indicator = vim.mode_indicator.as_ref().unwrap(); - let position = status_bar - .position_of_item::(); - if let Some(position) = position { - status_bar.insert_item_after(position, mode_indicator.clone(), cx) - } else { - status_bar.add_left_item(mode_indicator.clone(), cx) - } - } else if !vim.enabled { - if let Some(position) = current_position { - status_bar.remove_item_at(position, cx) - } - } - }) - }) - }) - }) - .detach_and_log_err(cx); - } - fn set_enabled(&mut self, enabled: bool, cx: &mut AppContext) { if self.enabled != enabled { self.enabled = enabled; @@ -359,8 +322,6 @@ impl Vim { self.unhook_vim_settings(editor, cx); } }); - - Vim::sync_mode_indicator(cx); } fn unhook_vim_settings(&self, editor: &mut Editor, cx: &mut ViewContext) { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 84cef99f81e41d0b43909ab2368e3366a7257d26..a29567ac385633af04b7e7c3f4b2c0de595d892c 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -308,6 +308,7 @@ pub fn initialize_workspace( ); let active_buffer_language = cx.add_view(|_| language_selector::ActiveBufferLanguage::new(workspace)); + let vim_mode_indicator = cx.add_view(|cx| vim::ModeIndicator::new(cx)); let feedback_button = cx.add_view(|_| { feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace) }); @@ -319,6 +320,7 @@ pub fn initialize_workspace( status_bar.add_right_item(feedback_button, cx); status_bar.add_right_item(copilot, cx); status_bar.add_right_item(active_buffer_language, cx); + status_bar.add_right_item(vim_mode_indicator, cx); status_bar.add_right_item(cursor_position, cx); }); From 03bc430bdd82422dc01813f859a8ff8e201212a6 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 27 Jul 2023 16:14:56 -0700 Subject: [PATCH 076/160] Make mode indicator follow vim enabled state --- crates/vim/src/mode_indicator.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/vim/src/mode_indicator.rs b/crates/vim/src/mode_indicator.rs index 84e3e5868a42f8b3f360af2d7b0e17a8f17fc015..639a7594f113c61bc8c232325ac8d769b2ac89e5 100644 --- a/crates/vim/src/mode_indicator.rs +++ b/crates/vim/src/mode_indicator.rs @@ -44,7 +44,11 @@ impl ModeIndicator { // Vim doesn't exist in some tests let mode = cx .has_global::() - .then(|| cx.global::().state.mode); + .then(|| { + let vim = cx.global::(); + vim.enabled.then(|| vim.state.mode) + }) + .flatten(); Self { mode, From 1935307b4f6b80438df46719ab5202ea7bd26850 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Thu, 27 Jul 2023 18:08:15 -0600 Subject: [PATCH 077/160] Fix jumping to definition in a new file This is broken because vim currently sets settings only on the active editor. Fix this by correcting the range on the currently active editor. It would be nice (at some point) to refactor how vim sets settings, but that's for another day. --- crates/editor/src/editor.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index e05837740d4c50fbe7e02e51272bd6340884ec8a..7af3f5460def3d55a9d661e3b29724e0d392e637 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -6374,8 +6374,8 @@ impl Editor { .range .to_offset(definition.target.buffer.read(cx)); + let range = self.range_for_match(&range); if Some(&definition.target.buffer) == self.buffer.read(cx).as_singleton().as_ref() { - let range = self.range_for_match(&range); self.change_selections(Some(Autoscroll::fit()), cx, |s| { s.select_ranges([range]); }); @@ -6392,7 +6392,6 @@ impl Editor { // When selecting a definition in a different buffer, disable the nav history // to avoid creating a history entry at the previous cursor location. pane.update(cx, |pane, _| pane.disable_history()); - let range = target_editor.range_for_match(&range); target_editor.change_selections(Some(Autoscroll::fit()), cx, |s| { s.select_ranges([range]); }); From f15a03816f9357522a3793fbba449818dc9ed67e Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 27 Jul 2023 17:19:32 -0700 Subject: [PATCH 078/160] underscore arguments --- crates/zed/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index df16ea7db97fbbd2acfb005be15ff45af7ef4ad1..b9fefb89a73555a16a03d9d7e34fa5369d3abde4 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -717,7 +717,7 @@ async fn watch_languages(_: Arc, _: Arc) -> Option<()> } #[cfg(not(debug_assertions))] -fn watch_file_types(fs: Arc, cx: &mut AppContext) {} +fn watch_file_types(_fs: Arc, _cx: &mut AppContext) {} fn connect_to_cli( server_name: &str, From 0dffb728db4287376c1fc9214e2de3b7aee2d06e Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 27 Jul 2023 17:36:02 -0700 Subject: [PATCH 079/160] Update elixir depedency co-authored-by: Alex --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c6a213d0d4e36a427fc4352b2e417258f12de8f..9de3e6f4a69fb14351504b66a59f293069978381 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3851,7 +3851,7 @@ dependencies = [ "text", "theme", "tree-sitter", - "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=4ba9dab6e2602960d95b2b625f3386c27e08084e)", + "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=2616034f78ffa83ca6a521ebd7eee1868cb5c14c)", "tree-sitter-embedded-template", "tree-sitter-heex", "tree-sitter-html", @@ -8287,7 +8287,7 @@ dependencies = [ [[package]] name = "tree-sitter-elixir" version = "0.1.0" -source = "git+https://github.com/elixir-lang/tree-sitter-elixir?rev=4ba9dab6e2602960d95b2b625f3386c27e08084e#4ba9dab6e2602960d95b2b625f3386c27e08084e" +source = "git+https://github.com/elixir-lang/tree-sitter-elixir?rev=2616034f78ffa83ca6a521ebd7eee1868cb5c14c#2616034f78ffa83ca6a521ebd7eee1868cb5c14c" dependencies = [ "cc", "tree-sitter", @@ -9923,7 +9923,7 @@ dependencies = [ "tree-sitter-c", "tree-sitter-cpp 0.20.0", "tree-sitter-css", - "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=4ba9dab6e2602960d95b2b625f3386c27e08084e)", + "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=2616034f78ffa83ca6a521ebd7eee1868cb5c14c)", "tree-sitter-elm", "tree-sitter-embedded-template", "tree-sitter-glsl", diff --git a/Cargo.toml b/Cargo.toml index fc46286de0c78f286e9d110aed41fe41bf3902d3..19d43a1b95bc3f7ebf4c482dad8d1a4607faa8c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -111,7 +111,7 @@ tree-sitter-bash = { git = "https://github.com/tree-sitter/tree-sitter-bash", re tree-sitter-c = "0.20.1" tree-sitter-cpp = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev="f44509141e7e483323d2ec178f2d2e6c0fc041c1" } tree-sitter-css = { git = "https://github.com/tree-sitter/tree-sitter-css", rev = "769203d0f9abe1a9a691ac2b9fe4bb4397a73c51" } -tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "4ba9dab6e2602960d95b2b625f3386c27e08084e" } +tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "2616034f78ffa83ca6a521ebd7eee1868cb5c14c" } tree-sitter-elm = { git = "https://github.com/elm-tooling/tree-sitter-elm", rev = "692c50c0b961364c40299e73c1306aecb5d20f40"} tree-sitter-embedded-template = "0.20.0" tree-sitter-glsl = { git = "https://github.com/theHamsta/tree-sitter-glsl", rev = "2a56fb7bc8bb03a1892b4741279dd0a8758b7fb3" } From 45e5d816649242b058c19979779c0b04c3d9de17 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 27 Jul 2023 17:41:13 -0700 Subject: [PATCH 080/160] update to dependency without symbol conflict --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9de3e6f4a69fb14351504b66a59f293069978381..04ee8c2212f0296c8f1af116823296bb51b49e59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3851,7 +3851,7 @@ dependencies = [ "text", "theme", "tree-sitter", - "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=2616034f78ffa83ca6a521ebd7eee1868cb5c14c)", + "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=a2861e88a730287a60c11ea9299c033c7d076e30)", "tree-sitter-embedded-template", "tree-sitter-heex", "tree-sitter-html", @@ -8287,7 +8287,7 @@ dependencies = [ [[package]] name = "tree-sitter-elixir" version = "0.1.0" -source = "git+https://github.com/elixir-lang/tree-sitter-elixir?rev=2616034f78ffa83ca6a521ebd7eee1868cb5c14c#2616034f78ffa83ca6a521ebd7eee1868cb5c14c" +source = "git+https://github.com/elixir-lang/tree-sitter-elixir?rev=a2861e88a730287a60c11ea9299c033c7d076e30#a2861e88a730287a60c11ea9299c033c7d076e30" dependencies = [ "cc", "tree-sitter", @@ -9923,7 +9923,7 @@ dependencies = [ "tree-sitter-c", "tree-sitter-cpp 0.20.0", "tree-sitter-css", - "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=2616034f78ffa83ca6a521ebd7eee1868cb5c14c)", + "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=a2861e88a730287a60c11ea9299c033c7d076e30)", "tree-sitter-elm", "tree-sitter-embedded-template", "tree-sitter-glsl", diff --git a/Cargo.toml b/Cargo.toml index 19d43a1b95bc3f7ebf4c482dad8d1a4607faa8c8..157db0635f7bcc490ba207c6c0932899cfd6abf0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -111,7 +111,7 @@ tree-sitter-bash = { git = "https://github.com/tree-sitter/tree-sitter-bash", re tree-sitter-c = "0.20.1" tree-sitter-cpp = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev="f44509141e7e483323d2ec178f2d2e6c0fc041c1" } tree-sitter-css = { git = "https://github.com/tree-sitter/tree-sitter-css", rev = "769203d0f9abe1a9a691ac2b9fe4bb4397a73c51" } -tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "2616034f78ffa83ca6a521ebd7eee1868cb5c14c" } +tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "a2861e88a730287a60c11ea9299c033c7d076e30" } tree-sitter-elm = { git = "https://github.com/elm-tooling/tree-sitter-elm", rev = "692c50c0b961364c40299e73c1306aecb5d20f40"} tree-sitter-embedded-template = "0.20.0" tree-sitter-glsl = { git = "https://github.com/theHamsta/tree-sitter-glsl", rev = "2a56fb7bc8bb03a1892b4741279dd0a8758b7fb3" } From a0fc515cfca9677dde32cef8be22321d1304a13e Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 27 Jul 2023 17:58:43 -0700 Subject: [PATCH 081/160] Rework close_inactive_items to await all tasks Update action name to be more accurate --- assets/keymaps/default.json | 2 +- crates/workspace/src/pane.rs | 4 +++ crates/workspace/src/workspace.rs | 42 ++++++++++++++++++++----------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 5c841d19b2ca1b5bf54e5ca93c5f7d10341876b5..090385458efd1bb43cce6d83615fbbaf8dbc6166 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -22,7 +22,7 @@ "alt-cmd-right": "pane::ActivateNextItem", "cmd-w": "pane::CloseActiveItem", "alt-cmd-t": "pane::CloseInactiveItems", - "ctrl-alt-cmd-w": "workspace::CloseInactiveEditors", + "ctrl-alt-cmd-w": "workspace::CloseInactiveTabsAndPanes", "cmd-k u": "pane::CloseCleanItems", "cmd-k cmd-w": "pane::CloseAllItems", "cmd-shift-w": "workspace::CloseWindow", diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 2972c307f2624a6bb23bef0f1919aab5a43eb66d..ee658c9cc92b3a4fa24a56f986e895547a190ad1 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -746,6 +746,10 @@ impl Pane { _: &CloseAllItems, cx: &mut ViewContext, ) -> Option>> { + if self.items.is_empty() { + return None; + } + Some(self.close_items(cx, move |_| true)) } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 6694cc06a32ff416323cea047539759a8ee62e39..827b0b8427c0bf4e0f25237d664489f747199592 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -21,6 +21,7 @@ use drag_and_drop::DragAndDrop; use futures::{ channel::{mpsc, oneshot}, future::try_join_all, + stream::FuturesUnordered, FutureExt, StreamExt, }; use gpui::{ @@ -122,7 +123,7 @@ actions!( NewFile, NewWindow, CloseWindow, - CloseInactiveEditors, + CloseInactiveTabsAndPanes, AddFolderToProject, Unfollow, Save, @@ -240,7 +241,7 @@ pub fn init(app_state: Arc, cx: &mut AppContext) { cx.add_async_action(Workspace::follow_next_collaborator); cx.add_async_action(Workspace::close); - cx.add_async_action(Workspace::close_inactive_editors); + cx.add_async_action(Workspace::close_inactive_items_and_panes); cx.add_global_action(Workspace::close_global); cx.add_global_action(restart); cx.add_async_action(Workspace::save_all); @@ -1635,32 +1636,43 @@ impl Workspace { } } - pub fn close_inactive_editors( + pub fn close_inactive_items_and_panes( &mut self, - _: &CloseInactiveEditors, + _: &CloseInactiveTabsAndPanes, cx: &mut ViewContext, ) -> Option>> { let current_pane = self.active_pane(); - // let mut tasks: Vec>> = Vec::new(); - current_pane - .update(cx, |pane, cx| { - pane.close_inactive_items(&CloseInactiveItems, cx).unwrap() - }) - .detach_and_log_err(cx); + let mut tasks = Vec::new(); + + if let Some(current_pane_close) = current_pane.update(cx, |pane, cx| { + pane.close_inactive_items(&CloseInactiveItems, cx) + }) { + tasks.push(current_pane_close); + }; for pane in self.panes() { if pane.id() == current_pane.id() { continue; } - pane.update(cx, |pane: &mut Pane, cx| { - pane.close_all_items(&CloseAllItems, cx).unwrap() - }) - .detach_and_log_err(cx); + if let Some(close_pane_items) = pane.update(cx, |pane: &mut Pane, cx| { + pane.close_all_items(&CloseAllItems, cx) + }) { + tasks.push(close_pane_items) + } } - Some(Task::ready(Ok(()))) + if tasks.is_empty() { + None + } else { + Some(cx.spawn(|_, _| async move { + for task in tasks { + task.await? + } + Ok(()) + })) + } } pub fn toggle_dock(&mut self, dock_side: DockPosition, cx: &mut ViewContext) { From 4735b07088269e5b99e9299dbb9dd620e70f4497 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 27 Jul 2023 18:00:33 -0700 Subject: [PATCH 082/160] Fix warning --- crates/workspace/src/workspace.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 827b0b8427c0bf4e0f25237d664489f747199592..a8ba017655a8a6546ed641e5714f2db1f5663cc5 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -21,7 +21,6 @@ use drag_and_drop::DragAndDrop; use futures::{ channel::{mpsc, oneshot}, future::try_join_all, - stream::FuturesUnordered, FutureExt, StreamExt, }; use gpui::{ From cf6e524c9a5f2fecbfbad9675e37cafd746c002c Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 28 Jul 2023 12:56:44 +0300 Subject: [PATCH 083/160] Make project search includes and excludes more user-friendly Allow search results that start with the include/exclude path part --- crates/project/src/project_tests.rs | 55 ++++---- crates/project/src/search.rs | 117 +++++++++++++++--- crates/search/src/project_search.rs | 84 ++++--------- crates/semantic_index/src/db.rs | 17 +-- crates/semantic_index/src/semantic_index.rs | 14 +-- .../src/semantic_index_tests.rs | 7 +- 6 files changed, 160 insertions(+), 134 deletions(-) diff --git a/crates/project/src/project_tests.rs b/crates/project/src/project_tests.rs index 16e706a77eeb9b4a92a368d7bb653639d24e9814..259c10ca057c8bb29ad5b2d805107eb982239441 100644 --- a/crates/project/src/project_tests.rs +++ b/crates/project/src/project_tests.rs @@ -1,7 +1,6 @@ -use crate::{worktree::WorktreeHandle, Event, *}; +use crate::{search::PathMatcher, worktree::WorktreeHandle, Event, *}; use fs::{FakeFs, LineEnding, RealFs}; use futures::{future, StreamExt}; -use globset::Glob; use gpui::{executor::Deterministic, test::subscribe, AppContext}; use language::{ language_settings::{AllLanguageSettings, LanguageSettingsContent}, @@ -3641,7 +3640,7 @@ async fn test_search_with_inclusions(cx: &mut gpui::TestAppContext) { search_query, false, true, - vec![Glob::new("*.odd").unwrap().compile_matcher()], + vec![PathMatcher::new("*.odd").unwrap()], Vec::new() ), cx @@ -3659,7 +3658,7 @@ async fn test_search_with_inclusions(cx: &mut gpui::TestAppContext) { search_query, false, true, - vec![Glob::new("*.rs").unwrap().compile_matcher()], + vec![PathMatcher::new("*.rs").unwrap()], Vec::new() ), cx @@ -3681,8 +3680,8 @@ async fn test_search_with_inclusions(cx: &mut gpui::TestAppContext) { false, true, vec![ - Glob::new("*.ts").unwrap().compile_matcher(), - Glob::new("*.odd").unwrap().compile_matcher(), + PathMatcher::new("*.ts").unwrap(), + PathMatcher::new("*.odd").unwrap(), ], Vec::new() ), @@ -3705,9 +3704,9 @@ async fn test_search_with_inclusions(cx: &mut gpui::TestAppContext) { false, true, vec![ - Glob::new("*.rs").unwrap().compile_matcher(), - Glob::new("*.ts").unwrap().compile_matcher(), - Glob::new("*.odd").unwrap().compile_matcher(), + PathMatcher::new("*.rs").unwrap(), + PathMatcher::new("*.ts").unwrap(), + PathMatcher::new("*.odd").unwrap(), ], Vec::new() ), @@ -3752,7 +3751,7 @@ async fn test_search_with_exclusions(cx: &mut gpui::TestAppContext) { false, true, Vec::new(), - vec![Glob::new("*.odd").unwrap().compile_matcher()], + vec![PathMatcher::new("*.odd").unwrap()], ), cx ) @@ -3775,7 +3774,7 @@ async fn test_search_with_exclusions(cx: &mut gpui::TestAppContext) { false, true, Vec::new(), - vec![Glob::new("*.rs").unwrap().compile_matcher()], + vec![PathMatcher::new("*.rs").unwrap()], ), cx ) @@ -3797,8 +3796,8 @@ async fn test_search_with_exclusions(cx: &mut gpui::TestAppContext) { true, Vec::new(), vec![ - Glob::new("*.ts").unwrap().compile_matcher(), - Glob::new("*.odd").unwrap().compile_matcher(), + PathMatcher::new("*.ts").unwrap(), + PathMatcher::new("*.odd").unwrap(), ], ), cx @@ -3821,9 +3820,9 @@ async fn test_search_with_exclusions(cx: &mut gpui::TestAppContext) { true, Vec::new(), vec![ - Glob::new("*.rs").unwrap().compile_matcher(), - Glob::new("*.ts").unwrap().compile_matcher(), - Glob::new("*.odd").unwrap().compile_matcher(), + PathMatcher::new("*.rs").unwrap(), + PathMatcher::new("*.ts").unwrap(), + PathMatcher::new("*.odd").unwrap(), ], ), cx @@ -3860,8 +3859,8 @@ async fn test_search_with_exclusions_and_inclusions(cx: &mut gpui::TestAppContex search_query, false, true, - vec![Glob::new("*.odd").unwrap().compile_matcher()], - vec![Glob::new("*.odd").unwrap().compile_matcher()], + vec![PathMatcher::new("*.odd").unwrap()], + vec![PathMatcher::new("*.odd").unwrap()], ), cx ) @@ -3878,8 +3877,8 @@ async fn test_search_with_exclusions_and_inclusions(cx: &mut gpui::TestAppContex search_query, false, true, - vec![Glob::new("*.ts").unwrap().compile_matcher()], - vec![Glob::new("*.ts").unwrap().compile_matcher()], + vec![PathMatcher::new("*.ts").unwrap()], + vec![PathMatcher::new("*.ts").unwrap()], ), cx ) @@ -3897,12 +3896,12 @@ async fn test_search_with_exclusions_and_inclusions(cx: &mut gpui::TestAppContex false, true, vec![ - Glob::new("*.ts").unwrap().compile_matcher(), - Glob::new("*.odd").unwrap().compile_matcher() + PathMatcher::new("*.ts").unwrap(), + PathMatcher::new("*.odd").unwrap() ], vec![ - Glob::new("*.ts").unwrap().compile_matcher(), - Glob::new("*.odd").unwrap().compile_matcher() + PathMatcher::new("*.ts").unwrap(), + PathMatcher::new("*.odd").unwrap() ], ), cx @@ -3921,12 +3920,12 @@ async fn test_search_with_exclusions_and_inclusions(cx: &mut gpui::TestAppContex false, true, vec![ - Glob::new("*.ts").unwrap().compile_matcher(), - Glob::new("*.odd").unwrap().compile_matcher() + PathMatcher::new("*.ts").unwrap(), + PathMatcher::new("*.odd").unwrap() ], vec![ - Glob::new("*.rs").unwrap().compile_matcher(), - Glob::new("*.odd").unwrap().compile_matcher() + PathMatcher::new("*.rs").unwrap(), + PathMatcher::new("*.odd").unwrap() ], ), cx diff --git a/crates/project/src/search.rs b/crates/project/src/search.rs index 4b4126fef2e1f8f4cb403c809ca62a136cff5afb..71a0b70b81b7a6f08a2584064a55a07743096b2c 100644 --- a/crates/project/src/search.rs +++ b/crates/project/src/search.rs @@ -1,5 +1,5 @@ use aho_corasick::{AhoCorasick, AhoCorasickBuilder}; -use anyhow::Result; +use anyhow::{Context, Result}; use client::proto; use globset::{Glob, GlobMatcher}; use itertools::Itertools; @@ -9,7 +9,7 @@ use smol::future::yield_now; use std::{ io::{BufRead, BufReader, Read}, ops::Range, - path::Path, + path::{Path, PathBuf}, sync::Arc, }; @@ -20,8 +20,8 @@ pub enum SearchQuery { query: Arc, whole_word: bool, case_sensitive: bool, - files_to_include: Vec, - files_to_exclude: Vec, + files_to_include: Vec, + files_to_exclude: Vec, }, Regex { regex: Regex, @@ -29,18 +29,43 @@ pub enum SearchQuery { multiline: bool, whole_word: bool, case_sensitive: bool, - files_to_include: Vec, - files_to_exclude: Vec, + files_to_include: Vec, + files_to_exclude: Vec, }, } +#[derive(Clone, Debug)] +pub struct PathMatcher { + maybe_path: PathBuf, + glob: GlobMatcher, +} + +impl std::fmt::Display for PathMatcher { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.maybe_path.to_string_lossy().fmt(f) + } +} + +impl PathMatcher { + pub fn new(maybe_glob: &str) -> Result { + Ok(PathMatcher { + glob: Glob::new(&maybe_glob)?.compile_matcher(), + maybe_path: PathBuf::from(maybe_glob), + }) + } + + pub fn is_match>(&self, other: P) -> bool { + other.as_ref().starts_with(&self.maybe_path) || self.glob.is_match(other) + } +} + impl SearchQuery { pub fn text( query: impl ToString, whole_word: bool, case_sensitive: bool, - files_to_include: Vec, - files_to_exclude: Vec, + files_to_include: Vec, + files_to_exclude: Vec, ) -> Self { let query = query.to_string(); let search = AhoCorasickBuilder::new() @@ -61,8 +86,8 @@ impl SearchQuery { query: impl ToString, whole_word: bool, case_sensitive: bool, - files_to_include: Vec, - files_to_exclude: Vec, + files_to_include: Vec, + files_to_exclude: Vec, ) -> Result { let mut query = query.to_string(); let initial_query = Arc::from(query.as_str()); @@ -96,16 +121,16 @@ impl SearchQuery { message.query, message.whole_word, message.case_sensitive, - deserialize_globs(&message.files_to_include)?, - deserialize_globs(&message.files_to_exclude)?, + deserialize_path_matches(&message.files_to_include)?, + deserialize_path_matches(&message.files_to_exclude)?, ) } else { Ok(Self::text( message.query, message.whole_word, message.case_sensitive, - deserialize_globs(&message.files_to_include)?, - deserialize_globs(&message.files_to_exclude)?, + deserialize_path_matches(&message.files_to_include)?, + deserialize_path_matches(&message.files_to_exclude)?, )) } } @@ -120,12 +145,12 @@ impl SearchQuery { files_to_include: self .files_to_include() .iter() - .map(|g| g.glob().to_string()) + .map(|matcher| matcher.to_string()) .join(","), files_to_exclude: self .files_to_exclude() .iter() - .map(|g| g.glob().to_string()) + .map(|matcher| matcher.to_string()) .join(","), } } @@ -266,7 +291,7 @@ impl SearchQuery { matches!(self, Self::Regex { .. }) } - pub fn files_to_include(&self) -> &[GlobMatcher] { + pub fn files_to_include(&self) -> &[PathMatcher] { match self { Self::Text { files_to_include, .. @@ -277,7 +302,7 @@ impl SearchQuery { } } - pub fn files_to_exclude(&self) -> &[GlobMatcher] { + pub fn files_to_exclude(&self) -> &[PathMatcher] { match self { Self::Text { files_to_exclude, .. @@ -306,11 +331,63 @@ impl SearchQuery { } } -fn deserialize_globs(glob_set: &str) -> Result> { +fn deserialize_path_matches(glob_set: &str) -> anyhow::Result> { glob_set .split(',') .map(str::trim) .filter(|glob_str| !glob_str.is_empty()) - .map(|glob_str| Ok(Glob::new(glob_str)?.compile_matcher())) + .map(|glob_str| { + PathMatcher::new(glob_str) + .with_context(|| format!("deserializing path match glob {glob_str}")) + }) .collect() } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn path_matcher_creation_for_valid_paths() { + for valid_path in [ + "file", + "Cargo.toml", + ".DS_Store", + "~/dir/another_dir/", + "./dir/file", + "dir/[a-z].txt", + "../dir/filé", + ] { + let path_matcher = PathMatcher::new(valid_path).unwrap_or_else(|e| { + panic!("Valid path {valid_path} should be accepted, but got: {e}") + }); + assert!( + path_matcher.is_match(valid_path), + "Path matcher for valid path {valid_path} should match itself" + ) + } + } + + #[test] + fn path_matcher_creation_for_globs() { + for invalid_glob in ["dir/[].txt", "dir/[a-z.txt", "dir/{file"] { + match PathMatcher::new(invalid_glob) { + Ok(_) => panic!("Invalid glob {invalid_glob} should not be accepted"), + Err(_expected) => {} + } + } + + for valid_glob in [ + "dir/?ile", + "dir/*.txt", + "dir/**/file", + "dir/[a-z].txt", + "{dir,file}", + ] { + match PathMatcher::new(valid_glob) { + Ok(_expected) => {} + Err(e) => panic!("Valid glob {valid_glob} should be accepted, but got: {e}"), + } + } + } +} diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 52ee12c26de17274d5cd8c5d39a69843cbcb7869..d6d69e575fdfa01a77c92b62efacfa45c31de23d 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -2,14 +2,13 @@ use crate::{ SearchOptions, SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleRegex, ToggleWholeWord, }; -use anyhow::Result; +use anyhow::Context; use collections::HashMap; use editor::{ items::active_match_index, scroll::autoscroll::Autoscroll, Anchor, Editor, MultiBuffer, SelectAll, MAX_TAB_TITLE_LEN, }; use futures::StreamExt; -use globset::{Glob, GlobMatcher}; use gpui::{ actions, elements::*, @@ -19,7 +18,10 @@ use gpui::{ }; use menu::Confirm; use postage::stream::Stream; -use project::{search::SearchQuery, Entry, Project}; +use project::{ + search::{PathMatcher, SearchQuery}, + Entry, Project, +}; use semantic_index::SemanticIndex; use smallvec::SmallVec; use std::{ @@ -185,21 +187,15 @@ impl ProjectSearch { cx.notify(); } - fn semantic_search( - &mut self, - query: String, - include_files: Vec, - exclude_files: Vec, - cx: &mut ModelContext, - ) { + fn semantic_search(&mut self, query: SearchQuery, cx: &mut ModelContext) { let search = SemanticIndex::global(cx).map(|index| { index.update(cx, |semantic_index, cx| { semantic_index.search_project( self.project.clone(), - query.clone(), + query.as_str().to_owned(), 10, - include_files, - exclude_files, + query.files_to_include().to_vec(), + query.files_to_exclude().to_vec(), cx, ) }) @@ -590,8 +586,7 @@ impl ProjectSearchView { if !dir_entry.is_dir() { return; } - let filter_path = dir_entry.path.join("**"); - let Some(filter_str) = filter_path.to_str() else { return; }; + let Some(filter_str) = dir_entry.path.to_str() else { return; }; let model = cx.add_model(|cx| ProjectSearch::new(workspace.project().clone(), cx)); let search = cx.add_view(|cx| ProjectSearchView::new(model, cx)); @@ -662,16 +657,10 @@ impl ProjectSearchView { if semantic.outstanding_file_count > 0 { return; } - - let query = self.query_editor.read(cx).text(cx); - if let Some((included_files, exclude_files)) = - self.get_included_and_excluded_globsets(cx) - { - self.model.update(cx, |model, cx| { - model.semantic_search(query, included_files, exclude_files, cx) - }); + if let Some(query) = self.build_search_query(cx) { + self.model + .update(cx, |model, cx| model.semantic_search(query, cx)); } - return; } if let Some(query) = self.build_search_query(cx) { @@ -679,42 +668,10 @@ impl ProjectSearchView { } } - fn get_included_and_excluded_globsets( - &mut self, - cx: &mut ViewContext, - ) -> Option<(Vec, Vec)> { - let included_files = - match Self::load_glob_set(&self.included_files_editor.read(cx).text(cx)) { - Ok(included_files) => { - self.panels_with_errors.remove(&InputPanel::Include); - included_files - } - Err(_e) => { - self.panels_with_errors.insert(InputPanel::Include); - cx.notify(); - return None; - } - }; - let excluded_files = - match Self::load_glob_set(&self.excluded_files_editor.read(cx).text(cx)) { - Ok(excluded_files) => { - self.panels_with_errors.remove(&InputPanel::Exclude); - excluded_files - } - Err(_e) => { - self.panels_with_errors.insert(InputPanel::Exclude); - cx.notify(); - return None; - } - }; - - Some((included_files, excluded_files)) - } - fn build_search_query(&mut self, cx: &mut ViewContext) -> Option { let text = self.query_editor.read(cx).text(cx); let included_files = - match Self::load_glob_set(&self.included_files_editor.read(cx).text(cx)) { + match Self::parse_path_matches(&self.included_files_editor.read(cx).text(cx)) { Ok(included_files) => { self.panels_with_errors.remove(&InputPanel::Include); included_files @@ -726,7 +683,7 @@ impl ProjectSearchView { } }; let excluded_files = - match Self::load_glob_set(&self.excluded_files_editor.read(cx).text(cx)) { + match Self::parse_path_matches(&self.excluded_files_editor.read(cx).text(cx)) { Ok(excluded_files) => { self.panels_with_errors.remove(&InputPanel::Exclude); excluded_files @@ -766,11 +723,14 @@ impl ProjectSearchView { } } - fn load_glob_set(text: &str) -> Result> { + fn parse_path_matches(text: &str) -> anyhow::Result> { text.split(',') .map(str::trim) - .filter(|glob_str| !glob_str.is_empty()) - .map(|glob_str| anyhow::Ok(Glob::new(glob_str)?.compile_matcher())) + .filter(|maybe_glob_str| !maybe_glob_str.is_empty()) + .map(|maybe_glob_str| { + PathMatcher::new(maybe_glob_str) + .with_context(|| format!("parsing {maybe_glob_str} as path matcher")) + }) .collect() } @@ -1769,7 +1729,7 @@ pub mod tests { search_view.included_files_editor.update(cx, |editor, cx| { assert_eq!( editor.display_text(cx), - a_dir_entry.path.join("**").display().to_string(), + a_dir_entry.path.to_str().unwrap(), "New search in directory should have included dir entry path" ); }); diff --git a/crates/semantic_index/src/db.rs b/crates/semantic_index/src/db.rs index d180f5e8314291593b1b343cd96527b1aea1d838..e8c929c99500c6a1da445b36d49ec007b4a6d997 100644 --- a/crates/semantic_index/src/db.rs +++ b/crates/semantic_index/src/db.rs @@ -1,7 +1,6 @@ use crate::{parsing::Document, SEMANTIC_INDEX_VERSION}; use anyhow::{anyhow, Context, Result}; -use globset::GlobMatcher; -use project::Fs; +use project::{search::PathMatcher, Fs}; use rpc::proto::Timestamp; use rusqlite::{ params, @@ -290,8 +289,8 @@ impl VectorDatabase { pub fn retrieve_included_file_ids( &self, worktree_ids: &[i64], - include_globs: Vec, - exclude_globs: Vec, + includes: &[PathMatcher], + excludes: &[PathMatcher], ) -> Result> { let mut file_query = self.db.prepare( " @@ -310,13 +309,9 @@ impl VectorDatabase { while let Some(row) = rows.next()? { let file_id = row.get(0)?; let relative_path = row.get_ref(1)?.as_str()?; - let included = include_globs.is_empty() - || include_globs - .iter() - .any(|glob| glob.is_match(relative_path)); - let excluded = exclude_globs - .iter() - .any(|glob| glob.is_match(relative_path)); + let included = + includes.is_empty() || includes.iter().any(|glob| glob.is_match(relative_path)); + let excluded = excludes.iter().any(|glob| glob.is_match(relative_path)); if included && !excluded { file_ids.push(file_id); } diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index bd114de216a0a30b3271b56c2b627439a7e70a0e..f1450eb7b0200d2f2dbedca9f46acb7db2a615a3 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -11,13 +11,12 @@ use anyhow::{anyhow, Result}; use db::VectorDatabase; use embedding::{EmbeddingProvider, OpenAIEmbeddings}; use futures::{channel::oneshot, Future}; -use globset::GlobMatcher; use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task, WeakModelHandle}; use language::{Anchor, Buffer, Language, LanguageRegistry}; use parking_lot::Mutex; use parsing::{CodeContextRetriever, Document, PARSEABLE_ENTIRE_FILE_TYPES}; use postage::watch; -use project::{Fs, Project, WorktreeId}; +use project::{search::PathMatcher, Fs, Project, WorktreeId}; use smol::channel; use std::{ cmp::Ordering, @@ -682,8 +681,8 @@ impl SemanticIndex { project: ModelHandle, phrase: String, limit: usize, - include_globs: Vec, - exclude_globs: Vec, + includes: Vec, + excludes: Vec, cx: &mut ModelContext, ) -> Task>> { let project_state = if let Some(state) = self.projects.get(&project.downgrade()) { @@ -714,11 +713,8 @@ impl SemanticIndex { .next() .unwrap(); - let file_ids = database.retrieve_included_file_ids( - &worktree_db_ids, - include_globs, - exclude_globs, - )?; + let file_ids = + database.retrieve_included_file_ids(&worktree_db_ids, &includes, &excludes)?; let batch_n = cx.background().num_cpus(); let ids_len = file_ids.clone().len(); diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index acf5a9d72b43a1123102e105da2b4b039fba87c6..6acb25d98a911a061a9b4e8e2f6a387fc73204cc 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -7,11 +7,10 @@ use crate::{ }; use anyhow::Result; use async_trait::async_trait; -use globset::Glob; use gpui::{Task, TestAppContext}; use language::{Language, LanguageConfig, LanguageRegistry, ToOffset}; use pretty_assertions::assert_eq; -use project::{project_settings::ProjectSettings, FakeFs, Fs, Project}; +use project::{project_settings::ProjectSettings, search::PathMatcher, FakeFs, Fs, Project}; use rand::{rngs::StdRng, Rng}; use serde_json::json; use settings::SettingsStore; @@ -121,8 +120,8 @@ async fn test_semantic_index(cx: &mut TestAppContext) { ); // Test Include Files Functonality - let include_files = vec![Glob::new("*.rs").unwrap().compile_matcher()]; - let exclude_files = vec![Glob::new("*.rs").unwrap().compile_matcher()]; + let include_files = vec![PathMatcher::new("*.rs").unwrap()]; + let exclude_files = vec![PathMatcher::new("*.rs").unwrap()]; let rust_only_search_results = store .update(cx, |store, cx| { store.search_project( From fac0e2dd56bfa44dbeea1baf814d2fad23e08c63 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 28 Jul 2023 12:10:04 -0600 Subject: [PATCH 084/160] Don't highlight project search matches either --- crates/editor/src/editor.rs | 2 +- crates/search/src/project_search.rs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index e05837740d4c50fbe7e02e51272bd6340884ec8a..5404610b1da4213d217c6e5f8f77d4261941ef0e 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1537,7 +1537,7 @@ impl Editor { self.collapse_matches = collapse_matches; } - fn range_for_match(&self, range: &Range) -> Range { + pub fn range_for_match(&self, range: &Range) -> Range { if self.collapse_matches { return range.start..range.start; } diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 9054d9e1213dcc0544af0faeb35eb8bd74a3f117..ade60a6d348d8522517ac601588a04b5ecac5b6b 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -654,6 +654,7 @@ impl ProjectSearchView { let range_to_select = match_ranges[new_index].clone(); self.results_editor.update(cx, |editor, cx| { + let range_to_select = editor.range_for_match(&range_to_select); editor.unfold_ranges([range_to_select.clone()], false, true, cx); editor.change_selections(Some(Autoscroll::fit()), cx, |s| { s.select_ranges([range_to_select]) @@ -695,8 +696,12 @@ impl ProjectSearchView { let is_new_search = self.search_id != prev_search_id; self.results_editor.update(cx, |editor, cx| { if is_new_search { + let range_to_select = match_ranges + .first() + .clone() + .map(|range| editor.range_for_match(range)); editor.change_selections(Some(Autoscroll::fit()), cx, |s| { - s.select_ranges(match_ranges.first().cloned()) + s.select_ranges(range_to_select) }); } editor.highlight_background::( From b8690ec1d1df2e5f3d7a018070be0180dfa3257e Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Fri, 28 Jul 2023 15:12:37 -0400 Subject: [PATCH 085/160] Update release action to choose between preview and stable URL in Discord announcements This is what ChatGPT told me, so we'll see. --- .github/workflows/release_actions.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release_actions.yml b/.github/workflows/release_actions.yml index 6c3b3d57c0b49453c66597b133b2893e898f398e..f767324e4f6e2bc2edc825af512bbb5561ac6b62 100644 --- a/.github/workflows/release_actions.yml +++ b/.github/workflows/release_actions.yml @@ -6,6 +6,16 @@ jobs: discord_release: runs-on: ubuntu-latest steps: + - name: Get appropriate URL + id: get-appropriate-url + run: | + if [ "${{ github.event.release.prerelease }}" == "true" ]; then + URL="https://zed.dev/releases/preview/latest" + else + URL="https://zed.dev/releases/stable/latest" + fi + echo "::set-output name=URL::$URL" + - name: Discord Webhook Action uses: tsickert/discord-webhook@v5.3.0 with: @@ -13,6 +23,6 @@ jobs: content: | 📣 Zed ${{ github.event.release.tag_name }} was just released! - Restart your Zed or head to https://zed.dev/releases/stable/latest to grab it. + Restart your Zed or head to ${{ steps.get-appropriate-url.outputs.URL }} to grab it. ${{ github.event.release.body }} From 46101bf1103721088f16da845dae3a79bf30e856 Mon Sep 17 00:00:00 2001 From: Julia Date: Fri, 28 Jul 2023 15:24:40 -0400 Subject: [PATCH 086/160] Reattempt Node installation if the installation itself errors This also makes us a bit more aggressive about reinstalling Node --- crates/copilot/src/copilot.rs | 4 +-- crates/node_runtime/src/node_runtime.rs | 44 ++++++------------------- crates/zed/src/main.rs | 2 +- crates/zed/src/zed.rs | 2 +- 4 files changed, 14 insertions(+), 38 deletions(-) diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs index ce4938ed0d9e31c8130625b526095aeb0283e12c..ab2d861190ff98fb7b4da954a7b92bfb43d75a9d 100644 --- a/crates/copilot/src/copilot.rs +++ b/crates/copilot/src/copilot.rs @@ -338,9 +338,9 @@ impl Copilot { let (server, fake_server) = LanguageServer::fake("copilot".into(), Default::default(), cx.to_async()); let http = util::http::FakeHttpClient::create(|_| async { unreachable!() }); - let this = cx.add_model(|cx| Self { + let this = cx.add_model(|_| Self { http: http.clone(), - node_runtime: NodeRuntime::instance(http, cx.background().clone()), + node_runtime: NodeRuntime::instance(http), server: CopilotServer::Running(RunningCopilotServer { lsp: Arc::new(server), sign_in_status: SignInStatus::Authorized, diff --git a/crates/node_runtime/src/node_runtime.rs b/crates/node_runtime/src/node_runtime.rs index 94858df880e28eeaf44a4899e75395aea47cca6a..d43c14ec7b6e8bcfdc6452df67120efc086f103a 100644 --- a/crates/node_runtime/src/node_runtime.rs +++ b/crates/node_runtime/src/node_runtime.rs @@ -1,9 +1,6 @@ use anyhow::{anyhow, bail, Context, Result}; use async_compression::futures::bufread::GzipDecoder; use async_tar::Archive; -use futures::lock::Mutex; -use futures::{future::Shared, FutureExt}; -use gpui::{executor::Background, Task}; use serde::Deserialize; use smol::{fs, io::BufReader, process::Command}; use std::process::{Output, Stdio}; @@ -33,20 +30,12 @@ pub struct NpmInfoDistTags { pub struct NodeRuntime { http: Arc, - background: Arc, - installation_path: Mutex>>>>>, } impl NodeRuntime { - pub fn instance(http: Arc, background: Arc) -> Arc { + pub fn instance(http: Arc) -> Arc { RUNTIME_INSTANCE - .get_or_init(|| { - Arc::new(NodeRuntime { - http, - background, - installation_path: Mutex::new(None), - }) - }) + .get_or_init(|| Arc::new(NodeRuntime { http })) .clone() } @@ -61,7 +50,9 @@ impl NodeRuntime { subcommand: &str, args: &[&str], ) -> Result { - let attempt = |installation_path: PathBuf| async move { + let attempt = || async move { + let installation_path = self.install_if_needed().await?; + let mut env_path = installation_path.join("bin").into_os_string(); if let Some(existing_path) = std::env::var_os("PATH") { if !existing_path.is_empty() { @@ -92,10 +83,9 @@ impl NodeRuntime { command.output().await.map_err(|e| anyhow!("{e}")) }; - let installation_path = self.install_if_needed().await?; - let mut output = attempt(installation_path.clone()).await; + let mut output = attempt().await; if output.is_err() { - output = attempt(installation_path).await; + output = attempt().await; if output.is_err() { return Err(anyhow!( "failed to launch npm subcommand {subcommand} subcommand" @@ -167,23 +157,8 @@ impl NodeRuntime { } async fn install_if_needed(&self) -> Result { - let task = self - .installation_path - .lock() - .await - .get_or_insert_with(|| { - let http = self.http.clone(); - self.background - .spawn(async move { Self::install(http).await.map_err(Arc::new) }) - .shared() - }) - .clone(); - - task.await.map_err(|e| anyhow!("{}", e)) - } + log::info!("Node runtime install_if_needed"); - async fn install(http: Arc) -> Result { - log::info!("installing Node runtime"); let arch = match consts::ARCH { "x86_64" => "x64", "aarch64" => "arm64", @@ -214,7 +189,8 @@ impl NodeRuntime { let file_name = format!("node-{VERSION}-darwin-{arch}.tar.gz"); let url = format!("https://nodejs.org/dist/{VERSION}/{file_name}"); - let mut response = http + let mut response = self + .http .get(&url, Default::default(), true) .await .context("error downloading Node binary tarball")?; diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index b9fefb89a73555a16a03d9d7e34fa5369d3abde4..e44ab3e33acbb213f69b230a80075aea07890c85 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -136,7 +136,7 @@ fn main() { languages.set_executor(cx.background().clone()); languages.set_language_server_download_dir(paths::LANGUAGES_DIR.clone()); let languages = Arc::new(languages); - let node_runtime = NodeRuntime::instance(http.clone(), cx.background().to_owned()); + let node_runtime = NodeRuntime::instance(http.clone()); languages::init(languages.clone(), node_runtime.clone()); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx)); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index a29567ac385633af04b7e7c3f4b2c0de595d892c..4b0bf1cd4c6aec42aa2d636b474828ef452cbe03 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -2364,7 +2364,7 @@ mod tests { languages.set_executor(cx.background().clone()); let languages = Arc::new(languages); let http = FakeHttpClient::with_404_response(); - let node_runtime = NodeRuntime::instance(http, cx.background().to_owned()); + let node_runtime = NodeRuntime::instance(http); languages::init(languages.clone(), node_runtime); for name in languages.language_names() { languages.language_for_name(&name); From d3b89e16f26d24965267637000e642382cb4b675 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Fri, 28 Jul 2023 14:56:13 -0700 Subject: [PATCH 087/160] Make wrap guides respect scroll position --- crates/editor/src/element.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index b9bf74ee85f8bbc3c338a75b4cd1bf39bc0a53cb..cb46e74af0b1e8d1480dedba1ae51db417fbf5b6 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -546,8 +546,18 @@ impl EditorElement { }); } + let scroll_left = + layout.position_map.snapshot.scroll_position().x() * layout.position_map.em_width; + for (wrap_position, active) in layout.wrap_guides.iter() { - let x = text_bounds.origin_x() + wrap_position + layout.position_map.em_width / 2.; + let x = + (text_bounds.origin_x() + wrap_position + layout.position_map.em_width / 2.) + - scroll_left; + + if x < text_bounds.origin_x() { + continue; + } + let color = if *active { self.style.active_wrap_guide } else { From fe43bacb6fa9a22d57d174df92a05a8cb6739e9d Mon Sep 17 00:00:00 2001 From: Julia Date: Fri, 28 Jul 2023 18:53:24 -0400 Subject: [PATCH 088/160] Put LiveKitBridge Swift build directory in `target` Helps it get caught in a cargo clean --- crates/live_kit_client/build.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/live_kit_client/build.rs b/crates/live_kit_client/build.rs index bcd3f76dca99d5cf22ee01ebe1e1d51cc13e103f..3fa0e003e744b656139958acea89a7b107c68579 100644 --- a/crates/live_kit_client/build.rs +++ b/crates/live_kit_client/build.rs @@ -58,11 +58,14 @@ fn build_bridge(swift_target: &SwiftTarget) { "cargo:rerun-if-changed={}/Package.resolved", SWIFT_PACKAGE_NAME ); + let swift_package_root = swift_package_root(); + let swift_target_folder = swift_target_folder(); if !Command::new("swift") .arg("build") .args(["--configuration", &env::var("PROFILE").unwrap()]) .args(["--triple", &swift_target.target.triple]) + .args(["--build-path".into(), swift_target_folder]) .current_dir(&swift_package_root) .status() .unwrap() @@ -128,6 +131,12 @@ fn swift_package_root() -> PathBuf { env::current_dir().unwrap().join(SWIFT_PACKAGE_NAME) } +fn swift_target_folder() -> PathBuf { + env::current_dir() + .unwrap() + .join(format!("../../target/{SWIFT_PACKAGE_NAME}")) +} + fn copy_dir(source: &Path, destination: &Path) { assert!( Command::new("rm") @@ -155,8 +164,7 @@ fn copy_dir(source: &Path, destination: &Path) { impl SwiftTarget { fn out_dir_path(&self) -> PathBuf { - swift_package_root() - .join(".build") + swift_target_folder() .join(&self.target.unversioned_triple) .join(env::var("PROFILE").unwrap()) } From 2c47efcce91328ee8d567f2871fae1e3cd107b63 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Fri, 28 Jul 2023 22:36:15 -0400 Subject: [PATCH 089/160] Add a command to collapse all entires --- crates/project_panel/src/project_panel.rs | 76 +++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index e6e1cff5981cf7450c154cd7173ab195c5190751..b650d272fbdb7cbb05b477e5033e1f127be8d07b 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -115,6 +115,7 @@ actions!( [ ExpandSelectedEntry, CollapseSelectedEntry, + CollapseAllEntries, NewDirectory, NewFile, Copy, @@ -140,6 +141,7 @@ pub fn init(assets: impl AssetSource, cx: &mut AppContext) { file_associations::init(assets, cx); cx.add_action(ProjectPanel::expand_selected_entry); cx.add_action(ProjectPanel::collapse_selected_entry); + cx.add_action(ProjectPanel::collapse_all_entries); cx.add_action(ProjectPanel::select_prev); cx.add_action(ProjectPanel::select_next); cx.add_action(ProjectPanel::new_file); @@ -514,6 +516,12 @@ impl ProjectPanel { } } + pub fn collapse_all_entries(&mut self, _: &CollapseAllEntries, cx: &mut ViewContext) { + self.expanded_dir_ids.clear(); + self.update_visible_entries(None, cx); + cx.notify(); + } + fn toggle_expanded(&mut self, entry_id: ProjectEntryId, cx: &mut ViewContext) { if let Some(worktree_id) = self.project.read(cx).worktree_id_for_entry(entry_id, cx) { if let Some(expanded_dir_ids) = self.expanded_dir_ids.get_mut(&worktree_id) { @@ -2678,6 +2686,73 @@ mod tests { ); } + #[gpui::test] + async fn test_collapse_all_entries(cx: &mut gpui::TestAppContext) { + init_test_with_editor(cx); + + let fs = FakeFs::new(cx.background()); + fs.insert_tree( + "/project_root", + json!({ + "dir_1": { + "nested_dir": { + "file_a.py": "# File contents", + "file_b.py": "# File contents", + "file_c.py": "# File contents", + }, + "file_1.py": "# File contents", + "file_2.py": "# File contents", + "file_3.py": "# File contents", + }, + "dir_2": { + "file_1.py": "# File contents", + "file_2.py": "# File contents", + "file_3.py": "# File contents", + } + }), + ) + .await; + + let project = Project::test(fs.clone(), ["/project_root".as_ref()], cx).await; + let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); + + let new_search_events_count = Arc::new(AtomicUsize::new(0)); + let _subscription = panel.update(cx, |_, cx| { + let subcription_count = Arc::clone(&new_search_events_count); + cx.subscribe(&cx.handle(), move |_, _, event, _| { + if matches!(event, Event::NewSearchInDirectory { .. }) { + subcription_count.fetch_add(1, atomic::Ordering::SeqCst); + } + }) + }); + + panel.update(cx, |panel, cx| { + panel.collapse_all_entries(&CollapseAllEntries, cx) + }); + cx.foreground().run_until_parked(); + assert_eq!( + visible_entries_as_strings(&panel, 0..10, cx), + &["v project_root", " > dir_1", " > dir_2",] + ); + + // Open dir_1 and make sure nested_dir was collapsed during + toggle_expand_dir(&panel, "project_root/dir_1", cx); + cx.foreground().run_until_parked(); + assert_eq!( + visible_entries_as_strings(&panel, 0..10, cx), + &[ + "v project_root", + " v dir_1 <== selected", + " > nested_dir", + " file_1.py", + " file_2.py", + " file_3.py", + " > dir_2", + ] + ); + } + fn toggle_expand_dir( panel: &ViewHandle, path: impl AsRef, @@ -2878,3 +2953,4 @@ mod tests { }); } } +// TODO - a workspace command? From b0e81c58dc9d85a93153563b1c71753c425c4247 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Fri, 28 Jul 2023 23:06:40 -0400 Subject: [PATCH 090/160] Remove unused code in test --- crates/project_panel/src/project_panel.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index b650d272fbdb7cbb05b477e5033e1f127be8d07b..b2b8b2e4bd721fa225db6b8d6f902cb0e0b560d6 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -2717,16 +2717,6 @@ mod tests { let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); - let new_search_events_count = Arc::new(AtomicUsize::new(0)); - let _subscription = panel.update(cx, |_, cx| { - let subcription_count = Arc::clone(&new_search_events_count); - cx.subscribe(&cx.handle(), move |_, _, event, _| { - if matches!(event, Event::NewSearchInDirectory { .. }) { - subcription_count.fetch_add(1, atomic::Ordering::SeqCst); - } - }) - }); - panel.update(cx, |panel, cx| { panel.collapse_all_entries(&CollapseAllEntries, cx) }); From 0bd6e7bac3179b49f69125b573c78dce438f286a Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Fri, 28 Jul 2023 23:13:36 -0400 Subject: [PATCH 091/160] Fix comment --- crates/project_panel/src/project_panel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index b2b8b2e4bd721fa225db6b8d6f902cb0e0b560d6..0be52646e631ef1446f168dc3ecf1ce7b9ef0075 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -2726,7 +2726,7 @@ mod tests { &["v project_root", " > dir_1", " > dir_2",] ); - // Open dir_1 and make sure nested_dir was collapsed during + // Open dir_1 and make sure nested_dir was collapsed when running collapse_all_entries toggle_expand_dir(&panel, "project_root/dir_1", cx); cx.foreground().run_until_parked(); assert_eq!( From d58f031696ce039c0068344803551558c391d85c Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Fri, 28 Jul 2023 22:27:36 -0700 Subject: [PATCH 092/160] disable wrap guides in the assitant panel --- crates/ai/src/assistant.rs | 1 + crates/editor/src/editor.rs | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/crates/ai/src/assistant.rs b/crates/ai/src/assistant.rs index 8a4c04d3387784e0e2b5e4e7d745c690f72c02aa..957c5e1c063aad3de12657448267d0f813f38887 100644 --- a/crates/ai/src/assistant.rs +++ b/crates/ai/src/assistant.rs @@ -1637,6 +1637,7 @@ impl ConversationEditor { let mut editor = Editor::for_buffer(conversation.read(cx).buffer.clone(), None, cx); editor.set_soft_wrap_mode(SoftWrap::EditorWidth, cx); editor.set_show_gutter(false, cx); + editor.set_show_wrap_guides(false, cx); editor }); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index b4145edb6483dd0d8c25d0f645cdcef1927ed374..5270d6f951870fa952e9a0a33f2f229a1d71ff98 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -543,6 +543,7 @@ pub struct Editor { show_local_selections: bool, mode: EditorMode, show_gutter: bool, + show_wrap_guides: Option, placeholder_text: Option>, highlighted_rows: Option>, #[allow(clippy::type_complexity)] @@ -1375,6 +1376,7 @@ impl Editor { show_local_selections: true, mode, show_gutter: mode == EditorMode::Full, + show_wrap_guides: None, placeholder_text: None, highlighted_rows: None, background_highlights: Default::default(), @@ -7187,6 +7189,10 @@ impl Editor { pub fn wrap_guides(&self, cx: &AppContext) -> SmallVec<[(usize, bool); 2]> { let mut wrap_guides = smallvec::smallvec![]; + if self.show_wrap_guides == Some(false) { + return wrap_guides; + } + let settings = self.buffer.read(cx).settings_at(0, cx); if settings.show_wrap_guides { if let SoftWrap::Column(soft_wrap) = self.soft_wrap_mode(cx) { @@ -7244,6 +7250,11 @@ impl Editor { cx.notify(); } + pub fn set_show_wrap_guides(&mut self, show_gutter: bool, cx: &mut ViewContext) { + self.show_wrap_guides = Some(show_gutter); + cx.notify(); + } + pub fn reveal_in_finder(&mut self, _: &RevealInFinder, cx: &mut ViewContext) { if let Some(buffer) = self.buffer().read(cx).as_singleton() { if let Some(file) = buffer.read(cx).file().and_then(|f| f.as_local()) { From 8926266952948063a666a248f2e4b7bf8edcfde6 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Sat, 29 Jul 2023 23:53:16 -0700 Subject: [PATCH 093/160] Halve opacity on wrap guides --- styles/src/style_tree/editor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/styles/src/style_tree/editor.ts b/styles/src/style_tree/editor.ts index 832e77626491ff94f183d5ce1fe195f5a55a3780..deab45d4b21df8b7d130479c277ed317ba78d8d4 100644 --- a/styles/src/style_tree/editor.ts +++ b/styles/src/style_tree/editor.ts @@ -182,8 +182,8 @@ export default function editor(): any { line_number: with_opacity(foreground(layer), 0.35), line_number_active: foreground(layer), rename_fade: 0.6, - wrap_guide: with_opacity(foreground(layer), 0.1), - active_wrap_guide: with_opacity(foreground(layer), 0.2), + wrap_guide: with_opacity(foreground(layer), 0.05), + active_wrap_guide: with_opacity(foreground(layer), 0.1), unnecessary_code_fade: 0.5, selection: theme.players[0], whitespace: theme.ramps.neutral(0.5).hex(), From a5dd8dd0a9c14e85bc95a8b84989366f5ff590fa Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 31 Jul 2023 10:02:28 -0400 Subject: [PATCH 094/160] add lua embedding query for semantic search --- Cargo.lock | 39 +++---- crates/semantic_index/Cargo.toml | 1 + .../src/semantic_index_tests.rs | 102 ++++++++++++++++++ crates/zed/src/languages/lua/config.toml | 1 + crates/zed/src/languages/lua/embedding.scm | 10 ++ 5 files changed, 134 insertions(+), 19 deletions(-) create mode 100644 crates/zed/src/languages/lua/embedding.scm diff --git a/Cargo.lock b/Cargo.lock index 7c6a213d0d4e36a427fc4352b2e417258f12de8f..6c558cbb090a557814cbcd662683e1a40561a463 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2042,9 +2042,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.64+curl-8.2.0" +version = "0.4.65+curl-8.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f96069f0b1cb1241c838740659a771ef143363f52772a9ce1bd9c04c75eee0dc" +checksum = "961ba061c9ef2fe34bbd12b807152d96f0badd2bebe7b90ce6c8c8b7572a0986" dependencies = [ "cc", "libc", @@ -3033,9 +3033,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1391ab1f92ffcc08911957149833e682aa3fe252b9f45f966d2ef972274c97df" +checksum = "aca8bbd8e0707c1887a8bbb7e6b40e228f251ff5d62c8220a4a7a53c73aff006" dependencies = [ "aho-corasick 1.0.2", "bstr", @@ -6688,6 +6688,7 @@ dependencies = [ "tree-sitter-cpp 0.20.2", "tree-sitter-elixir 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tree-sitter-json 0.19.0", + "tree-sitter-lua", "tree-sitter-rust", "tree-sitter-toml 0.20.0", "tree-sitter-typescript 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6722,18 +6723,18 @@ checksum = "5a9f47faea3cad316faa914d013d24f471cd90bfca1a0c70f05a3f42c6441e99" [[package]] name = "serde" -version = "1.0.175" +version = "1.0.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b" +checksum = "63ba2516aa6bf82e0b19ca8b50019d52df58455d3cf9bdaf6315225fdd0c560a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.175" +version = "1.0.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4" +checksum = "401797fe7833d72109fedec6bfcbe67c0eed9b99772f26eb8afd261f0abc6fd3" dependencies = [ "proc-macro2", "quote", @@ -6762,9 +6763,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "indexmap 2.0.0", "itoa 1.0.9", @@ -6786,9 +6787,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e168eaaf71e8f9bd6037feb05190485708e019f4fd87d161b3c0a0d37daf85e5" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", @@ -9031,9 +9032,9 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-encoder" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06a3d1b4a575ffb873679402b2aedb3117555eb65c27b1b86c8a91e574bc2a2a" +checksum = "41763f20eafed1399fff1afb466496d3a959f58241436cfdc17e3f5ca954de16" dependencies = [ "leb128", ] @@ -9255,9 +9256,9 @@ dependencies = [ [[package]] name = "wast" -version = "62.0.0" +version = "62.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f7ee878019d69436895f019b65f62c33da63595d8e857cbdc87c13ecb29a32" +checksum = "b8ae06f09dbe377b889fbd620ff8fa21e1d49d1d9d364983c0cdbf9870cb9f1f" dependencies = [ "leb128", "memchr", @@ -9267,11 +9268,11 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "295572bf24aa5b685a971a83ad3e8b6e684aaad8a9be24bc7bf59bed84cc1c08" +checksum = "842e15861d203fb4a96d314b0751cdeaf0f6f8b35e8d81d2953af2af5e44e637" dependencies = [ - "wast 62.0.0", + "wast 62.0.1", ] [[package]] diff --git a/crates/semantic_index/Cargo.toml b/crates/semantic_index/Cargo.toml index a1f126bfb841ecb8334aeca391ac4959ef9f57b0..942f61d29883134895cf257bdbbeaded8a3677a4 100644 --- a/crates/semantic_index/Cargo.toml +++ b/crates/semantic_index/Cargo.toml @@ -60,3 +60,4 @@ tree-sitter-rust = "*" tree-sitter-toml = "*" tree-sitter-cpp = "*" tree-sitter-elixir = "*" +tree-sitter-lua = "*" diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index acf5a9d72b43a1123102e105da2b4b039fba87c6..4eedade69d9ed15c85a4e84a1e647b8510b71fd4 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -486,6 +486,79 @@ async fn test_code_context_retrieval_javascript() { ) } +#[gpui::test] +async fn test_code_context_retrieval_lua() { + let language = lua_lang(); + let mut retriever = CodeContextRetriever::new(); + + let text = r#" + -- Creates a new class + -- @param baseclass The Baseclass of this class, or nil. + -- @return A new class reference. + function classes.class(baseclass) + -- Create the class definition and metatable. + local classdef = {} + -- Find the super class, either Object or user-defined. + baseclass = baseclass or classes.Object + -- If this class definition does not know of a function, it will 'look up' to the Baseclass via the __index of the metatable. + setmetatable(classdef, { __index = baseclass }) + -- All class instances have a reference to the class object. + classdef.class = classdef + --- Recursivly allocates the inheritance tree of the instance. + -- @param mastertable The 'root' of the inheritance tree. + -- @return Returns the instance with the allocated inheritance tree. + function classdef.alloc(mastertable) + -- All class instances have a reference to a superclass object. + local instance = { super = baseclass.alloc(mastertable) } + -- Any functions this instance does not know of will 'look up' to the superclass definition. + setmetatable(instance, { __index = classdef, __newindex = mastertable }) + return instance + end + end + "#.unindent(); + + let documents = retriever.parse_file(&text, language.clone()).unwrap(); + + assert_documents_eq( + &documents, + &[ + (r#" + -- Creates a new class + -- @param baseclass The Baseclass of this class, or nil. + -- @return A new class reference. + function classes.class(baseclass) + -- Create the class definition and metatable. + local classdef = {} + -- Find the super class, either Object or user-defined. + baseclass = baseclass or classes.Object + -- If this class definition does not know of a function, it will 'look up' to the Baseclass via the __index of the metatable. + setmetatable(classdef, { __index = baseclass }) + -- All class instances have a reference to the class object. + classdef.class = classdef + --- Recursivly allocates the inheritance tree of the instance. + -- @param mastertable The 'root' of the inheritance tree. + -- @return Returns the instance with the allocated inheritance tree. + function classdef.alloc(mastertable) + --[ ... ]-- + --[ ... ]-- + end + end"#.unindent(), + 114), + (r#" + --- Recursivly allocates the inheritance tree of the instance. + -- @param mastertable The 'root' of the inheritance tree. + -- @return Returns the instance with the allocated inheritance tree. + function classdef.alloc(mastertable) + -- All class instances have a reference to a superclass object. + local instance = { super = baseclass.alloc(mastertable) } + -- Any functions this instance does not know of will 'look up' to the superclass definition. + setmetatable(instance, { __index = classdef, __newindex = mastertable }) + return instance + end"#.unindent(), 809), + ] + ); +} + #[gpui::test] async fn test_code_context_retrieval_elixir() { let language = elixir_lang(); @@ -1084,6 +1157,35 @@ fn cpp_lang() -> Arc { ) } +fn lua_lang() -> Arc { + Arc::new( + Language::new( + LanguageConfig { + name: "Lua".into(), + path_suffixes: vec!["lua".into()], + collapsed_placeholder: "--[ ... ]--".to_string(), + ..Default::default() + }, + Some(tree_sitter_lua::language()), + ) + .with_embedding_query( + r#" + ( + (comment)* @context + . + (function_declaration + "function" @name + name: (_) @name + (comment)* @collapse + body: (block) @collapse + ) @item + ) + "#, + ) + .unwrap(), + ) +} + fn elixir_lang() -> Arc { Arc::new( Language::new( diff --git a/crates/zed/src/languages/lua/config.toml b/crates/zed/src/languages/lua/config.toml index fe44a3d2aaa5b0c57d13f41d925193d478d714a9..d3e44edfe97b6aa07481d0bf0f0fffae072950b7 100644 --- a/crates/zed/src/languages/lua/config.toml +++ b/crates/zed/src/languages/lua/config.toml @@ -7,3 +7,4 @@ brackets = [ { start = "[", end = "]", close = true, newline = true }, { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] }, ] +collapsed_placeholder = "--[ ... ]--" diff --git a/crates/zed/src/languages/lua/embedding.scm b/crates/zed/src/languages/lua/embedding.scm new file mode 100644 index 0000000000000000000000000000000000000000..0d1065089fc0853c1e6fa874f4e511e1ef2c1422 --- /dev/null +++ b/crates/zed/src/languages/lua/embedding.scm @@ -0,0 +1,10 @@ +( + (comment)* @context + . + (function_declaration + "function" @name + name: (_) @name + (comment)* @collapse + body: (block) @collapse + ) @item +) From ca4e21881efc5d0293e545a1059971cab356bc54 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 31 Jul 2023 10:54:30 -0400 Subject: [PATCH 095/160] add ruby support for semantic search --- Cargo.lock | 1 + crates/semantic_index/Cargo.toml | 1 + .../src/semantic_index_tests.rs | 231 ++++++++++++++++++ crates/zed/src/languages/ruby/config.toml | 1 + crates/zed/src/languages/ruby/embedding.scm | 22 ++ 5 files changed, 256 insertions(+) create mode 100644 crates/zed/src/languages/ruby/embedding.scm diff --git a/Cargo.lock b/Cargo.lock index 6c558cbb090a557814cbcd662683e1a40561a463..b4a8f13bea56d64f4d10084e726c22c312cdec92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6689,6 +6689,7 @@ dependencies = [ "tree-sitter-elixir 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tree-sitter-json 0.19.0", "tree-sitter-lua", + "tree-sitter-ruby", "tree-sitter-rust", "tree-sitter-toml 0.20.0", "tree-sitter-typescript 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crates/semantic_index/Cargo.toml b/crates/semantic_index/Cargo.toml index 942f61d29883134895cf257bdbbeaded8a3677a4..637f3f4487443825ace9b98dbe73690ce02ec250 100644 --- a/crates/semantic_index/Cargo.toml +++ b/crates/semantic_index/Cargo.toml @@ -61,3 +61,4 @@ tree-sitter-toml = "*" tree-sitter-cpp = "*" tree-sitter-elixir = "*" tree-sitter-lua = "*" +tree-sitter-ruby = "*" diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index 4eedade69d9ed15c85a4e84a1e647b8510b71fd4..58d34649c7e953faf2ebf3bac5829e5474330f85 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -827,6 +827,196 @@ async fn test_code_context_retrieval_cpp() { ); } +#[gpui::test] +async fn test_code_context_retrieval_ruby() { + let language = ruby_lang(); + let mut retriever = CodeContextRetriever::new(); + + let text = r#" + # This concern is inspired by "sudo mode" on GitHub. It + # is a way to re-authenticate a user before allowing them + # to see or perform an action. + # + # Add `before_action :require_challenge!` to actions you + # want to protect. + # + # The user will be shown a page to enter the challenge (which + # is either the password, or just the username when no + # password exists). Upon passing, there is a grace period + # during which no challenge will be asked from the user. + # + # Accessing challenge-protected resources during the grace + # period will refresh the grace period. + module ChallengableConcern + extend ActiveSupport::Concern + + CHALLENGE_TIMEOUT = 1.hour.freeze + + def require_challenge! + return if skip_challenge? + + if challenge_passed_recently? + session[:challenge_passed_at] = Time.now.utc + return + end + + @challenge = Form::Challenge.new(return_to: request.url) + + if params.key?(:form_challenge) + if challenge_passed? + session[:challenge_passed_at] = Time.now.utc + else + flash.now[:alert] = I18n.t('challenge.invalid_password') + render_challenge + end + else + render_challenge + end + end + + def challenge_passed? + current_user.valid_password?(challenge_params[:current_password]) + end + end + + class Animal + include Comparable + + attr_reader :legs + + def initialize(name, legs) + @name, @legs = name, legs + end + + def <=>(other) + legs <=> other.legs + end + end + + # Singleton method for car object + def car.wheels + puts "There are four wheels" + end"# + .unindent(); + + let documents = retriever.parse_file(&text, language.clone()).unwrap(); + + assert_documents_eq( + &documents, + &[ + ( + r#" + # This concern is inspired by "sudo mode" on GitHub. It + # is a way to re-authenticate a user before allowing them + # to see or perform an action. + # + # Add `before_action :require_challenge!` to actions you + # want to protect. + # + # The user will be shown a page to enter the challenge (which + # is either the password, or just the username when no + # password exists). Upon passing, there is a grace period + # during which no challenge will be asked from the user. + # + # Accessing challenge-protected resources during the grace + # period will refresh the grace period. + module ChallengableConcern + extend ActiveSupport::Concern + + CHALLENGE_TIMEOUT = 1.hour.freeze + + def require_challenge! + # ... + end + + def challenge_passed? + # ... + end + end"# + .unindent(), + 558, + ), + ( + r#" + def require_challenge! + return if skip_challenge? + + if challenge_passed_recently? + session[:challenge_passed_at] = Time.now.utc + return + end + + @challenge = Form::Challenge.new(return_to: request.url) + + if params.key?(:form_challenge) + if challenge_passed? + session[:challenge_passed_at] = Time.now.utc + else + flash.now[:alert] = I18n.t('challenge.invalid_password') + render_challenge + end + else + render_challenge + end + end"# + .unindent(), + 663, + ), + ( + r#" + def challenge_passed? + current_user.valid_password?(challenge_params[:current_password]) + end"# + .unindent(), + 1254, + ), + ( + r#" + class Animal + include Comparable + + attr_reader :legs + + def initialize(name, legs) + # ... + end + + def <=>(other) + # ... + end + end"# + .unindent(), + 1363, + ), + ( + r#" + def initialize(name, legs) + @name, @legs = name, legs + end"# + .unindent(), + 1427, + ), + ( + r#" + def <=>(other) + legs <=> other.legs + end"# + .unindent(), + 1501, + ), + ( + r#" + # Singleton method for car object + def car.wheels + puts "There are four wheels" + end"# + .unindent(), + 1591, + ), + ], + ); +} + #[gpui::test] fn test_dot_product(mut rng: StdRng) { assert_eq!(dot(&[1., 0., 0., 0., 0.], &[0., 1., 0., 0., 0.]), 0.); @@ -1186,6 +1376,47 @@ fn lua_lang() -> Arc { ) } +fn ruby_lang() -> Arc { + Arc::new( + Language::new( + LanguageConfig { + name: "Ruby".into(), + path_suffixes: vec!["rb".into()], + collapsed_placeholder: "# ...".to_string(), + ..Default::default() + }, + Some(tree_sitter_ruby::language()), + ) + .with_embedding_query( + r#" + ( + (comment)* @context + . + [ + (module + "module" @name + name: (_) @name) + (method + "def" @name + name: (_) @name + body: (body_statement) @collapse) + (class + "class" @name + name: (_) @name) + (singleton_method + "def" @name + object: (_) @name + "." @name + name: (_) @name + body: (body_statement) @collapse) + ] @item + ) + "#, + ) + .unwrap(), + ) +} + fn elixir_lang() -> Arc { Arc::new( Language::new( diff --git a/crates/zed/src/languages/ruby/config.toml b/crates/zed/src/languages/ruby/config.toml index a0b26bff92048d0b0327f1bcbe4301f9964737c6..6c8c61501556c88dac13d890bd1ddcc758134cc8 100644 --- a/crates/zed/src/languages/ruby/config.toml +++ b/crates/zed/src/languages/ruby/config.toml @@ -10,3 +10,4 @@ brackets = [ { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] }, { start = "'", end = "'", close = true, newline = false, not_in = ["comment", "string"] }, ] +collapsed_placeholder = "# ..." diff --git a/crates/zed/src/languages/ruby/embedding.scm b/crates/zed/src/languages/ruby/embedding.scm new file mode 100644 index 0000000000000000000000000000000000000000..7a101e6b0925383f09fcdd24a7d5c26bfaf85628 --- /dev/null +++ b/crates/zed/src/languages/ruby/embedding.scm @@ -0,0 +1,22 @@ +( + (comment)* @context + . + [ + (module + "module" @name + name: (_) @name) + (method + "def" @name + name: (_) @name + body: (body_statement) @collapse) + (class + "class" @name + name: (_) @name) + (singleton_method + "def" @name + object: (_) @name + "." @name + name: (_) @name + body: (body_statement) @collapse) + ] @item + ) From 89edb3d1b534b962f3e4e81c6055b6fd92fef868 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 31 Jul 2023 11:41:18 -0400 Subject: [PATCH 096/160] fix templating bug for parseable entire files --- crates/semantic_index/src/parsing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/semantic_index/src/parsing.rs b/crates/semantic_index/src/parsing.rs index c952ef3a4edf939ddc8ad17c9bab6e17ec5e0cce..677406931e0cc36cd32fd497a5f53337052421e8 100644 --- a/crates/semantic_index/src/parsing.rs +++ b/crates/semantic_index/src/parsing.rs @@ -59,7 +59,7 @@ impl CodeContextRetriever { let document_span = ENTIRE_FILE_TEMPLATE .replace("", relative_path.to_string_lossy().as_ref()) .replace("", language_name.as_ref()) - .replace("item", &content); + .replace("", &content); Ok(vec![Document { range: 0..content.len(), From e07a81b22590257bb7bc8c4362d6afe3a01d401c Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 31 Jul 2023 12:49:55 -0400 Subject: [PATCH 097/160] Add additional storage filetypes --- assets/icons/file_icons/file_types.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/assets/icons/file_icons/file_types.json b/assets/icons/file_icons/file_types.json index 0ccf9c2bb7c7b4eb12f6ca83646ab9a38c661490..67791aaecb42f20a6a57035266a9bedaa4d7b415 100644 --- a/assets/icons/file_icons/file_types.json +++ b/assets/icons/file_icons/file_types.json @@ -1,5 +1,16 @@ { "suffixes": { + "db": "storage", + "sqlite": "storage", + "myi": "storage", + "myd": "storage", + "mdf": "storage", + "csv": "storage", + "bak": "backup", + "dat": "storage", + "dll": "storage", + "sav": "storage", + "tsv": "storage", "aac": "audio", "bash": "terminal", "bmp": "image", From c4709418d142888b5d94ae61c5aad98f28c6b21a Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 31 Jul 2023 12:50:30 -0400 Subject: [PATCH 098/160] Format --- assets/icons/file_icons/file_types.json | 343 ++++++++++++------------ 1 file changed, 176 insertions(+), 167 deletions(-) diff --git a/assets/icons/file_icons/file_types.json b/assets/icons/file_icons/file_types.json index 67791aaecb42f20a6a57035266a9bedaa4d7b415..9ea75d07309d853f37fed0192ca83bfd7d1099d8 100644 --- a/assets/icons/file_icons/file_types.json +++ b/assets/icons/file_icons/file_types.json @@ -1,170 +1,179 @@ { - "suffixes": { - "db": "storage", - "sqlite": "storage", - "myi": "storage", - "myd": "storage", - "mdf": "storage", - "csv": "storage", - "bak": "backup", - "dat": "storage", - "dll": "storage", - "sav": "storage", - "tsv": "storage", - "aac": "audio", - "bash": "terminal", - "bmp": "image", - "c": "code", - "conf": "settings", - "cpp": "code", - "cc": "code", - "css": "code", - "doc": "document", - "docx": "document", - "eslintrc": "eslint", - "eslintrc.js": "eslint", - "eslintrc.json": "eslint", - "flac": "audio", - "fish": "terminal", - "gitattributes": "vcs", - "gitignore": "vcs", - "gitmodules": "vcs", - "gif": "image", - "go": "code", - "h": "code", - "handlebars": "code", - "hbs": "template", - "htm": "template", - "html": "template", - "svelte": "template", - "hpp": "code", - "ico": "image", - "ini": "settings", - "java": "code", - "jpeg": "image", - "jpg": "image", - "js": "code", - "json": "storage", - "lock": "lock", - "log": "log", - "md": "document", - "mdx": "document", - "mp3": "audio", - "mp4": "video", - "ods": "document", - "odp": "document", - "odt": "document", - "ogg": "video", - "pdf": "document", - "php": "code", - "png": "image", - "ppt": "document", - "pptx": "document", - "prettierrc": "prettier", - "prettierignore": "prettier", - "ps1": "terminal", - "psd": "image", - "py": "code", - "rb": "code", - "rkt": "code", - "rs": "rust", - "rtf": "document", - "scm": "code", - "sh": "terminal", - "bashrc": "terminal", - "bash_profile": "terminal", - "bash_aliases": "terminal", - "bash_logout": "terminal", - "profile": "terminal", - "zshrc": "terminal", - "zshenv": "terminal", - "zsh_profile": "terminal", - "zsh_aliases": "terminal", - "zsh_histfile": "terminal", - "zlogin": "terminal", - "sql": "code", - "svg": "image", - "swift": "code", - "tiff": "image", - "toml": "toml", - "ts": "typescript", - "tsx": "code", - "txt": "document", - "wav": "audio", - "webm": "video", - "xls": "document", - "xlsx": "document", - "xml": "template", - "yaml": "settings", - "yml": "settings", - "zsh": "terminal" - }, - "types": { - "audio": { - "icon": "icons/file_icons/audio.svg" - }, - "code": { - "icon": "icons/file_icons/code.svg" - }, - "collapsed_chevron": { - "icon": "icons/file_icons/chevron_right.svg" - }, - "collapsed_folder": { - "icon": "icons/file_icons/folder.svg" - }, - "default": { - "icon": "icons/file_icons/file.svg" - }, - "document": { - "icon": "icons/file_icons/book.svg" - }, - "eslint": { - "icon": "icons/file_icons/eslint.svg" - }, - "expanded_chevron": { - "icon": "icons/file_icons/chevron_down.svg" - }, - "expanded_folder": { - "icon": "icons/file_icons/folder_open.svg" - }, - "image": { - "icon": "icons/file_icons/image.svg" - }, - "lock": { - "icon": "icons/file_icons/lock.svg" - }, - "log": { - "icon": "icons/file_icons/info.svg" - }, - "prettier": { - "icon": "icons/file_icons/prettier.svg" - }, - "rust": { - "icon": "icons/file_icons/rust.svg" - }, - "settings": { - "icon": "icons/file_icons/settings.svg" - }, - "storage": { - "icon": "icons/file_icons/database.svg" - }, - "template": { - "icon": "icons/file_icons/html.svg" - }, - "terminal": { - "icon": "icons/file_icons/terminal.svg" - }, - "toml": { - "icon": "icons/file_icons/toml.svg" - }, - "typescript": { - "icon": "icons/file_icons/typescript.svg" - }, - "vcs": { - "icon": "icons/file_icons/git.svg" - }, - "video": { - "icon": "icons/file_icons/video.svg" + "suffixes": { + "aac": "audio", + "accdb": "storage", + "bak": "backup", + "bash": "terminal", + "bash_aliases": "terminal", + "bash_logout": "terminal", + "bash_profile": "terminal", + "bashrc": "terminal", + "bmp": "image", + "c": "code", + "cc": "code", + "conf": "settings", + "cpp": "code", + "css": "code", + "csv": "storage", + "dat": "storage", + "db": "storage", + "dbf": "storage", + "dll": "storage", + "doc": "document", + "docx": "document", + "eslintrc": "eslint", + "eslintrc.js": "eslint", + "eslintrc.json": "eslint", + "fmp": "storage", + "fp7": "storage", + "flac": "audio", + "fish": "terminal", + "frm": "storage", + "gdb": "storage", + "gitattributes": "vcs", + "gitignore": "vcs", + "gitmodules": "vcs", + "gif": "image", + "go": "code", + "h": "code", + "handlebars": "code", + "hbs": "template", + "htm": "template", + "html": "template", + "ib": "storage", + "ico": "image", + "ini": "settings", + "java": "code", + "jpeg": "image", + "jpg": "image", + "js": "code", + "json": "storage", + "ldf": "storage", + "lock": "lock", + "log": "log", + "mdb": "storage", + "md": "document", + "mdf": "storage", + "mdx": "document", + "mp3": "audio", + "mp4": "video", + "myd": "storage", + "myi": "storage", + "ods": "document", + "odp": "document", + "odt": "document", + "ogg": "video", + "pdb": "storage", + "pdf": "document", + "php": "code", + "png": "image", + "ppt": "document", + "pptx": "document", + "prettierignore": "prettier", + "prettierrc": "prettier", + "profile": "terminal", + "ps1": "terminal", + "psd": "image", + "py": "code", + "rb": "code", + "rkt": "code", + "rs": "rust", + "rtf": "document", + "sav": "storage", + "scm": "code", + "sh": "terminal", + "sqlite": "storage", + "sdf": "storage", + "svelte": "template", + "svg": "image", + "swift": "code", + "ts": "typescript", + "tsx": "code", + "tiff": "image", + "toml": "toml", + "tsv": "storage", + "txt": "document", + "wav": "audio", + "webm": "video", + "xls": "document", + "xlsx": "document", + "xml": "template", + "yaml": "settings", + "yml": "settings", + "zlogin": "terminal", + "zsh": "terminal", + "zsh_aliases": "terminal", + "zshenv": "terminal", + "zsh_histfile": "terminal", + "zsh_profile": "terminal", + "zshrc": "terminal" + }, + "types": { + "audio": { + "icon": "icons/file_icons/audio.svg" + }, + "code": { + "icon": "icons/file_icons/code.svg" + }, + "collapsed_chevron": { + "icon": "icons/file_icons/chevron_right.svg" + }, + "collapsed_folder": { + "icon": "icons/file_icons/folder.svg" + }, + "default": { + "icon": "icons/file_icons/file.svg" + }, + "document": { + "icon": "icons/file_icons/book.svg" + }, + "eslint": { + "icon": "icons/file_icons/eslint.svg" + }, + "expanded_chevron": { + "icon": "icons/file_icons/chevron_down.svg" + }, + "expanded_folder": { + "icon": "icons/file_icons/folder_open.svg" + }, + "image": { + "icon": "icons/file_icons/image.svg" + }, + "lock": { + "icon": "icons/file_icons/lock.svg" + }, + "log": { + "icon": "icons/file_icons/info.svg" + }, + "prettier": { + "icon": "icons/file_icons/prettier.svg" + }, + "rust": { + "icon": "icons/file_icons/rust.svg" + }, + "settings": { + "icon": "icons/file_icons/settings.svg" + }, + "storage": { + "icon": "icons/file_icons/database.svg" + }, + "template": { + "icon": "icons/file_icons/html.svg" + }, + "terminal": { + "icon": "icons/file_icons/terminal.svg" + }, + "toml": { + "icon": "icons/file_icons/toml.svg" + }, + "typescript": { + "icon": "icons/file_icons/typescript.svg" + }, + "vcs": { + "icon": "icons/file_icons/git.svg" + }, + "video": { + "icon": "icons/file_icons/video.svg" + } } - } } From bb288eb941fba31ba98a89f9b2b32940ed493ac5 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 31 Jul 2023 13:08:40 -0400 Subject: [PATCH 099/160] Ensure json uses a tab size of 4 --- .zed/settings.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .zed/settings.json diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..d4b3375b0d21f95128c6bffb2c7a92f8bf97916c --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,5 @@ +{ + "JSON": { + "tab_size": 4 + } +} From 88474a60485257814313b4a6ff799642feeafe6a Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Mon, 31 Jul 2023 10:54:29 -0700 Subject: [PATCH 100/160] Clip wrap guides from under the scrollbar --- crates/editor/src/element.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index cb46e74af0b1e8d1480dedba1ae51db417fbf5b6..750beaea1380ee676c15a3d895c633a91bbe6c12 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -554,7 +554,9 @@ impl EditorElement { (text_bounds.origin_x() + wrap_position + layout.position_map.em_width / 2.) - scroll_left; - if x < text_bounds.origin_x() { + if x < text_bounds.origin_x() + || (layout.show_scrollbars && x > self.scrollbar_left(&bounds)) + { continue; } @@ -1046,6 +1048,10 @@ impl EditorElement { scene.pop_layer(); } + fn scrollbar_left(&self, bounds: &RectF) -> f32 { + bounds.max_x() - self.style.theme.scrollbar.width + } + fn paint_scrollbar( &mut self, scene: &mut SceneBuilder, @@ -1064,7 +1070,7 @@ impl EditorElement { let top = bounds.min_y(); let bottom = bounds.max_y(); let right = bounds.max_x(); - let left = right - style.width; + let left = self.scrollbar_left(&bounds); let row_range = &layout.scrollbar_row_range; let max_row = layout.max_row as f32 + (row_range.end - row_range.start); From 599f6748274ca40e91e593d5d049982b2fbded45 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 31 Jul 2023 16:36:09 -0400 Subject: [PATCH 101/160] add php support for semantic search --- Cargo.lock | 65 ++---- crates/semantic_index/Cargo.toml | 17 +- crates/semantic_index/src/parsing.rs | 7 +- .../src/semantic_index_tests.rs | 205 ++++++++++++++++++ crates/zed/src/languages/php/config.toml | 1 + crates/zed/src/languages/php/embedding.scm | 36 +++ crates/zed/src/languages/php/outline.scm | 7 +- 7 files changed, 275 insertions(+), 63 deletions(-) create mode 100644 crates/zed/src/languages/php/embedding.scm diff --git a/Cargo.lock b/Cargo.lock index b4a8f13bea56d64f4d10084e726c22c312cdec92..f6a85aa70c38181110739d30310cf59603d2af8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2341,7 +2341,7 @@ dependencies = [ "tree-sitter", "tree-sitter-html", "tree-sitter-rust", - "tree-sitter-typescript 0.20.2 (git+https://github.com/tree-sitter/tree-sitter-typescript?rev=5d20856f34315b068c41edaee2ac8a100081d259)", + "tree-sitter-typescript", "unindent", "util", "workspace", @@ -3851,7 +3851,7 @@ dependencies = [ "text", "theme", "tree-sitter", - "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=4ba9dab6e2602960d95b2b625f3386c27e08084e)", + "tree-sitter-elixir", "tree-sitter-embedded-template", "tree-sitter-heex", "tree-sitter-html", @@ -3860,7 +3860,7 @@ dependencies = [ "tree-sitter-python", "tree-sitter-ruby", "tree-sitter-rust", - "tree-sitter-typescript 0.20.2 (git+https://github.com/tree-sitter/tree-sitter-typescript?rev=5d20856f34315b068c41edaee2ac8a100081d259)", + "tree-sitter-typescript", "unicase", "unindent", "util", @@ -6685,14 +6685,15 @@ dependencies = [ "theme", "tiktoken-rs 0.5.0", "tree-sitter", - "tree-sitter-cpp 0.20.2", - "tree-sitter-elixir 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tree-sitter-json 0.19.0", + "tree-sitter-cpp", + "tree-sitter-elixir", + "tree-sitter-json 0.20.0", "tree-sitter-lua", + "tree-sitter-php", "tree-sitter-ruby", "tree-sitter-rust", - "tree-sitter-toml 0.20.0", - "tree-sitter-typescript 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tree-sitter-toml", + "tree-sitter-typescript", "unindent", "util", "workspace", @@ -8257,16 +8258,6 @@ dependencies = [ "tree-sitter", ] -[[package]] -name = "tree-sitter-cpp" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c88fd925d0333e63ac64e521f5bd79c53019e569ffbbccfeef346a326f459e9" -dependencies = [ - "cc", - "tree-sitter", -] - [[package]] name = "tree-sitter-css" version = "0.19.0" @@ -8276,16 +8267,6 @@ dependencies = [ "tree-sitter", ] -[[package]] -name = "tree-sitter-elixir" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9916f3e1c80b3c8aab8582604e97e8720cb9b893489b347cf999f80f9d469e" -dependencies = [ - "cc", - "tree-sitter", -] - [[package]] name = "tree-sitter-elixir" version = "0.1.0" @@ -8464,26 +8445,6 @@ dependencies = [ "tree-sitter", ] -[[package]] -name = "tree-sitter-toml" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca517f578a98b23d20780247cc2688407fa81effad5b627a5a364ec3339b53e8" -dependencies = [ - "cc", - "tree-sitter", -] - -[[package]] -name = "tree-sitter-typescript" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "079c695c32d39ad089101c66393aeaca30e967fba3486a91f573d2f0e12d290a" -dependencies = [ - "cc", - "tree-sitter", -] - [[package]] name = "tree-sitter-typescript" version = "0.20.2" @@ -9923,9 +9884,9 @@ dependencies = [ "tree-sitter", "tree-sitter-bash", "tree-sitter-c", - "tree-sitter-cpp 0.20.0", + "tree-sitter-cpp", "tree-sitter-css", - "tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=4ba9dab6e2602960d95b2b625f3386c27e08084e)", + "tree-sitter-elixir", "tree-sitter-elm", "tree-sitter-embedded-template", "tree-sitter-glsl", @@ -9942,8 +9903,8 @@ dependencies = [ "tree-sitter-rust", "tree-sitter-scheme", "tree-sitter-svelte", - "tree-sitter-toml 0.5.1", - "tree-sitter-typescript 0.20.2 (git+https://github.com/tree-sitter/tree-sitter-typescript?rev=5d20856f34315b068c41edaee2ac8a100081d259)", + "tree-sitter-toml", + "tree-sitter-typescript", "tree-sitter-yaml", "unindent", "url", diff --git a/crates/semantic_index/Cargo.toml b/crates/semantic_index/Cargo.toml index 637f3f4487443825ace9b98dbe73690ce02ec250..3c7a6ff5df6df4b0ae7de9e0e7754a0e0d5850cc 100644 --- a/crates/semantic_index/Cargo.toml +++ b/crates/semantic_index/Cargo.toml @@ -54,11 +54,12 @@ tempdir.workspace = true ctor.workspace = true env_logger.workspace = true -tree-sitter-typescript = "*" -tree-sitter-json = "*" -tree-sitter-rust = "*" -tree-sitter-toml = "*" -tree-sitter-cpp = "*" -tree-sitter-elixir = "*" -tree-sitter-lua = "*" -tree-sitter-ruby = "*" +tree-sitter-typescript.workspace = true +tree-sitter-json.workspace = true +tree-sitter-rust.workspace = true +tree-sitter-toml.workspace = true +tree-sitter-cpp.workspace = true +tree-sitter-elixir.workspace = true +tree-sitter-lua.workspace = true +tree-sitter-ruby.workspace = true +tree-sitter-php.workspace = true diff --git a/crates/semantic_index/src/parsing.rs b/crates/semantic_index/src/parsing.rs index 677406931e0cc36cd32fd497a5f53337052421e8..3f7a850a5743a737ccb23aa5c91ee93317f3ae3d 100644 --- a/crates/semantic_index/src/parsing.rs +++ b/crates/semantic_index/src/parsing.rs @@ -200,7 +200,12 @@ impl CodeContextRetriever { let mut document_content = String::new(); for context_range in &context_match.context_ranges { - document_content.push_str(&content[context_range.clone()]); + add_content_from_range( + &mut document_content, + content, + context_range.clone(), + context_match.start_col, + ); document_content.push_str("\n"); } diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index 58d34649c7e953faf2ebf3bac5829e5474330f85..0411a8e5ecd70d503dd8dfcdfd5f19426e2e81c5 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -1017,6 +1017,156 @@ async fn test_code_context_retrieval_ruby() { ); } +#[gpui::test] +async fn test_code_context_retrieval_php() { + let language = php_lang(); + let mut retriever = CodeContextRetriever::new(); + + let text = r#" + 100) { + throw new Exception(message: 'Progress cannot be greater than 100'); + } + + if ($this->achievements()->find($achievement->id)) { + throw new Exception(message: 'User already has this Achievement'); + } + + $this->achievements()->attach($achievement, [ + 'progress' => $progress ?? null, + ]); + + $this->when(value: ($progress === null) || ($progress === 100), callback: fn (): ?array => event(new AchievementAwarded(achievement: $achievement, user: $this))); + } + + public function achievements(): BelongsToMany + { + return $this->belongsToMany(related: Achievement::class) + ->withPivot(columns: 'progress') + ->where('is_secret', false) + ->using(AchievementUser::class); + } + } + + interface Multiplier + { + public function qualifies(array $data): bool; + + public function setMultiplier(): int; + } + + enum AuditType: string + { + case Add = 'add'; + case Remove = 'remove'; + case Reset = 'reset'; + case LevelUp = 'level_up'; + } + + ?>"# + .unindent(); + + let documents = retriever.parse_file(&text, language.clone()).unwrap(); + + assert_documents_eq( + &documents, + &[ + ( + r#" + /* + This is a multiple-lines comment block + that spans over multiple + lines + */ + function functionName() { + echo "Hello world!"; + }"# + .unindent(), + 123, + ), + ( + r#" + trait HasAchievements + { + /** + * @throws \Exception + */ + public function grantAchievement(Achievement $achievement, $progress = null): void + {/* ... */} + + public function achievements(): BelongsToMany + {/* ... */} + }"# + .unindent(), + 177, + ), + (r#" + /** + * @throws \Exception + */ + public function grantAchievement(Achievement $achievement, $progress = null): void + { + if ($progress > 100) { + throw new Exception(message: 'Progress cannot be greater than 100'); + } + + if ($this->achievements()->find($achievement->id)) { + throw new Exception(message: 'User already has this Achievement'); + } + + $this->achievements()->attach($achievement, [ + 'progress' => $progress ?? null, + ]); + + $this->when(value: ($progress === null) || ($progress === 100), callback: fn (): ?array => event(new AchievementAwarded(achievement: $achievement, user: $this))); + }"#.unindent(), 245), + (r#" + public function achievements(): BelongsToMany + { + return $this->belongsToMany(related: Achievement::class) + ->withPivot(columns: 'progress') + ->where('is_secret', false) + ->using(AchievementUser::class); + }"#.unindent(), 902), + (r#" + interface Multiplier + { + public function qualifies(array $data): bool; + + public function setMultiplier(): int; + }"#.unindent(), + 1146), + (r#" + enum AuditType: string + { + case Add = 'add'; + case Remove = 'remove'; + case Reset = 'reset'; + case LevelUp = 'level_up'; + }"#.unindent(), 1265) + ], + ); +} + #[gpui::test] fn test_dot_product(mut rng: StdRng) { assert_eq!(dot(&[1., 0., 0., 0., 0.], &[0., 1., 0., 0., 0.]), 0.); @@ -1376,6 +1526,61 @@ fn lua_lang() -> Arc { ) } +fn php_lang() -> Arc { + Arc::new( + Language::new( + LanguageConfig { + name: "PHP".into(), + path_suffixes: vec!["php".into()], + collapsed_placeholder: "/* ... */".into(), + ..Default::default() + }, + Some(tree_sitter_php::language()), + ) + .with_embedding_query( + r#" + ( + (comment)* @context + . + [ + (function_definition + "function" @name + name: (_) @name + body: (_ + "{" @keep + "}" @keep) @collapse + ) + + (trait_declaration + "trait" @name + name: (_) @name) + + (method_declaration + "function" @name + name: (_) @name + body: (_ + "{" @keep + "}" @keep) @collapse + ) + + (interface_declaration + "interface" @name + name: (_) @name + ) + + (enum_declaration + "enum" @name + name: (_) @name + ) + + ] @item + ) + "#, + ) + .unwrap(), + ) +} + fn ruby_lang() -> Arc { Arc::new( Language::new( diff --git a/crates/zed/src/languages/php/config.toml b/crates/zed/src/languages/php/config.toml index e9de52745a153b63df0ed99c260d64b9aea65aab..19acb949e25c66be9890f9931f49a8e82f8bb972 100644 --- a/crates/zed/src/languages/php/config.toml +++ b/crates/zed/src/languages/php/config.toml @@ -9,3 +9,4 @@ brackets = [ { start = "(", end = ")", close = true, newline = true }, { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] }, ] +collapsed_placeholder = "/* ... */" diff --git a/crates/zed/src/languages/php/embedding.scm b/crates/zed/src/languages/php/embedding.scm new file mode 100644 index 0000000000000000000000000000000000000000..db277775b38fe43f5bc3dc981cf468048202dc17 --- /dev/null +++ b/crates/zed/src/languages/php/embedding.scm @@ -0,0 +1,36 @@ +( + (comment)* @context + . + [ + (function_definition + "function" @name + name: (_) @name + body: (_ + "{" @keep + "}" @keep) @collapse + ) + + (trait_declaration + "trait" @name + name: (_) @name) + + (method_declaration + "function" @name + name: (_) @name + body: (_ + "{" @keep + "}" @keep) @collapse + ) + + (interface_declaration + "interface" @name + name: (_) @name + ) + + (enum_declaration + "enum" @name + name: (_) @name + ) + + ] @item + ) diff --git a/crates/zed/src/languages/php/outline.scm b/crates/zed/src/languages/php/outline.scm index 4934bc494d0ae709ec52ea3fb46db518b8dc35d8..87986f1032e7189070add8d18f163b00432c6475 100644 --- a/crates/zed/src/languages/php/outline.scm +++ b/crates/zed/src/languages/php/outline.scm @@ -8,8 +8,6 @@ name: (_) @name ) @item - - (method_declaration "function" @context name: (_) @name @@ -24,3 +22,8 @@ "enum" @context name: (_) @name ) @item + +(trait_declaration + "trait" @context + name: (_) @name + ) @item From 646dabe1133b32c852bf9b41b22234723f442602 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 31 Jul 2023 16:40:03 +0300 Subject: [PATCH 102/160] Add buffer search history --- assets/keymaps/default.json | 7 + crates/gpui/src/app.rs | 6 + crates/search/src/buffer_search.rs | 230 ++++++++++++++++++++++++++++- crates/search/src/search.rs | 187 +++++++++++++++++++++++ crates/vim/src/normal/search.rs | 2 +- crates/vim/src/test.rs | 4 +- 6 files changed, 428 insertions(+), 8 deletions(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index adc55f8c91e8cd39ec72745975c988aaaac9fb7c..57fde112bfc5a9ab4d15f5a17f91afd6a89cbf82 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -227,6 +227,13 @@ "alt-enter": "search::SelectAllMatches" } }, + { + "context": "BufferSearchBar > Editor", + "bindings": { + "up": "search::PreviousHistoryQuery", + "down": "search::NextHistoryQuery" + } + }, { "context": "ProjectSearchBar", "bindings": { diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 7af363d596b63abe06f78717d8945dcba820d7fd..da601ba3510e3624b7acd0954f922082b2197755 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1128,6 +1128,12 @@ impl AppContext { self.keystroke_matcher.clear_bindings(); } + pub fn binding_for_action(&self, action: &dyn Action) -> Option<&Binding> { + self.keystroke_matcher + .bindings_for_action(action.id()) + .find(|binding| binding.action().eq(action)) + } + pub fn default_global(&mut self) -> &T { let type_id = TypeId::of::(); self.update(|this| { diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 54293050989c146e5bb39363c12281c46eea1a53..45842aa5617b4f87cf306aebdead2d9ae96d455f 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -1,6 +1,6 @@ use crate::{ - SearchOptions, SelectAllMatches, SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, - ToggleRegex, ToggleWholeWord, + NextHistoryQuery, PreviousHistoryQuery, SearchHistory, SearchOptions, SelectAllMatches, + SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleRegex, ToggleWholeWord, }; use collections::HashMap; use editor::Editor; @@ -46,6 +46,8 @@ pub fn init(cx: &mut AppContext) { cx.add_action(BufferSearchBar::select_prev_match_on_pane); cx.add_action(BufferSearchBar::select_all_matches_on_pane); cx.add_action(BufferSearchBar::handle_editor_cancel); + cx.add_action(BufferSearchBar::next_history_query); + cx.add_action(BufferSearchBar::previous_history_query); add_toggle_option_action::(SearchOptions::CASE_SENSITIVE, cx); add_toggle_option_action::(SearchOptions::WHOLE_WORD, cx); add_toggle_option_action::(SearchOptions::REGEX, cx); @@ -65,7 +67,7 @@ fn add_toggle_option_action(option: SearchOptions, cx: &mut AppContex } pub struct BufferSearchBar { - pub query_editor: ViewHandle, + query_editor: ViewHandle, active_searchable_item: Option>, active_match_index: Option, active_searchable_item_subscription: Option, @@ -76,6 +78,7 @@ pub struct BufferSearchBar { default_options: SearchOptions, query_contains_error: bool, dismissed: bool, + search_history: SearchHistory, } impl Entity for BufferSearchBar { @@ -106,6 +109,48 @@ impl View for BufferSearchBar { .map(|active_searchable_item| active_searchable_item.supported_options()) .unwrap_or_default(); + let previous_query_keystrokes = + cx.binding_for_action(&PreviousHistoryQuery {}) + .map(|binding| { + binding + .keystrokes() + .iter() + .map(|k| k.to_string()) + .collect::>() + }); + let next_query_keystrokes = cx.binding_for_action(&NextHistoryQuery {}).map(|binding| { + binding + .keystrokes() + .iter() + .map(|k| k.to_string()) + .collect::>() + }); + let new_placeholder_text = match (previous_query_keystrokes, next_query_keystrokes) { + (Some(previous_query_keystrokes), Some(next_query_keystrokes)) => { + format!( + "Search ({}/{} for previous/next query)", + previous_query_keystrokes.join(" "), + next_query_keystrokes.join(" ") + ) + } + (None, Some(next_query_keystrokes)) => { + format!( + "Search ({} for next query)", + next_query_keystrokes.join(" ") + ) + } + (Some(previous_query_keystrokes), None) => { + format!( + "Search ({} for previous query)", + previous_query_keystrokes.join(" ") + ) + } + (None, None) => String::new(), + }; + self.query_editor.update(cx, |editor, cx| { + editor.set_placeholder_text(new_placeholder_text, cx); + }); + Flex::row() .with_child( Flex::row() @@ -258,6 +303,7 @@ impl BufferSearchBar { pending_search: None, query_contains_error: false, dismissed: true, + search_history: SearchHistory::default(), } } @@ -341,7 +387,7 @@ impl BufferSearchBar { cx: &mut ViewContext, ) -> oneshot::Receiver<()> { let options = options.unwrap_or(self.default_options); - if query != self.query_editor.read(cx).text(cx) || self.search_options != options { + if query != self.query(cx) || self.search_options != options { self.query_editor.update(cx, |query_editor, cx| { query_editor.buffer().update(cx, |query_buffer, cx| { let len = query_buffer.len(cx); @@ -674,7 +720,7 @@ impl BufferSearchBar { fn update_matches(&mut self, cx: &mut ViewContext) -> oneshot::Receiver<()> { let (done_tx, done_rx) = oneshot::channel(); - let query = self.query_editor.read(cx).text(cx); + let query = self.query(cx); self.pending_search.take(); if let Some(active_searchable_item) = self.active_searchable_item.as_ref() { if query.is_empty() { @@ -707,6 +753,7 @@ impl BufferSearchBar { ) }; + let query_text = query.as_str().to_string(); let matches = active_searchable_item.find_matches(query, cx); let active_searchable_item = active_searchable_item.downgrade(); @@ -720,6 +767,7 @@ impl BufferSearchBar { .insert(active_searchable_item.downgrade(), matches); this.update_match_index(cx); + this.search_history.add(query_text); if !this.dismissed { let matches = this .searchable_items_with_matches @@ -753,6 +801,28 @@ impl BufferSearchBar { cx.notify(); } } + + fn next_history_query(&mut self, _: &NextHistoryQuery, cx: &mut ViewContext) { + if let Some(new_query) = self.search_history.next().map(str::to_string) { + let _ = self.search(&new_query, Some(self.search_options), cx); + } else { + self.search_history.reset_selection(); + let _ = self.search("", Some(self.search_options), cx); + } + } + + fn previous_history_query(&mut self, _: &PreviousHistoryQuery, cx: &mut ViewContext) { + if self.query(cx).is_empty() { + if let Some(new_query) = self.search_history.current().map(str::to_string) { + let _ = self.search(&new_query, Some(self.search_options), cx); + return; + } + } + + if let Some(new_query) = self.search_history.previous().map(str::to_string) { + let _ = self.search(&new_query, Some(self.search_options), cx); + } + } } #[cfg(test)] @@ -1333,4 +1403,154 @@ mod tests { ); }); } + + #[gpui::test] + async fn test_search_query_history(cx: &mut TestAppContext) { + crate::project_search::tests::init_test(cx); + + let buffer_text = r#" + A regular expression (shortened as regex or regexp;[1] also referred to as + rational expression[2][3]) is a sequence of characters that specifies a search + pattern in text. Usually such patterns are used by string-searching algorithms + for "find" or "find and replace" operations on strings, or for input validation. + "# + .unindent(); + let buffer = cx.add_model(|cx| Buffer::new(0, buffer_text, cx)); + let (window_id, _root_view) = cx.add_window(|_| EmptyView); + + let editor = cx.add_view(window_id, |cx| Editor::for_buffer(buffer.clone(), None, cx)); + + let search_bar = cx.add_view(window_id, |cx| { + let mut search_bar = BufferSearchBar::new(cx); + search_bar.set_active_pane_item(Some(&editor), cx); + search_bar.show(cx); + search_bar + }); + + // Add 3 search items into the history. + search_bar + .update(cx, |search_bar, cx| search_bar.search("a", None, cx)) + .await + .unwrap(); + search_bar + .update(cx, |search_bar, cx| search_bar.search("b", None, cx)) + .await + .unwrap(); + search_bar + .update(cx, |search_bar, cx| { + search_bar.search("c", Some(SearchOptions::CASE_SENSITIVE), cx) + }) + .await + .unwrap(); + // Ensure that the latest search is active. + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), "c"); + assert_eq!(search_bar.search_options, SearchOptions::CASE_SENSITIVE); + }); + + // Next history query after the latest should set the query to the empty string. + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), ""); + assert_eq!(search_bar.search_options, SearchOptions::CASE_SENSITIVE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), ""); + assert_eq!(search_bar.search_options, SearchOptions::CASE_SENSITIVE); + }); + + // First previous query for empty current query should set the query to the latest. + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), "c"); + assert_eq!(search_bar.search_options, SearchOptions::CASE_SENSITIVE); + }); + + // Further previous items should go over the history in reverse order. + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), "b"); + assert_eq!(search_bar.search_options, SearchOptions::CASE_SENSITIVE); + }); + + // Previous items should never go behind the first history item. + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), "a"); + assert_eq!(search_bar.search_options, SearchOptions::CASE_SENSITIVE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), "a"); + assert_eq!(search_bar.search_options, SearchOptions::CASE_SENSITIVE); + }); + + // Next items should go over the history in the original order. + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), "b"); + assert_eq!(search_bar.search_options, SearchOptions::CASE_SENSITIVE); + }); + + search_bar + .update(cx, |search_bar, cx| search_bar.search("ba", None, cx)) + .await + .unwrap(); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), "ba"); + assert_eq!(search_bar.search_options, SearchOptions::NONE); + }); + + // New search input should add another entry to history and move the selection to the end of the history. + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), "c"); + assert_eq!(search_bar.search_options, SearchOptions::NONE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), "b"); + assert_eq!(search_bar.search_options, SearchOptions::NONE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), "c"); + assert_eq!(search_bar.search_options, SearchOptions::NONE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), "ba"); + assert_eq!(search_bar.search_options, SearchOptions::NONE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_bar.read_with(cx, |search_bar, cx| { + assert_eq!(search_bar.query(cx), ""); + assert_eq!(search_bar.search_options, SearchOptions::NONE); + }); + } } diff --git a/crates/search/src/search.rs b/crates/search/src/search.rs index 58cda0c7dc5f819ec1b34cd97ff577331cc030b0..18e39155274c650d4f2dde860a4998e398a8bbbe 100644 --- a/crates/search/src/search.rs +++ b/crates/search/src/search.rs @@ -3,6 +3,7 @@ pub use buffer_search::BufferSearchBar; use gpui::{actions, Action, AppContext}; use project::search::SearchQuery; pub use project_search::{ProjectSearchBar, ProjectSearchView}; +use smallvec::SmallVec; pub mod buffer_search; pub mod project_search; @@ -21,6 +22,8 @@ actions!( SelectNextMatch, SelectPrevMatch, SelectAllMatches, + NextHistoryQuery, + PreviousHistoryQuery, ] ); @@ -65,3 +68,187 @@ impl SearchOptions { options } } + +const SEARCH_HISTORY_LIMIT: usize = 20; + +#[derive(Default, Debug)] +pub struct SearchHistory { + history: SmallVec<[String; SEARCH_HISTORY_LIMIT]>, + selected: Option, +} + +impl SearchHistory { + pub fn add(&mut self, search_string: String) { + if let Some(i) = self.selected { + if search_string == self.history[i] { + return; + } + } + + if let Some(previously_searched) = self.history.last_mut() { + if search_string.find(previously_searched.as_str()).is_some() { + *previously_searched = search_string; + self.selected = Some(self.history.len() - 1); + return; + } + } + + self.history.push(search_string); + if self.history.len() > SEARCH_HISTORY_LIMIT { + self.history.remove(0); + } + self.selected = Some(self.history.len() - 1); + } + + pub fn next(&mut self) -> Option<&str> { + let history_size = self.history.len(); + if history_size == 0 { + return None; + } + + let selected = self.selected?; + if selected == history_size - 1 { + return None; + } + let next_index = selected + 1; + self.selected = Some(next_index); + Some(&self.history[next_index]) + } + + pub fn current(&self) -> Option<&str> { + Some(&self.history[self.selected?]) + } + + pub fn previous(&mut self) -> Option<&str> { + let history_size = self.history.len(); + if history_size == 0 { + return None; + } + + let prev_index = match self.selected { + Some(selected_index) => { + if selected_index == 0 { + return None; + } else { + selected_index - 1 + } + } + None => history_size - 1, + }; + + self.selected = Some(prev_index); + Some(&self.history[prev_index]) + } + + pub fn reset_selection(&mut self) { + self.selected = None; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_add() { + let mut search_history = SearchHistory::default(); + assert_eq!( + search_history.current(), + None, + "No current selection should be set fo the default search history" + ); + + search_history.add("rust".to_string()); + assert_eq!( + search_history.current(), + Some("rust"), + "Newly added item should be selected" + ); + + // check if duplicates are not added + search_history.add("rust".to_string()); + assert_eq!( + search_history.history.len(), + 1, + "Should not add a duplicate" + ); + assert_eq!(search_history.current(), Some("rust")); + + // check if new string containing the previous string replaces it + search_history.add("rustlang".to_string()); + assert_eq!( + search_history.history.len(), + 1, + "Should replace previous item if it's a substring" + ); + assert_eq!(search_history.current(), Some("rustlang")); + + // push enough items to test SEARCH_HISTORY_LIMIT + for i in 0..SEARCH_HISTORY_LIMIT * 2 { + search_history.add(format!("item{i}")); + } + assert!(search_history.history.len() <= SEARCH_HISTORY_LIMIT); + } + + #[test] + fn test_next_and_previous() { + let mut search_history = SearchHistory::default(); + assert_eq!( + search_history.next(), + None, + "Default search history should not have a next item" + ); + + search_history.add("Rust".to_string()); + assert_eq!(search_history.next(), None); + search_history.add("JavaScript".to_string()); + assert_eq!(search_history.next(), None); + search_history.add("TypeScript".to_string()); + assert_eq!(search_history.next(), None); + + assert_eq!(search_history.current(), Some("TypeScript")); + + assert_eq!(search_history.previous(), Some("JavaScript")); + assert_eq!(search_history.current(), Some("JavaScript")); + + assert_eq!(search_history.previous(), Some("Rust")); + assert_eq!(search_history.current(), Some("Rust")); + + assert_eq!(search_history.previous(), None); + assert_eq!(search_history.current(), Some("Rust")); + + assert_eq!(search_history.next(), Some("JavaScript")); + assert_eq!(search_history.current(), Some("JavaScript")); + + assert_eq!(search_history.next(), Some("TypeScript")); + assert_eq!(search_history.current(), Some("TypeScript")); + + assert_eq!(search_history.next(), None); + assert_eq!(search_history.current(), Some("TypeScript")); + } + + #[test] + fn test_reset_selection() { + let mut search_history = SearchHistory::default(); + search_history.add("Rust".to_string()); + search_history.add("JavaScript".to_string()); + search_history.add("TypeScript".to_string()); + + assert_eq!(search_history.current(), Some("TypeScript")); + search_history.reset_selection(); + assert_eq!(search_history.current(), None); + assert_eq!( + search_history.previous(), + Some("TypeScript"), + "Should start from the end after reset on previous item query" + ); + + search_history.previous(); + assert_eq!(search_history.current(), Some("JavaScript")); + search_history.previous(); + assert_eq!(search_history.current(), Some("Rust")); + + search_history.reset_selection(); + assert_eq!(search_history.current(), None); + } +} diff --git a/crates/vim/src/normal/search.rs b/crates/vim/src/normal/search.rs index d584c575d2970e3fa1131acb08b1adfac7ca38a9..614866d9c9c4ce7b3aca398dcc978f79298dfc81 100644 --- a/crates/vim/src/normal/search.rs +++ b/crates/vim/src/normal/search.rs @@ -222,7 +222,7 @@ mod test { }); search_bar.read_with(cx.cx, |bar, cx| { - assert_eq!(bar.query_editor.read(cx).text(cx), "cc"); + assert_eq!(bar.query(cx), "cc"); }); deterministic.run_until_parked(); diff --git a/crates/vim/src/test.rs b/crates/vim/src/test.rs index 98d8cb8749996909757367c36e2591817030bebe..474f2128fc5194857e2c5436a802c5ce99791cc8 100644 --- a/crates/vim/src/test.rs +++ b/crates/vim/src/test.rs @@ -99,7 +99,7 @@ async fn test_buffer_search(cx: &mut gpui::TestAppContext) { }); search_bar.read_with(cx.cx, |bar, cx| { - assert_eq!(bar.query_editor.read(cx).text(cx), ""); + assert_eq!(bar.query(cx), ""); }) } @@ -175,7 +175,7 @@ async fn test_selection_on_search(cx: &mut gpui::TestAppContext) { }); search_bar.read_with(cx.cx, |bar, cx| { - assert_eq!(bar.query_editor.read(cx).text(cx), "cc"); + assert_eq!(bar.query(cx), "cc"); }); // wait for the query editor change event to fire. From 634baeedb4a0a59b303182519ef1279b72319c8f Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 1 Aug 2023 01:23:51 +0300 Subject: [PATCH 103/160] Add project search history --- assets/keymaps/default.json | 7 + crates/search/src/project_search.rs | 283 +++++++++++++++++++++++++++- crates/search/src/search.rs | 2 +- 3 files changed, 289 insertions(+), 3 deletions(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 57fde112bfc5a9ab4d15f5a17f91afd6a89cbf82..38ec8ffb4057d2404c5e38e1150b27bb3acd155d 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -240,6 +240,13 @@ "escape": "project_search::ToggleFocus" } }, + { + "context": "ProjectSearchBar > Editor", + "bindings": { + "up": "search::PreviousHistoryQuery", + "down": "search::NextHistoryQuery" + } + }, { "context": "ProjectSearchView", "bindings": { diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 87307264f507070ced1303c072c8b9a59cee5cc9..1b4e32f4b832483c160293a5d792b39d62a1a628 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1,6 +1,6 @@ use crate::{ - SearchOptions, SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleRegex, - ToggleWholeWord, + NextHistoryQuery, PreviousHistoryQuery, SearchHistory, SearchOptions, SelectNextMatch, + SelectPrevMatch, ToggleCaseSensitive, ToggleRegex, ToggleWholeWord, }; use anyhow::Context; use collections::HashMap; @@ -56,6 +56,8 @@ pub fn init(cx: &mut AppContext) { cx.add_action(ProjectSearchBar::search_in_new); cx.add_action(ProjectSearchBar::select_next_match); cx.add_action(ProjectSearchBar::select_prev_match); + cx.add_action(ProjectSearchBar::next_history_query); + cx.add_action(ProjectSearchBar::previous_history_query); cx.capture_action(ProjectSearchBar::tab); cx.capture_action(ProjectSearchBar::tab_previous); add_toggle_option_action::(SearchOptions::CASE_SENSITIVE, cx); @@ -83,6 +85,7 @@ struct ProjectSearch { match_ranges: Vec>, active_query: Option, search_id: usize, + search_history: SearchHistory, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -131,6 +134,7 @@ impl ProjectSearch { match_ranges: Default::default(), active_query: None, search_id: 0, + search_history: SearchHistory::default(), } } @@ -144,6 +148,7 @@ impl ProjectSearch { match_ranges: self.match_ranges.clone(), active_query: self.active_query.clone(), search_id: self.search_id, + search_history: self.search_history.clone(), }) } @@ -152,6 +157,7 @@ impl ProjectSearch { .project .update(cx, |project, cx| project.search(query.clone(), cx)); self.search_id += 1; + self.search_history.add(query.as_str().to_string()); self.active_query = Some(query); self.match_ranges.clear(); self.pending_search = Some(cx.spawn_weak(|this, mut cx| async move { @@ -202,6 +208,7 @@ impl ProjectSearch { }); self.search_id += 1; self.match_ranges.clear(); + self.search_history.add(query.as_str().to_string()); self.pending_search = Some(cx.spawn(|this, mut cx| async move { let results = search?.await.log_err()?; @@ -278,6 +285,49 @@ impl View for ProjectSearchView { Cow::Borrowed("No results") }; + let previous_query_keystrokes = + cx.binding_for_action(&PreviousHistoryQuery {}) + .map(|binding| { + binding + .keystrokes() + .iter() + .map(|k| k.to_string()) + .collect::>() + }); + let next_query_keystrokes = + cx.binding_for_action(&NextHistoryQuery {}).map(|binding| { + binding + .keystrokes() + .iter() + .map(|k| k.to_string()) + .collect::>() + }); + let new_placeholder_text = match (previous_query_keystrokes, next_query_keystrokes) { + (Some(previous_query_keystrokes), Some(next_query_keystrokes)) => { + format!( + "Search ({}/{} for previous/next query)", + previous_query_keystrokes.join(" "), + next_query_keystrokes.join(" ") + ) + } + (None, Some(next_query_keystrokes)) => { + format!( + "Search ({} for next query)", + next_query_keystrokes.join(" ") + ) + } + (Some(previous_query_keystrokes), None) => { + format!( + "Search ({} for previous query)", + previous_query_keystrokes.join(" ") + ) + } + (None, None) => String::new(), + }; + self.query_editor.update(cx, |editor, cx| { + editor.set_placeholder_text(new_placeholder_text, cx); + }); + MouseEventHandler::::new(0, cx, |_, _| { Label::new(text, theme.search.results_status.clone()) .aligned() @@ -1152,6 +1202,47 @@ impl ProjectSearchBar { false } } + + fn next_history_query(&mut self, _: &NextHistoryQuery, cx: &mut ViewContext) { + if let Some(search_view) = self.active_project_search.as_ref() { + search_view.update(cx, |search_view, cx| { + let new_query = search_view.model.update(cx, |model, _| { + if let Some(new_query) = model.search_history.next().map(str::to_string) { + new_query + } else { + model.search_history.reset_selection(); + String::new() + } + }); + search_view.set_query(&new_query, cx); + }); + } + } + + fn previous_history_query(&mut self, _: &PreviousHistoryQuery, cx: &mut ViewContext) { + if let Some(search_view) = self.active_project_search.as_ref() { + search_view.update(cx, |search_view, cx| { + if search_view.query_editor.read(cx).text(cx).is_empty() { + if let Some(new_query) = search_view + .model + .read(cx) + .search_history + .current() + .map(str::to_string) + { + search_view.set_query(&new_query, cx); + return; + } + } + + if let Some(new_query) = search_view.model.update(cx, |model, _| { + model.search_history.previous().map(str::to_string) + }) { + search_view.set_query(&new_query, cx); + } + }); + } + } } impl Entity for ProjectSearchBar { @@ -1333,6 +1424,7 @@ pub mod tests { use editor::DisplayPoint; use gpui::{color::Color, executor::Deterministic, TestAppContext}; use project::FakeFs; + use semantic_index::semantic_index_settings::SemanticIndexSettings; use serde_json::json; use settings::SettingsStore; use std::sync::Arc; @@ -1758,6 +1850,192 @@ pub mod tests { }); } + #[gpui::test] + async fn test_search_query_history(cx: &mut TestAppContext) { + init_test(cx); + + let fs = FakeFs::new(cx.background()); + fs.insert_tree( + "/dir", + json!({ + "one.rs": "const ONE: usize = 1;", + "two.rs": "const TWO: usize = one::ONE + one::ONE;", + "three.rs": "const THREE: usize = one::ONE + two::TWO;", + "four.rs": "const FOUR: usize = one::ONE + three::THREE;", + }), + ) + .await; + let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; + let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + workspace.update(cx, |workspace, cx| { + ProjectSearchView::deploy(workspace, &workspace::NewSearch, cx) + }); + + let search_view = cx.read(|cx| { + workspace + .read(cx) + .active_pane() + .read(cx) + .active_item() + .and_then(|item| item.downcast::()) + .expect("Search view expected to appear after new search event trigger") + }); + + let search_bar = cx.add_view(window_id, |cx| { + let mut search_bar = ProjectSearchBar::new(); + search_bar.set_active_pane_item(Some(&search_view), cx); + // search_bar.show(cx); + search_bar + }); + + // Add 3 search items into the history + another unsubmitted one. + search_view.update(cx, |search_view, cx| { + search_view.search_options = SearchOptions::CASE_SENSITIVE; + search_view + .query_editor + .update(cx, |query_editor, cx| query_editor.set_text("ONE", cx)); + search_view.search(cx); + }); + cx.foreground().run_until_parked(); + search_view.update(cx, |search_view, cx| { + search_view + .query_editor + .update(cx, |query_editor, cx| query_editor.set_text("TWO", cx)); + search_view.search(cx); + }); + cx.foreground().run_until_parked(); + search_view.update(cx, |search_view, cx| { + search_view + .query_editor + .update(cx, |query_editor, cx| query_editor.set_text("THREE", cx)); + search_view.search(cx); + }); + cx.foreground().run_until_parked(); + search_view.update(cx, |search_view, cx| { + search_view.query_editor.update(cx, |query_editor, cx| { + query_editor.set_text("JUST_TEXT_INPUT", cx) + }); + }); + cx.foreground().run_until_parked(); + + // Ensure that the latest input with search settings is active. + search_view.update(cx, |search_view, cx| { + assert_eq!( + search_view.query_editor.read(cx).text(cx), + "JUST_TEXT_INPUT" + ); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + + // Next history query after the latest should set the query to the empty string. + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), ""); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), ""); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + + // First previous query for empty current query should set the query to the latest submitted one. + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), "THREE"); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + + // Further previous items should go over the history in reverse order. + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), "TWO"); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + + // Previous items should never go behind the first history item. + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), "ONE"); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), "ONE"); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + + // Next items should go over the history in the original order. + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), "TWO"); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + + search_view.update(cx, |search_view, cx| { + search_view + .query_editor + .update(cx, |query_editor, cx| query_editor.set_text("TWO_NEW", cx)); + search_view.search(cx); + }); + cx.foreground().run_until_parked(); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), "TWO_NEW"); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + + // New search input should add another entry to history and move the selection to the end of the history. + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), "THREE"); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.previous_history_query(&PreviousHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), "TWO"); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), "THREE"); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), "TWO_NEW"); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + search_bar.update(cx, |search_bar, cx| { + search_bar.next_history_query(&NextHistoryQuery, cx); + }); + search_view.update(cx, |search_view, cx| { + assert_eq!(search_view.query_editor.read(cx).text(cx), ""); + assert_eq!(search_view.search_options, SearchOptions::CASE_SENSITIVE); + }); + } + pub fn init_test(cx: &mut TestAppContext) { cx.foreground().forbid_parking(); let fonts = cx.font_cache(); @@ -1767,6 +2045,7 @@ pub mod tests { cx.update(|cx| { cx.set_global(SettingsStore::test(cx)); cx.set_global(ActiveSearches::default()); + settings::register::(cx); theme::init((), cx); cx.update_global::(|store, _| { diff --git a/crates/search/src/search.rs b/crates/search/src/search.rs index 18e39155274c650d4f2dde860a4998e398a8bbbe..f1711afec20c73bd9965bd77140994aa1c1145b8 100644 --- a/crates/search/src/search.rs +++ b/crates/search/src/search.rs @@ -71,7 +71,7 @@ impl SearchOptions { const SEARCH_HISTORY_LIMIT: usize = 20; -#[derive(Default, Debug)] +#[derive(Default, Debug, Clone)] pub struct SearchHistory { history: SmallVec<[String; SEARCH_HISTORY_LIMIT]>, selected: Option, From 9a50b43eaa0f52a0a223e198141b8091ec618548 Mon Sep 17 00:00:00 2001 From: KCaverly Date: Mon, 31 Jul 2023 21:03:02 -0400 Subject: [PATCH 104/160] add templating languages html, erb, heex, svelte as entire parseable file types --- crates/semantic_index/src/parsing.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/semantic_index/src/parsing.rs b/crates/semantic_index/src/parsing.rs index 3f7a850a5743a737ccb23aa5c91ee93317f3ae3d..643db8c79827819a2e274aa2eb82d37cfb6bc4a2 100644 --- a/crates/semantic_index/src/parsing.rs +++ b/crates/semantic_index/src/parsing.rs @@ -21,7 +21,8 @@ const CODE_CONTEXT_TEMPLATE: &str = "The below code snippet is from file ''\n\n```\n\n```"; const ENTIRE_FILE_TEMPLATE: &str = "The below snippet is from file ''\n\n```\n\n```"; -pub const PARSEABLE_ENTIRE_FILE_TYPES: &[&str] = &["TOML", "YAML", "CSS"]; +pub const PARSEABLE_ENTIRE_FILE_TYPES: &[&str] = + &["TOML", "YAML", "CSS", "HEEX", "ERB", "SVELTE", "HTML"]; pub struct CodeContextRetriever { pub parser: Parser, From e221f23018d9b9883327712874b1237725922a0a Mon Sep 17 00:00:00 2001 From: KCaverly Date: Tue, 1 Aug 2023 10:30:34 -0400 Subject: [PATCH 105/160] add support for markdown files to semantic search --- crates/semantic_index/src/parsing.rs | 16 ++++++++++++++++ crates/semantic_index/src/semantic_index.rs | 1 + 2 files changed, 17 insertions(+) diff --git a/crates/semantic_index/src/parsing.rs b/crates/semantic_index/src/parsing.rs index 643db8c79827819a2e274aa2eb82d37cfb6bc4a2..cef23862c563f470000306fde5ac32f95a50a458 100644 --- a/crates/semantic_index/src/parsing.rs +++ b/crates/semantic_index/src/parsing.rs @@ -21,6 +21,7 @@ const CODE_CONTEXT_TEMPLATE: &str = "The below code snippet is from file ''\n\n```\n\n```"; const ENTIRE_FILE_TEMPLATE: &str = "The below snippet is from file ''\n\n```\n\n```"; +const MARKDOWN_CONTEXT_TEMPLATE: &str = "The below file contents is from file ''\n\n"; pub const PARSEABLE_ENTIRE_FILE_TYPES: &[&str] = &["TOML", "YAML", "CSS", "HEEX", "ERB", "SVELTE", "HTML"]; @@ -70,6 +71,19 @@ impl CodeContextRetriever { }]) } + fn parse_markdown_file(&self, relative_path: &Path, content: &str) -> Result> { + let document_span = MARKDOWN_CONTEXT_TEMPLATE + .replace("", relative_path.to_string_lossy().as_ref()) + .replace("", &content); + + Ok(vec![Document { + range: 0..content.len(), + content: document_span, + embedding: Vec::new(), + name: "Markdown".to_string(), + }]) + } + fn get_matches_in_file( &mut self, content: &str, @@ -136,6 +150,8 @@ impl CodeContextRetriever { if PARSEABLE_ENTIRE_FILE_TYPES.contains(&language_name.as_ref()) { return self.parse_entire_file(relative_path, language_name, &content); + } else if &language_name.to_string() == &"Markdown".to_string() { + return self.parse_markdown_file(relative_path, &content); } let mut documents = self.parse_file(content, language)?; diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index bd114de216a0a30b3271b56c2b627439a7e70a0e..23c75f40149cc4af2fb981844a6330dec3a638bb 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -613,6 +613,7 @@ impl SemanticIndex { .await { if !PARSEABLE_ENTIRE_FILE_TYPES.contains(&language.name().as_ref()) + && &language.name().as_ref() != &"Markdown" && language .grammar() .and_then(|grammar| grammar.embedding_config.as_ref()) From eb26fb2d45357e35d7d39edb8e2b3c6e0c1e9dbb Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Tue, 1 Aug 2023 11:52:53 -0400 Subject: [PATCH 106/160] Fix variable names --- crates/editor/src/editor.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 5270d6f951870fa952e9a0a33f2f229a1d71ff98..a4d9259a6d7e7a63dc1606450ecef9d2aa4c53f4 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -4221,7 +4221,7 @@ impl Editor { _: &SortLinesCaseSensitive, cx: &mut ViewContext, ) { - self.manipulate_lines(cx, |text| text.sort()) + self.manipulate_lines(cx, |lines| lines.sort()) } pub fn sort_lines_case_insensitive( @@ -4229,7 +4229,7 @@ impl Editor { _: &SortLinesCaseInsensitive, cx: &mut ViewContext, ) { - self.manipulate_lines(cx, |text| text.sort_by_key(|line| line.to_lowercase())) + self.manipulate_lines(cx, |lines| lines.sort_by_key(|line| line.to_lowercase())) } pub fn reverse_lines(&mut self, _: &ReverseLines, cx: &mut ViewContext) { @@ -4267,19 +4267,19 @@ impl Editor { let text = buffer .text_for_range(start_point..end_point) .collect::(); - let mut text = text.split("\n").collect_vec(); + let mut lines = text.split("\n").collect_vec(); - let text_len = text.len(); - callback(&mut text); + let lines_len = lines.len(); + callback(&mut lines); // This is a current limitation with selections. // If we wanted to support removing or adding lines, we'd need to fix the logic associated with selections. debug_assert!( - text.len() == text_len, + lines.len() == lines_len, "callback should not change the number of lines" ); - edits.push((start_point..end_point, text.join("\n"))); + edits.push((start_point..end_point, lines.join("\n"))); let start_anchor = buffer.anchor_after(start_point); let end_anchor = buffer.anchor_before(end_point); From 3cee181f99c6de5ae264a119124d0ca94c0ffe3d Mon Sep 17 00:00:00 2001 From: Julia Date: Tue, 1 Aug 2023 14:04:29 -0400 Subject: [PATCH 107/160] Improve panic message usefulness on local dev builds --- crates/zed/src/main.rs | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index e44ab3e33acbb213f69b230a80075aea07890c85..2a1fef6a56efc5bf1c5496c935c134a752767066 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -45,6 +45,7 @@ use std::{ use sum_tree::Bias; use terminal_view::{get_working_directory, TerminalSettings, TerminalView}; use util::{ + channel::ReleaseChannel, http::{self, HttpClient}, paths::PathLikeWithPosition, }; @@ -415,22 +416,41 @@ fn init_panic_hook(app: &App, installation_id: Option) { panic::set_hook(Box::new(move |info| { let prior_panic_count = PANIC_COUNT.fetch_add(1, Ordering::SeqCst); if prior_panic_count > 0 { - std::panic::resume_unwind(Box::new(())); + // Give the panic-ing thread time to write the panic file + loop { + std::thread::yield_now(); + } } - let app_version = ZED_APP_VERSION - .or_else(|| platform.app_version().ok()) - .map_or("dev".to_string(), |v| v.to_string()); - let thread = thread::current(); - let thread = thread.name().unwrap_or(""); + let thread_name = thread.name().unwrap_or(""); - let payload = info.payload(); - let payload = None - .or_else(|| payload.downcast_ref::<&str>().map(|s| s.to_string())) - .or_else(|| payload.downcast_ref::().map(|s| s.clone())) + let payload = info + .payload() + .downcast_ref::<&str>() + .map(|s| s.to_string()) + .or_else(|| info.payload().downcast_ref::().map(|s| s.clone())) .unwrap_or_else(|| "Box".to_string()); + if *util::channel::RELEASE_CHANNEL == ReleaseChannel::Dev { + let location = info.location().unwrap(); + let backtrace = Backtrace::new(); + eprintln!( + "Thread {:?} panicked with {:?} at {}:{}:{}\n{:?}", + thread_name, + payload, + location.file(), + location.line(), + location.column(), + backtrace, + ); + std::process::exit(-1); + } + + let app_version = ZED_APP_VERSION + .or_else(|| platform.app_version().ok()) + .map_or("dev".to_string(), |v| v.to_string()); + let backtrace = Backtrace::new(); let mut backtrace = backtrace .frames() @@ -447,7 +467,7 @@ fn init_panic_hook(app: &App, installation_id: Option) { } let panic_data = Panic { - thread: thread.into(), + thread: thread_name.into(), payload: payload.into(), location_data: info.location().map(|location| LocationData { file: location.file().into(), From b695c42e1152ad9019b2c6bfcaf21834fe00b386 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 1 Aug 2023 22:28:04 -0600 Subject: [PATCH 108/160] WIP: Return WindowHandle from AppContext::add_window --- crates/gpui/src/app.rs | 352 ++++++++++++++++-------- crates/gpui/src/app/ref_counts.rs | 23 ++ crates/gpui/src/app/test_app_context.rs | 11 +- 3 files changed, 268 insertions(+), 118 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index da601ba3510e3624b7acd0954f922082b2197755..b2d732d1700d3da202afc965b484463efda5958e 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -130,8 +130,12 @@ pub trait BorrowAppContext { } pub trait BorrowWindowContext { - fn read_with T>(&self, window_id: usize, f: F) -> T; - fn update T>(&mut self, window_id: usize, f: F) -> T; + fn read_with(&self, window_id: usize, f: F) -> T + where + F: FnOnce(&WindowContext) -> T; + fn update(&mut self, window_id: usize, f: F) -> T + where + F: FnOnce(&mut WindowContext) -> T; } #[derive(Clone)] @@ -402,7 +406,7 @@ impl AsyncAppContext { &mut self, window_options: WindowOptions, build_root_view: F, - ) -> (usize, ViewHandle) + ) -> WindowHandle where T: View, F: FnOnce(&mut ViewContext) -> T, @@ -1300,7 +1304,7 @@ impl AppContext { &mut self, window_options: WindowOptions, build_root_view: F, - ) -> (usize, ViewHandle) + ) -> WindowHandle where V: View, F: FnOnce(&mut ViewContext) -> V, @@ -1311,9 +1315,8 @@ impl AppContext { this.platform .open_window(window_id, window_options, this.foreground.clone()); let window = this.build_window(window_id, platform_window, build_root_view); - let root_view = window.root_view().clone().downcast::().unwrap(); this.windows.insert(window_id, window); - (window_id, root_view) + WindowHandle::new(window_id, this.ref_counts.clone()) }) } @@ -3802,6 +3805,131 @@ impl Clone for WeakModelHandle { impl Copy for WeakModelHandle {} +pub struct WindowHandle { + any_handle: AnyWindowHandle, + view_type: PhantomData, +} + +impl WindowHandle { + fn id(&self) -> usize { + self.any_handle.id() + } + + fn new(window_id: usize, ref_counts: Arc>) -> Self { + WindowHandle { + any_handle: AnyWindowHandle::new::(window_id, ref_counts), + view_type: PhantomData, + } + } + + fn root(&self, cx: &impl BorrowAppContext) -> ViewHandle { + self.read_with(cx, |cx| cx.root_view().clone().downcast().unwrap()) + } + + pub fn read_with(&self, cx: &C, read: F) -> R + where + C: BorrowAppContext, + F: FnOnce(&WindowContext) -> R, + { + cx.read_with(|cx| cx.read_window(self.id(), read).unwrap()) + } + + pub fn update(&self, cx: &mut C, update: F) -> R + where + C: BorrowAppContext, + F: FnOnce(&mut WindowContext) -> R, + { + cx.update(|cx| cx.update_window(self.id(), update).unwrap()) + } + + pub fn update_root(&self, cx: &mut C, update: F) -> R + where + C: BorrowAppContext, + F: FnOnce(&mut V, &mut ViewContext) -> R, + { + let window_id = self.id(); + cx.update(|cx| { + cx.update_window(window_id, |cx| { + cx.root_view() + .clone() + .downcast::() + .unwrap() + .update(cx, update) + }) + .unwrap() + }) + } + + pub fn read_root<'a>(&self, cx: &'a AppContext) -> &'a V { + let root_view = cx + .read_window(self.id(), |cx| cx.root_view().clone().downcast().unwrap()) + .unwrap(); + root_view.read(cx) + } + + pub fn read_root_with(&self, cx: &C, read: F) -> R + where + C: BorrowAppContext, + F: FnOnce(&V, &ViewContext) -> R, + { + self.read_with(cx, |cx| { + cx.root_view() + .downcast_ref::() + .unwrap() + .read_with(cx, read) + }) + } + + pub fn add_view(&self, cx: &mut C, build_view: F) -> ViewHandle + where + C: BorrowAppContext, + U: View, + F: FnOnce(&mut ViewContext) -> U, + { + self.update(cx, |cx| cx.add_view(build_view)) + } +} + +pub struct AnyWindowHandle { + window_id: usize, + root_view_type: TypeId, + ref_counts: Arc>, + + #[cfg(any(test, feature = "test-support"))] + handle_id: usize, +} + +impl AnyWindowHandle { + fn new(window_id: usize, ref_counts: Arc>) -> Self { + ref_counts.lock().inc_window(window_id); + + #[cfg(any(test, feature = "test-support"))] + let handle_id = ref_counts + .lock() + .leak_detector + .lock() + .handle_created(None, window_id); + + Self { + window_id, + root_view_type: TypeId::of::(), + ref_counts, + #[cfg(any(test, feature = "test-support"))] + handle_id, + } + } + + pub fn id(&self) -> usize { + self.window_id + } +} + +impl Drop for AnyWindowHandle { + fn drop(&mut self) { + self.ref_counts.lock().dec_window(self.window_id) + } +} + #[repr(transparent)] pub struct ViewHandle { any_handle: AnyViewHandle, @@ -4684,11 +4812,11 @@ mod tests { } } - let (_, view) = cx.add_window(|_| View { render_count: 0 }); + let window = cx.add_window(|_| View { render_count: 0 }); let called_defer = Rc::new(AtomicBool::new(false)); let called_after_window_update = Rc::new(AtomicBool::new(false)); - view.update(cx, |this, cx| { + window.update_root(cx, |this, cx| { assert_eq!(this.render_count, 1); cx.defer({ let called_defer = called_defer.clone(); @@ -4712,7 +4840,7 @@ mod tests { assert!(called_defer.load(SeqCst)); assert!(called_after_window_update.load(SeqCst)); - assert_eq!(view.read_with(cx, |view, _| view.render_count), 3); + assert_eq!(window.read_root_with(cx, |view, _| view.render_count), 3); } #[crate::test(self)] @@ -4751,9 +4879,9 @@ mod tests { } } - let (window_id, _root_view) = cx.add_window(|cx| View::new(None, cx)); - let handle_1 = cx.add_view(window_id, |cx| View::new(None, cx)); - let handle_2 = cx.add_view(window_id, |cx| View::new(Some(handle_1.clone()), cx)); + let window = cx.add_window(|cx| View::new(None, cx)); + let handle_1 = window.add_view(cx, |cx| View::new(None, cx)); + let handle_2 = window.add_view(cx, |cx| View::new(Some(handle_1.clone()), cx)); assert_eq!(cx.read(|cx| cx.views.len()), 3); handle_1.update(cx, |view, cx| { @@ -4813,11 +4941,11 @@ mod tests { } let mouse_down_count = Arc::new(AtomicUsize::new(0)); - let (window_id, _) = cx.add_window(Default::default(), |_| View { + let window = cx.add_window(Default::default(), |_| View { mouse_down_count: mouse_down_count.clone(), }); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { // Ensure window's root element is in a valid lifecycle state. cx.dispatch_event( Event::MouseDown(MouseButtonEvent { @@ -4876,9 +5004,11 @@ mod tests { let model = cx.add_model(|_| Model { released: model_released.clone(), }); - let (window_id, view) = cx.add_window(Default::default(), |_| View { + let window = cx.add_window(Default::default(), |_| View { released: view_released.clone(), }); + let view = window.root(cx); + assert!(!model_released.get()); assert!(!view_released.get()); @@ -4900,7 +5030,7 @@ mod tests { assert!(model_release_observed.get()); drop(view); - cx.update_window(window_id, |cx| cx.remove_window()); + window.update(cx, |cx| cx.remove_window()); assert!(view_released.get()); assert!(view_release_observed.get()); } @@ -4913,8 +5043,9 @@ mod tests { type Event = String; } - let (window_id, handle_1) = cx.add_window(|_| TestView::default()); - let handle_2 = cx.add_view(window_id, |_| TestView::default()); + let window = cx.add_window(|_| TestView::default()); + let handle_1 = window.root(cx); + let handle_2 = window.add_view(cx, |_| TestView::default()); let handle_3 = cx.add_model(|_| Model); handle_1.update(cx, |_, cx| { @@ -5140,9 +5271,9 @@ mod tests { type Event = (); } - let (window_id, _root_view) = cx.add_window(|_| TestView::default()); - let observing_view = cx.add_view(window_id, |_| TestView::default()); - let emitting_view = cx.add_view(window_id, |_| TestView::default()); + let window = cx.add_window(|_| TestView::default()); + let observing_view = window.add_view(cx, |_| TestView::default()); + let emitting_view = window.add_view(cx, |_| TestView::default()); let observing_model = cx.add_model(|_| Model); let observed_model = cx.add_model(|_| Model); @@ -5165,7 +5296,7 @@ mod tests { #[crate::test(self)] fn test_view_emit_before_subscribe_in_same_update_cycle(cx: &mut AppContext) { - let (_, view) = cx.add_window::(Default::default(), |cx| { + let window = cx.add_window::(Default::default(), |cx| { drop(cx.subscribe(&cx.handle(), { move |this, _, _, _| this.events.push("dropped before flush".into()) })); @@ -5181,7 +5312,7 @@ mod tests { TestView { events: Vec::new() } }); - assert_eq!(view.read(cx).events, ["before emit"]); + assert_eq!(window.read_root(cx).events, ["before emit"]); } #[crate::test(self)] @@ -5195,7 +5326,8 @@ mod tests { type Event = (); } - let (_, view) = cx.add_window(|_| TestView::default()); + let window = cx.add_window(|_| TestView::default()); + let view = window.root(cx); let model = cx.add_model(|_| Model { state: "old-state".into(), }); @@ -5216,7 +5348,7 @@ mod tests { #[crate::test(self)] fn test_view_notify_before_observe_in_same_update_cycle(cx: &mut AppContext) { - let (_, view) = cx.add_window::(Default::default(), |cx| { + let window = cx.add_window::(Default::default(), |cx| { drop(cx.observe(&cx.handle(), { move |this, _, _| this.events.push("dropped before flush".into()) })); @@ -5232,7 +5364,7 @@ mod tests { TestView { events: Vec::new() } }); - assert_eq!(view.read(cx).events, ["before notify"]); + assert_eq!(window.read_root(cx).events, ["before notify"]); } #[crate::test(self)] @@ -5243,7 +5375,8 @@ mod tests { } let model = cx.add_model(|_| Model); - let (_, view) = cx.add_window(|_| TestView::default()); + let window = cx.add_window(|_| TestView::default()); + let view = window.root(cx); view.update(cx, |_, cx| { model.update(cx, |_, cx| cx.notify()); @@ -5267,8 +5400,8 @@ mod tests { type Event = (); } - let (window_id, _root_view) = cx.add_window(|_| TestView::default()); - let observing_view = cx.add_view(window_id, |_| TestView::default()); + let window = cx.add_window(|_| TestView::default()); + let observing_view = window.add_view(cx, |_| TestView::default()); let observing_model = cx.add_model(|_| Model); let observed_model = cx.add_model(|_| Model); @@ -5390,9 +5523,9 @@ mod tests { } } - let (window_id, _root_view) = cx.add_window(|_| View); - let observing_view = cx.add_view(window_id, |_| View); - let observed_view = cx.add_view(window_id, |_| View); + let window = cx.add_window(|_| View); + let observing_view = window.add_view(cx, |_| View); + let observed_view = window.add_view(cx, |_| View); let observation_count = Rc::new(RefCell::new(0)); observing_view.update(cx, |_, cx| { @@ -5474,13 +5607,14 @@ mod tests { } let view_events: Arc>> = Default::default(); - let (window_id, view_1) = cx.add_window(|_| View { + let window = cx.add_window(|_| View { events: view_events.clone(), name: "view 1".to_string(), child: None, }); - let view_2 = cx - .update_window(window_id, |cx| { + let view_1 = window.root(cx); + let view_2 = window + .update(cx, |cx| { let view_2 = cx.add_view(|_| View { events: view_events.clone(), name: "view 2".to_string(), @@ -5731,40 +5865,34 @@ mod tests { }) .detach(); - let (window_id, view_1) = - cx.add_window(Default::default(), |_| ViewA { id: 1, child: None }); - let view_2 = cx - .update_window(window_id, |cx| { - let child = cx.add_view(|_| ViewB { id: 2, child: None }); - view_1.update(cx, |view, cx| { - view.child = Some(child.clone().into_any()); - cx.notify(); - }); - child - }) - .unwrap(); - let view_3 = cx - .update_window(window_id, |cx| { - let child = cx.add_view(|_| ViewA { id: 3, child: None }); - view_2.update(cx, |view, cx| { - view.child = Some(child.clone().into_any()); - cx.notify(); - }); - child - }) - .unwrap(); - let view_4 = cx - .update_window(window_id, |cx| { - let child = cx.add_view(|_| ViewB { id: 4, child: None }); - view_3.update(cx, |view, cx| { - view.child = Some(child.clone().into_any()); - cx.notify(); - }); - child - }) - .unwrap(); + let window = cx.add_window(Default::default(), |_| ViewA { id: 1, child: None }); + let view_1 = window.root(cx); + let view_2 = window.update(cx, |cx| { + let child = cx.add_view(|_| ViewB { id: 2, child: None }); + view_1.update(cx, |view, cx| { + view.child = Some(child.clone().into_any()); + cx.notify(); + }); + child + }); + let view_3 = window.update(cx, |cx| { + let child = cx.add_view(|_| ViewA { id: 3, child: None }); + view_2.update(cx, |view, cx| { + view.child = Some(child.clone().into_any()); + cx.notify(); + }); + child + }); + let view_4 = window.update(cx, |cx| { + let child = cx.add_view(|_| ViewB { id: 4, child: None }); + view_3.update(cx, |view, cx| { + view.child = Some(child.clone().into_any()); + cx.notify(); + }); + child + }); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { cx.dispatch_action(Some(view_4.id()), &Action("bar".to_string())) }); @@ -5786,31 +5914,27 @@ mod tests { // Remove view_1, which doesn't propagate the action - let (window_id, view_2) = - cx.add_window(Default::default(), |_| ViewB { id: 2, child: None }); - let view_3 = cx - .update_window(window_id, |cx| { - let child = cx.add_view(|_| ViewA { id: 3, child: None }); - view_2.update(cx, |view, cx| { - view.child = Some(child.clone().into_any()); - cx.notify(); - }); - child - }) - .unwrap(); - let view_4 = cx - .update_window(window_id, |cx| { - let child = cx.add_view(|_| ViewB { id: 4, child: None }); - view_3.update(cx, |view, cx| { - view.child = Some(child.clone().into_any()); - cx.notify(); - }); - child - }) - .unwrap(); + let window = cx.add_window(Default::default(), |_| ViewB { id: 2, child: None }); + let view_2 = window.root(cx); + let view_3 = window.update(cx, |cx| { + let child = cx.add_view(|_| ViewA { id: 3, child: None }); + view_2.update(cx, |view, cx| { + view.child = Some(child.clone().into_any()); + cx.notify(); + }); + child + }); + let view_4 = window.update(cx, |cx| { + let child = cx.add_view(|_| ViewB { id: 4, child: None }); + view_3.update(cx, |view, cx| { + view.child = Some(child.clone().into_any()); + cx.notify(); + }); + child + }); actions.borrow_mut().clear(); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { cx.dispatch_action(Some(view_4.id()), &Action("bar".to_string())) }); @@ -5887,7 +6011,7 @@ mod tests { view_3.keymap_context.add_identifier("b"); view_3.keymap_context.add_identifier("c"); - let (window_id, _view_1) = cx.add_window(Default::default(), |cx| { + let window = cx.add_window(Default::default(), |cx| { let view_2 = cx.add_view(|cx| { let view_3 = cx.add_view(|cx| { cx.focus_self(); @@ -6006,13 +6130,14 @@ mod tests { } } - let (window_id, view_1) = cx.add_window(|cx| { + let window = cx.add_window(|cx| { let view_2 = cx.add_view(|cx| { cx.focus_self(); View2 {} }); View1 { child: view_2 } }); + let view_1 = window.root(cx); let view_2 = view_1.read_with(cx, |view, _| view.child.clone()); cx.update(|cx| { @@ -6138,7 +6263,8 @@ mod tests { impl_actions!(test, [ActionWithArg]); - let (window_id, view) = cx.add_window(|_| View); + let window = cx.add_window(|_| View); + let view = window.root(cx); cx.update(|cx| { cx.add_global_action(|_: &ActionWithArg, _| {}); cx.add_bindings(vec![ @@ -6250,7 +6376,8 @@ mod tests { } } - let (_, view) = cx.add_window(|_| Counter(0)); + let window = cx.add_window(|_| Counter(0)); + let view = window.root(cx); let condition1 = view.condition(cx, |view, _| view.0 == 2); let condition2 = view.condition(cx, |view, _| view.0 == 3); @@ -6272,15 +6399,15 @@ mod tests { #[crate::test(self)] #[should_panic] async fn test_view_condition_timeout(cx: &mut TestAppContext) { - let (_, view) = cx.add_window(|_| TestView::default()); - view.condition(cx, |_, _| false).await; + let window = cx.add_window(|_| TestView::default()); + window.root(cx).condition(cx, |_, _| false).await; } #[crate::test(self)] #[should_panic(expected = "view dropped with pending condition")] async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) { - let (window_id, _root_view) = cx.add_window(|_| TestView::default()); - let view = cx.add_view(window_id, |_| TestView::default()); + let window = cx.add_window(|_| TestView::default()); + let view = window.add_view(cx, |_| TestView::default()); let condition = view.condition(cx, |_, _| false); cx.update(|_| drop(view)); @@ -6305,22 +6432,21 @@ mod tests { } } - let (window_id, root_view) = cx.add_window(Default::default(), |_| View(0)); - cx.update_window(window_id, |cx| { + let window = cx.add_window(Default::default(), |_| View(0)); + let root_view = window.root(cx); + window.update(cx, |cx| { assert_eq!( cx.window.rendered_views[&root_view.id()].name(), Some("render count: 0") ); }); - let view = cx - .update_window(window_id, |cx| { - cx.refresh_windows(); - cx.add_view(|_| View(0)) - }) - .unwrap(); + let view = window.update(cx, |cx| { + cx.refresh_windows(); + cx.add_view(|_| View(0)) + }); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { assert_eq!( cx.window.rendered_views[&root_view.id()].name(), Some("render count: 1") @@ -6333,7 +6459,7 @@ mod tests { cx.update(|cx| cx.refresh_windows()); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { assert_eq!( cx.window.rendered_views[&root_view.id()].name(), Some("render count: 2") @@ -6349,7 +6475,7 @@ mod tests { drop(view); }); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { assert_eq!( cx.window.rendered_views[&root_view.id()].name(), Some("render count: 3") @@ -6397,7 +6523,7 @@ mod tests { } let events = Rc::new(RefCell::new(Vec::new())); - let (window_1, _) = cx.add_window(|cx: &mut ViewContext| { + let window_1 = cx.add_window(|cx: &mut ViewContext| { cx.observe_window_activation({ let events = events.clone(); move |this, active, _| events.borrow_mut().push((this.0, active)) @@ -6407,7 +6533,7 @@ mod tests { }); assert_eq!(mem::take(&mut *events.borrow_mut()), [("window 1", true)]); - let (window_2, _) = cx.add_window(|cx: &mut ViewContext| { + let window_2 = cx.add_window(|cx: &mut ViewContext| { cx.observe_window_activation({ let events = events.clone(); move |this, active, _| events.borrow_mut().push((this.0, active)) @@ -6420,7 +6546,7 @@ mod tests { [("window 1", false), ("window 2", true)] ); - let (window_3, _) = cx.add_window(|cx: &mut ViewContext| { + let window_3 = cx.add_window(|cx: &mut ViewContext| { cx.observe_window_activation({ let events = events.clone(); move |this, active, _| events.borrow_mut().push((this.0, active)) diff --git a/crates/gpui/src/app/ref_counts.rs b/crates/gpui/src/app/ref_counts.rs index f0c1699f165ea8100ccdfe1facbfb8a3ac1a2d8e..c076a8a476fe2f91484f7f3e407707455be6c442 100644 --- a/crates/gpui/src/app/ref_counts.rs +++ b/crates/gpui/src/app/ref_counts.rs @@ -23,8 +23,10 @@ struct ElementStateRefCount { #[derive(Default)] pub struct RefCounts { + window_counts: HashMap, entity_counts: HashMap, element_state_counts: HashMap, + dropped_windows: HashSet, dropped_models: HashSet, dropped_views: HashSet<(usize, usize)>, dropped_element_states: HashSet, @@ -43,6 +45,18 @@ impl RefCounts { } } + pub fn inc_window(&mut self, window_id: usize) { + match self.window_counts.entry(window_id) { + Entry::Occupied(mut entry) => { + *entry.get_mut() += 1; + } + Entry::Vacant(entry) => { + entry.insert(1); + self.dropped_windows.remove(&window_id); + } + } + } + pub fn inc_model(&mut self, model_id: usize) { match self.entity_counts.entry(model_id) { Entry::Occupied(mut entry) => { @@ -85,6 +99,15 @@ impl RefCounts { } } + pub fn dec_window(&mut self, window_id: usize) { + let count = self.window_counts.get_mut(&window_id).unwrap(); + *count -= 1; + if *count == 0 { + self.entity_counts.remove(&window_id); + self.dropped_windows.insert(window_id); + } + } + pub fn dec_model(&mut self, model_id: usize) { let count = self.entity_counts.get_mut(&model_id).unwrap(); *count -= 1; diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 2fa86998837984d97139f4248493a29f70fa4f75..0fa64f531e1217fe9b9a66e4feee39f20a5f1623 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -6,7 +6,7 @@ use crate::{ platform::{Event, InputHandler, KeyDownEvent, Platform}, Action, AppContext, BorrowAppContext, BorrowWindowContext, Entity, FontCache, Handle, ModelContext, ModelHandle, Subscription, Task, View, ViewContext, ViewHandle, WeakHandle, - WindowContext, + WindowContext, WindowHandle, }; use collections::BTreeMap; use futures::Future; @@ -148,17 +148,18 @@ impl TestAppContext { self.cx.borrow_mut().add_model(build_model) } - pub fn add_window(&mut self, build_root_view: F) -> (usize, ViewHandle) + pub fn add_window(&mut self, build_root_view: F) -> WindowHandle where T: View, F: FnOnce(&mut ViewContext) -> T, { - let (window_id, view) = self + let window = self .cx .borrow_mut() .add_window(Default::default(), build_root_view); - self.simulate_window_activation(Some(window_id)); - (window_id, view) + self.simulate_window_activation(Some(window.id())); + + WindowHandle::new(window.id(), self.cx.borrow_mut().ref_counts.clone()) } pub fn add_view(&mut self, window_id: usize, build_view: F) -> ViewHandle From 300ce61bd0d6bf77153669eb3be044a870e76676 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 2 Aug 2023 08:25:40 -0600 Subject: [PATCH 109/160] WIP --- crates/gpui/src/app.rs | 76 ++++++++++++++----------- crates/gpui/src/app/ref_counts.rs | 5 +- crates/gpui/src/app/test_app_context.rs | 2 +- crates/gpui/src/app/window.rs | 2 +- 4 files changed, 47 insertions(+), 38 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index b2d732d1700d3da202afc965b484463efda5958e..adabcf0a8b9585ee1c3f86621477d12d6ff28c40 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -498,8 +498,8 @@ pub struct AppContext { // Action Types -> Action Handlers global_actions: HashMap>, keystroke_matcher: KeymapMatcher, - next_entity_id: usize, - next_window_id: usize, + next_id: usize, + // next_window_id: usize, next_subscription_id: usize, frame_count: usize, @@ -558,8 +558,7 @@ impl AppContext { actions: Default::default(), global_actions: Default::default(), keystroke_matcher: KeymapMatcher::default(), - next_entity_id: 0, - next_window_id: 0, + next_id: 0, next_subscription_id: 0, frame_count: 0, subscriptions: Default::default(), @@ -1230,7 +1229,7 @@ impl AppContext { F: FnOnce(&mut ModelContext) -> T, { self.update(|this| { - let model_id = post_inc(&mut this.next_entity_id); + let model_id = post_inc(&mut this.next_id); let handle = ModelHandle::new(model_id, &this.ref_counts); let mut cx = ModelContext::new(this, model_id); let model = build_model(&mut cx); @@ -1310,7 +1309,7 @@ impl AppContext { F: FnOnce(&mut ViewContext) -> V, { self.update(|this| { - let window_id = post_inc(&mut this.next_window_id); + let window_id = post_inc(&mut this.next_id); let platform_window = this.platform .open_window(window_id, window_options, this.foreground.clone()); @@ -1326,7 +1325,7 @@ impl AppContext { F: FnOnce(&mut ViewContext) -> V, { self.update(|this| { - let window_id = post_inc(&mut this.next_window_id); + let window_id = post_inc(&mut this.next_id); let platform_window = this.platform.add_status_item(window_id); let window = this.build_window(window_id, platform_window, build_root_view); let root_view = window.root_view().clone().downcast::().unwrap(); @@ -3810,6 +3809,7 @@ pub struct WindowHandle { view_type: PhantomData, } +#[allow(dead_code)] impl WindowHandle { fn id(&self) -> usize { self.any_handle.id() @@ -3922,6 +3922,17 @@ impl AnyWindowHandle { pub fn id(&self) -> usize { self.window_id } + + pub fn downcast(self) -> Option> { + if TypeId::of::() == self.root_view_type { + Some(WindowHandle { + any_handle: self, + view_type: PhantomData, + }) + } else { + None + } + } } impl Drop for AnyWindowHandle { @@ -5613,20 +5624,18 @@ mod tests { child: None, }); let view_1 = window.root(cx); - let view_2 = window - .update(cx, |cx| { - let view_2 = cx.add_view(|_| View { - events: view_events.clone(), - name: "view 2".to_string(), - child: None, - }); - view_1.update(cx, |view_1, cx| { - view_1.child = Some(view_2.clone().into_any()); - cx.notify(); - }); - view_2 - }) - .unwrap(); + let view_2 = window.update(cx, |cx| { + let view_2 = cx.add_view(|_| View { + events: view_events.clone(), + name: "view 2".to_string(), + child: None, + }); + view_1.update(cx, |view_1, cx| { + view_1.child = Some(view_2.clone().into_any()); + cx.notify(); + }); + view_2 + }); let observed_events: Arc>> = Default::default(); view_1.update(cx, |_, cx| { @@ -6071,26 +6080,26 @@ mod tests { } }); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { cx.dispatch_keystroke(&Keystroke::parse("a").unwrap()) }); assert_eq!(&*actions.borrow(), &["2 a"]); actions.borrow_mut().clear(); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { cx.dispatch_keystroke(&Keystroke::parse("b").unwrap()); }); assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]); actions.borrow_mut().clear(); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { cx.dispatch_keystroke(&Keystroke::parse("c").unwrap()); }); assert_eq!(&*actions.borrow(), &["3 c"]); actions.borrow_mut().clear(); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { cx.dispatch_keystroke(&Keystroke::parse("d").unwrap()); }); assert_eq!(&*actions.borrow(), &["2 d"]); @@ -6201,7 +6210,7 @@ mod tests { // Check that global actions do not have a binding, even if a binding does exist in another view assert_eq!( - &available_actions(window_id, view_1.id(), cx), + &available_actions(window.id(), view_1.id(), cx), &[ ("test::Action1", vec![Keystroke::parse("a").unwrap()]), ("test::GlobalAction", vec![]) @@ -6210,7 +6219,7 @@ mod tests { // Check that view 1 actions and bindings are available even when called from view 2 assert_eq!( - &available_actions(window_id, view_2.id(), cx), + &available_actions(window.id(), view_2.id(), cx), &[ ("test::Action1", vec![Keystroke::parse("a").unwrap()]), ("test::Action2", vec![Keystroke::parse("b").unwrap()]), @@ -6273,7 +6282,7 @@ mod tests { ]); }); - let actions = cx.available_actions(window_id, view.id()); + let actions = cx.available_actions(window.id(), view.id()); assert_eq!( actions[0].1.as_any().downcast_ref::(), Some(&ActionWithArg { arg: false }) @@ -6559,25 +6568,25 @@ mod tests { [("window 2", false), ("window 3", true)] ); - cx.simulate_window_activation(Some(window_2)); + cx.simulate_window_activation(Some(window_2.id())); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 3", false), ("window 2", true)] ); - cx.simulate_window_activation(Some(window_1)); + cx.simulate_window_activation(Some(window_1.id())); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 2", false), ("window 1", true)] ); - cx.simulate_window_activation(Some(window_3)); + cx.simulate_window_activation(Some(window_3.id())); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 1", false), ("window 3", true)] ); - cx.simulate_window_activation(Some(window_3)); + cx.simulate_window_activation(Some(window_3.id())); assert_eq!(mem::take(&mut *events.borrow_mut()), []); } @@ -6633,12 +6642,13 @@ mod tests { let child_rendered = Rc::new(Cell::new(false)); let child_dropped = Rc::new(Cell::new(false)); - let (_, root_view) = cx.add_window(|cx| Parent { + let window = cx.add_window(|cx| Parent { child: Some(cx.add_view(|_| Child { rendered: child_rendered.clone(), dropped: child_dropped.clone(), })), }); + let root_view = window.root(cx); assert!(child_rendered.take()); assert!(!child_dropped.take()); diff --git a/crates/gpui/src/app/ref_counts.rs b/crates/gpui/src/app/ref_counts.rs index c076a8a476fe2f91484f7f3e407707455be6c442..74563d05bc00d403dd768fe08fd269da9a8bfb5a 100644 --- a/crates/gpui/src/app/ref_counts.rs +++ b/crates/gpui/src/app/ref_counts.rs @@ -23,7 +23,6 @@ struct ElementStateRefCount { #[derive(Default)] pub struct RefCounts { - window_counts: HashMap, entity_counts: HashMap, element_state_counts: HashMap, dropped_windows: HashSet, @@ -46,7 +45,7 @@ impl RefCounts { } pub fn inc_window(&mut self, window_id: usize) { - match self.window_counts.entry(window_id) { + match self.entity_counts.entry(window_id) { Entry::Occupied(mut entry) => { *entry.get_mut() += 1; } @@ -100,7 +99,7 @@ impl RefCounts { } pub fn dec_window(&mut self, window_id: usize) { - let count = self.window_counts.get_mut(&window_id).unwrap(); + let count = self.entity_counts.get_mut(&window_id).unwrap(); *count -= 1; if *count == 0 { self.entity_counts.remove(&window_id); diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 0fa64f531e1217fe9b9a66e4feee39f20a5f1623..80f10374665f9c2215ca4b2582088dd43df3bb04 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -60,7 +60,7 @@ impl TestAppContext { RefCounts::new(leak_detector), (), ); - cx.next_entity_id = first_entity_id; + cx.next_id = first_entity_id; let cx = TestAppContext { cx: Rc::new(RefCell::new(cx)), foreground_platform, diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index e4beb58873cfb3599be6fc81a2ad0bd87ce811c3..9dc5d99bc5e8ac0b0994aae8b66169151d9b0b93 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -1176,7 +1176,7 @@ impl<'a> WindowContext<'a> { F: FnOnce(&mut ViewContext) -> Option, { let window_id = self.window_id; - let view_id = post_inc(&mut self.next_entity_id); + let view_id = post_inc(&mut self.next_id); let mut cx = ViewContext::mutable(self, view_id); let handle = if let Some(view) = build_view(&mut cx) { let mut keymap_context = KeymapContext::default(); From 4c7d60ed131f563edc5c937e5bf3cf654f1c9178 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 2 Aug 2023 09:07:35 -0700 Subject: [PATCH 110/160] Upgrade to rust 1.71 --- Dockerfile | 2 +- rust-toolchain.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2a78d37cbbcadd1bd7afaf612be5767a09abb581..77d011490e5821f282240af7d387b19f67a0edbe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax = docker/dockerfile:1.2 -FROM rust:1.70-bullseye as builder +FROM rust:1.71-bullseye as builder WORKDIR app COPY . . diff --git a/rust-toolchain.toml b/rust-toolchain.toml index f78a67ddb344b48057437e80661698500a1cb302..50003020e9baf17e3e9e0b50babb19c354356e15 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.70" +channel = "1.71" components = [ "rustfmt" ] targets = [ "x86_64-apple-darwin", "aarch64-apple-darwin", "wasm32-wasi" ] From a127b0d3e6168de644267541b5bd29b6adfec55c Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 2 Aug 2023 09:19:23 -0700 Subject: [PATCH 111/160] Fix warnings surfaced in Rust 1.71 --- crates/collab/src/tests/randomized_integration_tests.rs | 2 +- crates/editor/src/display_map/inlay_map.rs | 4 +--- crates/editor/src/inlay_hint_cache.rs | 1 - crates/project/src/worktree.rs | 2 +- crates/sum_tree/src/cursor.rs | 2 +- crates/vim/src/normal/search.rs | 2 +- crates/zed/src/zed.rs | 1 - 7 files changed, 5 insertions(+), 9 deletions(-) diff --git a/crates/collab/src/tests/randomized_integration_tests.rs b/crates/collab/src/tests/randomized_integration_tests.rs index 8062a12b83264f8ac4521f9071318d45fb5b0265..ae3e609b9397e77c0ee7d3fe3c6a1bcc4347a8fd 100644 --- a/crates/collab/src/tests/randomized_integration_tests.rs +++ b/crates/collab/src/tests/randomized_integration_tests.rs @@ -183,7 +183,7 @@ async fn apply_server_operation( let username; { let mut plan = plan.lock(); - let mut user = plan.user(user_id); + let user = plan.user(user_id); if user.online { return false; } diff --git a/crates/editor/src/display_map/inlay_map.rs b/crates/editor/src/display_map/inlay_map.rs index 6a59cecae8e2ecb172cd3e72b447b29cb33d42c4..9794ac45c1190ec88ccb471ee61630ec50d320ca 100644 --- a/crates/editor/src/display_map/inlay_map.rs +++ b/crates/editor/src/display_map/inlay_map.rs @@ -397,7 +397,7 @@ impl InlayMap { buffer_snapshot: MultiBufferSnapshot, mut buffer_edits: Vec>, ) -> (InlaySnapshot, Vec) { - let mut snapshot = &mut self.snapshot; + let snapshot = &mut self.snapshot; if buffer_edits.is_empty() { if snapshot.buffer.trailing_excerpt_update_count() @@ -572,7 +572,6 @@ impl InlayMap { }) .collect(); let buffer_snapshot = snapshot.buffer.clone(); - drop(snapshot); let (snapshot, edits) = self.sync(buffer_snapshot, buffer_edits); (snapshot, edits) } @@ -635,7 +634,6 @@ impl InlayMap { } log::info!("removing inlays: {:?}", to_remove); - drop(snapshot); let (snapshot, edits) = self.splice(to_remove, to_insert); (snapshot, edits) } diff --git a/crates/editor/src/inlay_hint_cache.rs b/crates/editor/src/inlay_hint_cache.rs index 63076ba234d52c53556bb9fc9a8a43acbf314a96..3d4ea3d6f28279273ce683a7a88997905d1feef0 100644 --- a/crates/editor/src/inlay_hint_cache.rs +++ b/crates/editor/src/inlay_hint_cache.rs @@ -571,7 +571,6 @@ fn new_update_task( if let Some(buffer) = refresh_multi_buffer.buffer(pending_refresh_query.buffer_id) { - drop(refresh_multi_buffer); editor.inlay_hint_cache.update_tasks.insert( pending_refresh_query.excerpt_id, UpdateTask { diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index b0795818b8d62557b688313fcfe8d017c2b55795..9e30796bbc58e3176ef73e8acb95358565fc6b34 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -2369,7 +2369,7 @@ impl BackgroundScannerState { } // Remove any git repositories whose .git entry no longer exists. - let mut snapshot = &mut self.snapshot; + let snapshot = &mut self.snapshot; let mut repositories = mem::take(&mut snapshot.git_repositories); let mut repository_entries = mem::take(&mut snapshot.repository_entries); repositories.retain(|work_directory_id, _| { diff --git a/crates/sum_tree/src/cursor.rs b/crates/sum_tree/src/cursor.rs index efd6ac145e0978ffc65cb5261bcd616b51aa71a6..12ab12dc27b9a2611983806665aa840e0ac32caa 100644 --- a/crates/sum_tree/src/cursor.rs +++ b/crates/sum_tree/src/cursor.rs @@ -202,7 +202,7 @@ where self.position = D::default(); } - let mut entry = self.stack.last_mut().unwrap(); + let entry = self.stack.last_mut().unwrap(); if !descending { if entry.index == 0 { self.stack.pop(); diff --git a/crates/vim/src/normal/search.rs b/crates/vim/src/normal/search.rs index 614866d9c9c4ce7b3aca398dcc978f79298dfc81..9375c4e78da53d58df29b636c768db56f9ac4fb9 100644 --- a/crates/vim/src/normal/search.rs +++ b/crates/vim/src/normal/search.rs @@ -93,7 +93,7 @@ fn search_submit(workspace: &mut Workspace, _: &SearchSubmit, cx: &mut ViewConte pane.update(cx, |pane, cx| { if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::() { search_bar.update(cx, |search_bar, cx| { - let mut state = &mut vim.state.search; + let state = &mut vim.state.search; let mut count = state.count; // in the case that the query has changed, the search bar diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 4b0bf1cd4c6aec42aa2d636b474828ef452cbe03..b67bf0bab48b76052b5ee10668b627f81e7f0042 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -545,7 +545,6 @@ pub fn handle_keymap_file_changes( reload_keymaps(cx, &keymap_content); } }) - .detach(); })); } } From b0ec05a73242bc131d1e788fa278a057e4dfb569 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Wed, 2 Aug 2023 13:50:30 -0400 Subject: [PATCH 112/160] v0.99.x dev --- Cargo.lock | 2 +- crates/zed/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a00b0735866ddd7bd4957e45f50fab0413f6c01f..fbf4e750c62c920a7158c712d48c4f6cd380bf6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9815,7 +9815,7 @@ dependencies = [ [[package]] name = "zed" -version = "0.98.0" +version = "0.99.0" dependencies = [ "activity_indicator", "ai", diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index a5877aaccb41a390776a16d8627653d2c0afa40c..95d6445d1762e3eedbd3c57141ba2c61595dd70b 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.98.0" +version = "0.99.0" publish = false [lib] From 60e190e5001553e4c3c0cd472e6feb45ea07aca2 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 2 Aug 2023 12:08:56 -0600 Subject: [PATCH 113/160] WIP --- crates/copilot/src/sign_in.rs | 13 ++++++------- crates/gpui/src/app.rs | 10 +++++----- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/crates/copilot/src/sign_in.rs b/crates/copilot/src/sign_in.rs index 803cb5cc85636d45946446b4e059a5e7d9aeae30..fec8f27c9730d776f4311498635772fb8a2791a5 100644 --- a/crates/copilot/src/sign_in.rs +++ b/crates/copilot/src/sign_in.rs @@ -4,7 +4,7 @@ use gpui::{ geometry::rect::RectF, platform::{WindowBounds, WindowKind, WindowOptions}, AnyElement, AnyViewHandle, AppContext, ClipboardItem, Element, Entity, View, ViewContext, - ViewHandle, + WindowHandle, }; use theme::ui::modal; @@ -18,14 +18,14 @@ const COPILOT_SIGN_UP_URL: &'static str = "https://github.com/features/copilot"; pub fn init(cx: &mut AppContext) { if let Some(copilot) = Copilot::global(cx) { - let mut code_verification: Option> = None; + let mut code_verification: Option> = None; cx.observe(&copilot, move |copilot, cx| { let status = copilot.read(cx).status(); match &status { crate::Status::SigningIn { prompt } => { if let Some(code_verification_handle) = code_verification.as_mut() { - let window_id = code_verification_handle.window_id(); + let window_id = code_verification_handle.id(); let updated = cx.update_window(window_id, |cx| { code_verification_handle.update(cx, |code_verification, cx| { code_verification.set_status(status.clone(), cx) @@ -66,7 +66,7 @@ pub fn init(cx: &mut AppContext) { fn create_copilot_auth_window( cx: &mut AppContext, status: &Status, -) -> ViewHandle { +) -> WindowHandle { let window_size = theme::current(cx).copilot.modal.dimensions(); let window_options = WindowOptions { bounds: WindowBounds::Fixed(RectF::new(Default::default(), window_size)), @@ -78,10 +78,9 @@ fn create_copilot_auth_window( is_movable: true, screen: None, }; - let (_, view) = cx.add_window(window_options, |_cx| { + cx.add_window(window_options, |_cx| { CopilotCodeVerification::new(status.clone()) - }); - view + }) } pub struct CopilotCodeVerification { diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index adabcf0a8b9585ee1c3f86621477d12d6ff28c40..9c0e50647c6138fc94ee388220cb65d0112e3dd6 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -3811,10 +3811,6 @@ pub struct WindowHandle { #[allow(dead_code)] impl WindowHandle { - fn id(&self) -> usize { - self.any_handle.id() - } - fn new(window_id: usize, ref_counts: Arc>) -> Self { WindowHandle { any_handle: AnyWindowHandle::new::(window_id, ref_counts), @@ -3822,7 +3818,11 @@ impl WindowHandle { } } - fn root(&self, cx: &impl BorrowAppContext) -> ViewHandle { + pub fn id(&self) -> usize { + self.any_handle.id() + } + + pub fn root(&self, cx: &impl BorrowAppContext) -> ViewHandle { self.read_with(cx, |cx| cx.root_view().clone().downcast().unwrap()) } From 9e755bb85582f2cbe953492e9a14ce0a166f24c1 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 2 Aug 2023 12:15:39 -0700 Subject: [PATCH 114/160] Revert "Extract syntax highlighting properties from tree-sitter highlight queries (#2797)" This reverts commit 45c635872b5ef7bb8994e16d593aa25edf8e94bf, reversing changes made to f2b82369f27b79fdcaa6a4276bb047abddf7171c. --- crates/zed/src/languages/bash/highlights.scm | 2 +- crates/zed/src/languages/c/highlights.scm | 3 +- crates/zed/src/languages/c/injections.scm | 4 +- crates/zed/src/languages/cpp/highlights.scm | 4 +- crates/zed/src/languages/cpp/injections.scm | 4 +- crates/zed/src/languages/css/highlights.scm | 2 +- crates/zed/src/languages/elixir/embedding.scm | 6 +- .../zed/src/languages/elixir/highlights.scm | 18 +- .../zed/src/languages/elixir/injections.scm | 4 +- crates/zed/src/languages/elixir/outline.scm | 4 +- crates/zed/src/languages/elm/injections.scm | 2 +- crates/zed/src/languages/erb/injections.scm | 8 +- crates/zed/src/languages/glsl/highlights.scm | 4 +- crates/zed/src/languages/heex/injections.scm | 6 +- crates/zed/src/languages/html/injections.scm | 4 +- .../src/languages/javascript/highlights.scm | 6 +- crates/zed/src/languages/lua/highlights.scm | 10 +- crates/zed/src/languages/php/highlights.scm | 10 +- crates/zed/src/languages/php/injections.scm | 4 +- .../zed/src/languages/python/highlights.scm | 8 +- .../zed/src/languages/racket/highlights.scm | 7 +- crates/zed/src/languages/racket/outline.scm | 4 +- crates/zed/src/languages/ruby/brackets.scm | 2 +- crates/zed/src/languages/ruby/highlights.scm | 8 +- crates/zed/src/languages/rust/highlights.scm | 4 +- crates/zed/src/languages/rust/injections.scm | 4 +- .../zed/src/languages/scheme/highlights.scm | 4 +- crates/zed/src/languages/scheme/outline.scm | 4 +- .../zed/src/languages/svelte/injections.scm | 14 +- .../src/languages/typescript/highlights.scm | 10 +- styles/package.json | 1 - styles/src/build_themes.ts | 9 +- styles/src/build_tokens.ts | 4 +- styles/src/component/icon_button.ts | 5 +- styles/src/component/tab_bar_button.ts | 67 ++- styles/src/component/text_button.ts | 5 +- styles/src/style_tree/app.ts | 2 +- styles/src/style_tree/assistant.ts | 69 ++-- styles/src/style_tree/editor.ts | 32 +- styles/src/style_tree/feedback.ts | 2 +- styles/src/style_tree/picker.ts | 2 +- styles/src/style_tree/project_panel.ts | 16 +- styles/src/style_tree/status_bar.ts | 10 +- styles/src/style_tree/titlebar.ts | 4 +- styles/src/theme/create_theme.ts | 30 +- styles/src/theme/syntax.ts | 389 ++++++++++++++---- styles/src/theme/theme_config.ts | 6 +- styles/src/theme/tokens/theme.ts | 10 +- styles/src/themes/atelier/common.ts | 9 +- styles/src/themes/ayu/common.ts | 6 +- styles/src/themes/gruvbox/gruvbox-common.ts | 6 +- styles/src/themes/one/one-dark.ts | 4 +- styles/src/themes/one/one-light.ts | 2 + styles/src/themes/rose-pine/common.ts | 4 +- styles/src/types/extract_syntax_types.ts | 111 ----- styles/src/types/syntax.ts | 202 --------- styles/tsconfig.json | 4 +- 57 files changed, 554 insertions(+), 631 deletions(-) delete mode 100644 styles/src/types/extract_syntax_types.ts delete mode 100644 styles/src/types/syntax.ts diff --git a/crates/zed/src/languages/bash/highlights.scm b/crates/zed/src/languages/bash/highlights.scm index f3e0c9529a1d7c19777e40c28f934c0b57e10941..a72c5468edd911b60b31c8ae07041c3f733f3497 100644 --- a/crates/zed/src/languages/bash/highlights.scm +++ b/crates/zed/src/languages/bash/highlights.scm @@ -54,5 +54,5 @@ ( (command (_) @constant) - (.match? @constant "^-") + (#match? @constant "^-") ) diff --git a/crates/zed/src/languages/c/highlights.scm b/crates/zed/src/languages/c/highlights.scm index 5245e53a052578a62f8d4cddab8141bb0d80d288..064ec61a378beb00417e6b6716a6f1358daa5cbf 100644 --- a/crates/zed/src/languages/c/highlights.scm +++ b/crates/zed/src/languages/c/highlights.scm @@ -86,7 +86,7 @@ (identifier) @variable ((identifier) @constant - (.match? @constant "^_*[A-Z][A-Z\\d_]*$")) + (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) (call_expression function: (identifier) @function) @@ -106,3 +106,4 @@ (primitive_type) (sized_type_specifier) ] @type + diff --git a/crates/zed/src/languages/c/injections.scm b/crates/zed/src/languages/c/injections.scm index fbc7d83f8211836067a08cf05fae1b7b66170d12..845a63bd1bd4e700df0fd1eb3c5d10d31e2ab0e4 100644 --- a/crates/zed/src/languages/c/injections.scm +++ b/crates/zed/src/languages/c/injections.scm @@ -1,7 +1,7 @@ (preproc_def value: (preproc_arg) @content - (.set! "language" "c")) + (#set! "language" "c")) (preproc_function_def value: (preproc_arg) @content - (.set! "language" "c")) + (#set! "language" "c")) \ No newline at end of file diff --git a/crates/zed/src/languages/cpp/highlights.scm b/crates/zed/src/languages/cpp/highlights.scm index a040b1d053cd714a5576c8a6d9f13304c6c1392c..bcfa01ca5c6aca231d444026af94c7f6c6b32f51 100644 --- a/crates/zed/src/languages/cpp/highlights.scm +++ b/crates/zed/src/languages/cpp/highlights.scm @@ -31,13 +31,13 @@ declarator: (field_identifier) @function) ((namespace_identifier) @type - (.match? @type "^[A-Z]")) + (#match? @type "^[A-Z]")) (auto) @type (type_identifier) @type ((identifier) @constant - (.match? @constant "^_*[A-Z][A-Z\\d_]*$")) + (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) (field_identifier) @property (statement_identifier) @label diff --git a/crates/zed/src/languages/cpp/injections.scm b/crates/zed/src/languages/cpp/injections.scm index 3c94ba4061f6942fd88c7b09279b4f40a1709d14..eca372d577be30c352a2b7f7d93505a3b869e293 100644 --- a/crates/zed/src/languages/cpp/injections.scm +++ b/crates/zed/src/languages/cpp/injections.scm @@ -1,7 +1,7 @@ (preproc_def value: (preproc_arg) @content - (.set! "language" "c++")) + (#set! "language" "c++")) (preproc_function_def value: (preproc_arg) @content - (.set! "language" "c++")) + (#set! "language" "c++")) \ No newline at end of file diff --git a/crates/zed/src/languages/css/highlights.scm b/crates/zed/src/languages/css/highlights.scm index 83f99861c59e19b9e60335f2f4cc10231d00e31b..e271d8583c661b62f1a0bf5f4c848ca34cdbdc9d 100644 --- a/crates/zed/src/languages/css/highlights.scm +++ b/crates/zed/src/languages/css/highlights.scm @@ -46,7 +46,7 @@ (property_name) (plain_value) ] @variable.special - (.match? @variable.special "^--") + (#match? @variable.special "^--") ) [ diff --git a/crates/zed/src/languages/elixir/embedding.scm b/crates/zed/src/languages/elixir/embedding.scm index 3c523c248767dff3b855f9c623e66e5b3e03a4ae..16ad20746d4b0c8697ff126fcc5150636cb8b794 100644 --- a/crates/zed/src/languages/elixir/embedding.scm +++ b/crates/zed/src/languages/elixir/embedding.scm @@ -3,7 +3,7 @@ operator: "@" operand: (call target: (identifier) @unary - (.match? @unary "^(doc)$")) + (#match? @unary "^(doc)$")) ) @context . (call @@ -18,10 +18,10 @@ target: (identifier) @name) operator: "when") ]) - (.match? @name "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item + (#match? @name "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item ) (call target: (identifier) @name (arguments (alias) @name) - (.match? @name "^(defmodule|defprotocol)$")) @item + (#match? @name "^(defmodule|defprotocol)$")) @item diff --git a/crates/zed/src/languages/elixir/highlights.scm b/crates/zed/src/languages/elixir/highlights.scm index a8fd7eb45a6c04de64f1c7aa00fbeeecb535a316..0e779d195c5e6e03404c783d9675fc223232c84d 100644 --- a/crates/zed/src/languages/elixir/highlights.scm +++ b/crates/zed/src/languages/elixir/highlights.scm @@ -54,13 +54,13 @@ (sigil_name) @__name__ quoted_start: _ @string quoted_end: _ @string - (.match? @__name__ "^[sS]$")) @string + (#match? @__name__ "^[sS]$")) @string (sigil (sigil_name) @__name__ quoted_start: _ @string.regex quoted_end: _ @string.regex - (.match? @__name__ "^[rR]$")) @string.regex + (#match? @__name__ "^[rR]$")) @string.regex (sigil (sigil_name) @__name__ @@ -69,7 +69,7 @@ ( (identifier) @comment.unused - (.match? @comment.unused "^_") + (#match? @comment.unused "^_") ) (call @@ -91,7 +91,7 @@ operator: "|>" right: (identifier)) ]) - (.match? @keyword "^(def|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp|defp)$")) + (#match? @keyword "^(def|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp|defp)$")) (binary_operator operator: "|>" @@ -99,15 +99,15 @@ (call target: (identifier) @keyword - (.match? @keyword "^(def|defdelegate|defexception|defguard|defguardp|defimpl|defmacro|defmacrop|defmodule|defn|defnp|defoverridable|defp|defprotocol|defstruct)$")) + (#match? @keyword "^(def|defdelegate|defexception|defguard|defguardp|defimpl|defmacro|defmacrop|defmodule|defn|defnp|defoverridable|defp|defprotocol|defstruct)$")) (call target: (identifier) @keyword - (.match? @keyword "^(alias|case|cond|else|for|if|import|quote|raise|receive|require|reraise|super|throw|try|unless|unquote|unquote_splicing|use|with)$")) + (#match? @keyword "^(alias|case|cond|else|for|if|import|quote|raise|receive|require|reraise|super|throw|try|unless|unquote|unquote_splicing|use|with)$")) ( (identifier) @constant.builtin - (.match? @constant.builtin "^(__MODULE__|__DIR__|__ENV__|__CALLER__|__STACKTRACE__)$") + (#match? @constant.builtin "^(__MODULE__|__DIR__|__ENV__|__CALLER__|__STACKTRACE__)$") ) (unary_operator @@ -121,7 +121,7 @@ (sigil) (boolean) ] @comment.doc)) - (.match? @__attribute__ "^(moduledoc|typedoc|doc)$")) + (#match? @__attribute__ "^(moduledoc|typedoc|doc)$")) (comment) @comment @@ -150,4 +150,4 @@ ((sigil (sigil_name) @_sigil_name (quoted_content) @embedded) - (.eq? @_sigil_name "H")) + (#eq? @_sigil_name "H")) diff --git a/crates/zed/src/languages/elixir/injections.scm b/crates/zed/src/languages/elixir/injections.scm index 5d445a7b820ed480a9545c638ba6e685be7c244a..4de229f1046ca39264ffb23dc98e565bfd74185b 100644 --- a/crates/zed/src/languages/elixir/injections.scm +++ b/crates/zed/src/languages/elixir/injections.scm @@ -3,5 +3,5 @@ ((sigil (sigil_name) @_sigil_name (quoted_content) @content) - (.eq? @_sigil_name "H") - (.set! language "heex")) + (#eq? @_sigil_name "H") + (#set! language "heex")) diff --git a/crates/zed/src/languages/elixir/outline.scm b/crates/zed/src/languages/elixir/outline.scm index 756d39651039c002ef79ec818ba63aee20523c20..a3311fb6d4640aa4ff5469c638022c1fde02e912 100644 --- a/crates/zed/src/languages/elixir/outline.scm +++ b/crates/zed/src/languages/elixir/outline.scm @@ -1,7 +1,7 @@ (call target: (identifier) @context (arguments (alias) @name) - (.match? @context "^(defmodule|defprotocol)$")) @item + (#match? @context "^(defmodule|defprotocol)$")) @item (call target: (identifier) @context @@ -23,4 +23,4 @@ ")" @context.extra)) operator: "when") ]) - (.match? @context "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item + (#match? @context "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item diff --git a/crates/zed/src/languages/elm/injections.scm b/crates/zed/src/languages/elm/injections.scm index 3456f59a04af62c95fc26c7cec085123eb8b567d..0567320675a89c6649a191fdef950c6670d65707 100644 --- a/crates/zed/src/languages/elm/injections.scm +++ b/crates/zed/src/languages/elm/injections.scm @@ -1,2 +1,2 @@ ((glsl_content) @content - (.set! "language" "glsl")) + (#set! "language" "glsl")) diff --git a/crates/zed/src/languages/erb/injections.scm b/crates/zed/src/languages/erb/injections.scm index d9801015b7ca1f41f94b8be516f79b4c3c9365f6..7a69a818ef31d7fa3822466209b08c15280c6f5b 100644 --- a/crates/zed/src/languages/erb/injections.scm +++ b/crates/zed/src/languages/erb/injections.scm @@ -1,7 +1,7 @@ ((code) @content - (.set! "language" "ruby") - (.set! "combined")) + (#set! "language" "ruby") + (#set! "combined")) ((content) @content - (.set! "language" "html") - (.set! "combined")) + (#set! "language" "html") + (#set! "combined")) diff --git a/crates/zed/src/languages/glsl/highlights.scm b/crates/zed/src/languages/glsl/highlights.scm index 2378b8449b594d883ba19a0e5515369f5725522f..e4503c6fbba298afb1f2eddb82ce960af74b03c0 100644 --- a/crates/zed/src/languages/glsl/highlights.scm +++ b/crates/zed/src/languages/glsl/highlights.scm @@ -74,7 +74,7 @@ (sized_type_specifier) @type ((identifier) @constant - (.match? @constant "^[A-Z][A-Z\\d_]*$")) + (#match? @constant "^[A-Z][A-Z\\d_]*$")) (identifier) @variable @@ -114,5 +114,5 @@ ( (identifier) @variable.builtin - (.match? @variable.builtin "^gl_") + (#match? @variable.builtin "^gl_") ) diff --git a/crates/zed/src/languages/heex/injections.scm b/crates/zed/src/languages/heex/injections.scm index 1b63005cbfa02189e19a6a202c5beea0112c0946..b503bcb28dc10911b9e57e74f7217a21ece549fb 100644 --- a/crates/zed/src/languages/heex/injections.scm +++ b/crates/zed/src/languages/heex/injections.scm @@ -5,9 +5,9 @@ (expression_value) (ending_expression_value) ] @content) - (.set! language "elixir") - (.set! combined) + (#set! language "elixir") + (#set! combined) ) ((expression (expression_value) @content) - (.set! language "elixir")) + (#set! language "elixir")) diff --git a/crates/zed/src/languages/html/injections.scm b/crates/zed/src/languages/html/injections.scm index 7d2ed0a225e7555c6f12a9b902863a2e9e2e0939..9084e373f217b95cf70bad9cc907d5d9cd127391 100644 --- a/crates/zed/src/languages/html/injections.scm +++ b/crates/zed/src/languages/html/injections.scm @@ -1,7 +1,7 @@ (script_element (raw_text) @content - (.set! "language" "javascript")) + (#set! "language" "javascript")) (style_element (raw_text) @content - (.set! "language" "css")) + (#set! "language" "css")) diff --git a/crates/zed/src/languages/javascript/highlights.scm b/crates/zed/src/languages/javascript/highlights.scm index 7761bbb3a2dbdf0a66536f233be1df85c0724a11..36ab21ca1ec854566ad716a13f5ab5725fa1acc9 100644 --- a/crates/zed/src/languages/javascript/highlights.scm +++ b/crates/zed/src/languages/javascript/highlights.scm @@ -44,7 +44,7 @@ ; Special identifiers ((identifier) @type - (.match? @type "^[A-Z]")) + (#match? @type "^[A-Z]")) (type_identifier) @type (predefined_type) @type.builtin @@ -53,7 +53,7 @@ (shorthand_property_identifier) (shorthand_property_identifier_pattern) ] @constant -(.match? @constant "^_*[A-Z_][A-Z\\d_]*$")) + (#match? @constant "^_*[A-Z_][A-Z\\d_]*$")) ; Literals @@ -214,4 +214,4 @@ "type" "readonly" "override" -] @keyword +] @keyword \ No newline at end of file diff --git a/crates/zed/src/languages/lua/highlights.scm b/crates/zed/src/languages/lua/highlights.scm index e00d0b9557c86bb6a6d395a727dae2a1f2593210..f061bbf8f91651605a7bcf946dcb576a82045aa6 100644 --- a/crates/zed/src/languages/lua/highlights.scm +++ b/crates/zed/src/languages/lua/highlights.scm @@ -127,7 +127,7 @@ (identifier) @variable ((identifier) @variable.special - (.eq? @variable.special "self")) + (#eq? @variable.special "self")) (variable_list attribute: (attribute @@ -137,7 +137,7 @@ ;; Constants ((identifier) @constant - (.match? @constant "^[A-Z][A-Z_0-9]*$")) + (#match? @constant "^[A-Z][A-Z_0-9]*$")) (vararg_expression) @constant @@ -158,7 +158,7 @@ [ "{" "}" -] @method.constructor) +] @constructor) ;; Functions @@ -180,7 +180,7 @@ (function_call (identifier) @function.builtin - (.any-of? @function.builtin + (#any-of? @function.builtin ;; built-in functions in Lua 5.1 "assert" "collectgarbage" "dofile" "error" "getfenv" "getmetatable" "ipairs" "load" "loadfile" "loadstring" "module" "next" "pairs" "pcall" "print" @@ -195,4 +195,4 @@ (number) @number -(string) @string +(string) @string \ No newline at end of file diff --git a/crates/zed/src/languages/php/highlights.scm b/crates/zed/src/languages/php/highlights.scm index fb85d997fad6585066ac621253fe9694467e8517..fcb087c47d14dbc036ed79a50be7ff1b57ebc4e8 100644 --- a/crates/zed/src/languages/php/highlights.scm +++ b/crates/zed/src/languages/php/highlights.scm @@ -43,15 +43,15 @@ (relative_scope) @variable.builtin ((name) @constant - (.match? @constant "^_?[A-Z][A-Z\\d_]+$")) + (#match? @constant "^_?[A-Z][A-Z\\d_]+$")) ((name) @constant.builtin - (.match? @constant.builtin "^__[A-Z][A-Z\d_]+__$")) + (#match? @constant.builtin "^__[A-Z][A-Z\d_]+__$")) -((name) @method.constructor -(.match? @method.constructor "^[A-Z]")) +((name) @constructor + (#match? @constructor "^[A-Z]")) ((name) @variable.builtin - (.eq? @variable.builtin "this")) + (#eq? @variable.builtin "this")) (variable_name) @variable diff --git a/crates/zed/src/languages/php/injections.scm b/crates/zed/src/languages/php/injections.scm index 725729337b240a9e58b1e392ab645809d235314e..57abd8ea2b0576e7b936788b4a9880bc57fea798 100644 --- a/crates/zed/src/languages/php/injections.scm +++ b/crates/zed/src/languages/php/injections.scm @@ -1,3 +1,3 @@ ((text) @content - (.set! "language" "html") - (.set! "combined")) + (#set! "language" "html") + (#set! "combined")) diff --git a/crates/zed/src/languages/python/highlights.scm b/crates/zed/src/languages/python/highlights.scm index b31bddaeb501158c8bf6370ca0de37a1d73b7a6a..71ab963d82664db4dd9a66b9e9ac0e85449caf57 100644 --- a/crates/zed/src/languages/python/highlights.scm +++ b/crates/zed/src/languages/python/highlights.scm @@ -18,16 +18,16 @@ ; Identifier naming conventions ((identifier) @type - (.match? @type "^[A-Z]")) + (#match? @type "^[A-Z]")) ((identifier) @constant - (.match? @constant "^_*[A-Z][A-Z\\d_]*$")) + (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) ; Builtin functions ((call function: (identifier) @function.builtin) - (.match? + (#match? @function.builtin "^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__)$")) @@ -122,4 +122,4 @@ "yield" "match" "case" -] @keyword +] @keyword \ No newline at end of file diff --git a/crates/zed/src/languages/racket/highlights.scm b/crates/zed/src/languages/racket/highlights.scm index 304b10a018b23eebcea9248d33e0f43edd50ea29..2c0caf89357cfbe8f966bffbbc712272b3c1e59d 100644 --- a/crates/zed/src/languages/racket/highlights.scm +++ b/crates/zed/src/languages/racket/highlights.scm @@ -22,7 +22,7 @@ (lang_name) @variable.special ((symbol) @operator - (.match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$")) + (#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$")) (list . @@ -31,9 +31,10 @@ (list . (symbol) @keyword - (.match? @keyword + (#match? @keyword "^(unit-from-context|for/last|syntax-case|match-let\\*-values|define-for-syntax|define/subexpression-pos-prop|set-field!|class-field-accessor|invoke-unit|#%stratified-body|for\\*/and|for\\*/weak-set|flat-rec-contract|for\\*/stream|planet|for/mutable-seteqv|log-error|delay|#%declare|prop:dict/contract|->d|lib|override\\*|define-local-member-name|send-generic|for\\*/hasheq|define-syntax|submod|except|include-at/relative-to/reader|public\\*|define-member-name|define/public|let\\*|for/and|for\\*/first|for|delay/strict|define-values-for-export|==|match-define-values|for/weak-seteq|for\\*/async|for/stream|for/weak-seteqv|set!-values|lambda|for\\*/product|augment-final\\*|pubment\\*|command-line|contract|case|struct-field-index|contract-struct|unless|for/hasheq|for/seteqv|with-method|define-values-for-syntax|for-template|pubment|for\\*/list|syntax-case\\*|init-field|define-serializable-class|=>|for/foldr/derived|letrec-syntaxes|overment\\*|unquote-splicing|_|inherit-field|for\\*|stream-lazy|match-lambda\\*|contract-pos/neg-doubling|unit/c|match-define|for\\*/set|unit/s|nor|#%expression|class/c|this%|place/context|super-make-object|when|set!|parametric->/c|syntax-id-rules|include/reader|compound-unit|override-final|get-field|gen:dict|for\\*/seteqv|for\\*/hash|#%provide|combine-out|link|with-contract-continuation-mark|define-struct/derived|stream\\*|λ|rename-out|define-serializable-class\\*|augment|define/augment|let|define-signature-form|letrec-syntax|abstract|define-namespace-anchor|#%module-begin|#%top-interaction|for\\*/weak-seteqv|do|define/subexpression-pos-prop/name|absent|send/apply|with-handlers\\*|all-from-out|provide-signature-elements|gen:stream|define/override-final|for\\*/mutable-seteqv|rename|quasisyntax/loc|instantiate|for/list|extends|include-at/relative-to|mixin|define/pubment|#%plain-lambda|except-out|#%plain-module-begin|init|for\\*/last|relative-in|define-unit/new-import-export|->dm|member-name-key|nand|interface\\*|struct|define/override|else|define/augment-final|failure-cont|open|log-info|define/final-prop|all-defined-out|for/sum|for\\*/sum|recursive-contract|define|define-logger|match\\*|log-debug|rename-inner|->|struct/derived|unit|class\\*|prefix-out|any|define/overment|define-signature|match-letrec-values|let-syntaxes|for/mutable-set|define/match|cond|super-instantiate|define-contract-struct|import|hash/dc|define-custom-set-types|public-final|for/vector|for-label|prefix-in|for\\*/foldr/derived|define-unit-binding|object-contract|syntax-rules|augride|for\\*/mutable-seteq|quasisyntax|inner|for-syntax|overment|send/keyword-apply|generic|let\\*-values|->m|define-values|struct-copy|init-depend|struct/ctc|match-lambda|#%printing-module-begin|match\\*/derived|case->m|this|file|stream-cons|inspect|field|for/weak-set|struct\\*|gen:custom-write|thunk\\*|combine-in|unquote|for/lists|define/private|for\\*/foldr|define-unit/s|with-continuation-mark|begin|prefix|quote-syntax/prune|object/c|interface|match/derived|for/hasheqv|current-contract-region|define-compound-unit|override|define/public-final|recontract-out|let/cc|augride\\*|inherit|send|define-values/invoke-unit|for/mutable-seteq|#%datum|for/first|match-let\\*|invoke-unit/infer|define/contract|syntax/loc|for\\*/hasheqv|define-sequence-syntax|let/ec|for/product|for\\*/fold/derived|define-syntax-rule|lazy|unconstrained-domain->|augment-final|private|class|define-splicing-for-clause-syntax|for\\*/fold|prompt-tag/c|contract-out|match/values|public-final\\*|case-lambda|for/fold|unsyntax|for/set|begin0|#%require|time|public|define-struct|include|define-values/invoke-unit/infer|only-space-in|struct/c|only-meta-in|unit/new-import-export|place|begin-for-syntax|shared|inherit/super|quote|for/or|struct/contract|export|inherit/inner|struct-out|let-syntax|augment\\*|for\\*/vector|rename-in|match-let|define-unit|:do-in|~@|for\\*/weak-seteq|private\\*|and|except-in|log-fatal|gen:equal\\+hash|provide|require|thunk|invariant-assertion|define-match-expander|init-rest|->\\*|class/derived|super-new|for/fold/derived|for\\*/mutable-set|match-lambda\\*\\*|only|with-contract|~\\?|opt/c|let-values|delay/thread|->i|for/foldr|for-meta|only-in|send\\+|\\.\\.\\.|struct-guard/c|->\\*m|gen:set|struct/dc|define-syntaxes|if|parameterize|module\\*|module|send\\*|#%variable-reference|compound-unit/infer|#%plain-app|for/hash|contracted|case->|match|for\\*/lists|#%app|letrec-values|log-warning|super|define/augride|local-require|provide/contract|define-struct/contract|match-let-values|quote-syntax|for\\*/seteq|define-compound-unit/infer|parameterize\\*|values/drop|for/seteq|tag|stream|delay/idle|module\\+|define-custom-hash-types|cons/dc|define-module-boundary-contract|or|protect-out|define-opt/c|implies|letrec-syntaxes\\+values|for\\*/or|unsyntax-splicing|override-final\\*|for/async|parameterize-break|syntax|place\\*|for-space|quasiquote|with-handlers|delay/sync|define-unit-from-context|match-letrec|#%top|define-unit/contract|delay/name|new|field-bound\\?|letrec|class-field-mutator|with-syntax|flat-murec-contract|rename-super|local)$" )) ((symbol) @comment - (.match? @comment "^#[cC][iIsS]$")) + (#match? @comment "^#[cC][iIsS]$")) + diff --git a/crates/zed/src/languages/racket/outline.scm b/crates/zed/src/languages/racket/outline.scm index 188067078de2676ebaeaba90fe98d508dc7d19e0..604e052a63f71badbe98ec1debc96a519dc49256 100644 --- a/crates/zed/src/languages/racket/outline.scm +++ b/crates/zed/src/languages/racket/outline.scm @@ -6,5 +6,5 @@ (symbol) @name (list . (symbol) @name) ] - (.match? @start-symbol "^define") -) @item + (#match? @start-symbol "^define") +) @item \ No newline at end of file diff --git a/crates/zed/src/languages/ruby/brackets.scm b/crates/zed/src/languages/ruby/brackets.scm index f5129f8f310ce4b533c29c5e3fdb465844e5e68e..957b20ecdb4524920ba30b9d202d94d101215ed5 100644 --- a/crates/zed/src/languages/ruby/brackets.scm +++ b/crates/zed/src/languages/ruby/brackets.scm @@ -11,4 +11,4 @@ (begin "begin" @open "end" @close) (module "module" @open "end" @close) (_ . "def" @open "end" @close) -(_ . "class" @open "end" @close) +(_ . "class" @open "end" @close) \ No newline at end of file diff --git a/crates/zed/src/languages/ruby/highlights.scm b/crates/zed/src/languages/ruby/highlights.scm index 93cf2608f4ee7829c55718c42075b6cb986805a1..2610cfa1ccf07254c68c87d2e8013741d7d6969f 100644 --- a/crates/zed/src/languages/ruby/highlights.scm +++ b/crates/zed/src/languages/ruby/highlights.scm @@ -33,12 +33,12 @@ (identifier) @variable ((identifier) @keyword - (.match? @keyword "^(private|protected|public)$")) + (#match? @keyword "^(private|protected|public)$")) ; Function calls ((identifier) @function.method.builtin - (.eq? @function.method.builtin "require")) + (#eq? @function.method.builtin "require")) "defined?" @function.method.builtin @@ -60,7 +60,7 @@ ] @property ((identifier) @constant.builtin - (.match? @constant.builtin "^__(FILE|LINE|ENCODING)__$")) + (#match? @constant.builtin "^__(FILE|LINE|ENCODING)__$")) (file) @constant.builtin (line) @constant.builtin @@ -71,7 +71,7 @@ ) @constant.builtin ((constant) @constant - (.match? @constant "^[A-Z\\d_]+$")) + (#match? @constant "^[A-Z\\d_]+$")) (constant) @type diff --git a/crates/zed/src/languages/rust/highlights.scm b/crates/zed/src/languages/rust/highlights.scm index 54dbfa00bd3195efadc965d3dca490d8c00b74bd..7240173a89260b22a9508a9984e40dc8b1ab7410 100644 --- a/crates/zed/src/languages/rust/highlights.scm +++ b/crates/zed/src/languages/rust/highlights.scm @@ -38,11 +38,11 @@ ; Assume uppercase names are types/enum-constructors ((identifier) @type - (.match? @type "^[A-Z]")) + (#match? @type "^[A-Z]")) ; Assume all-caps names are constants ((identifier) @constant - (.match? @constant "^_*[A-Z][A-Z\\d_]*$")) + (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) [ "(" diff --git a/crates/zed/src/languages/rust/injections.scm b/crates/zed/src/languages/rust/injections.scm index 78fde3752fd9722e33daf4ad747b4e557044d353..57ebea8539345c72145eaa44cffb09845f913406 100644 --- a/crates/zed/src/languages/rust/injections.scm +++ b/crates/zed/src/languages/rust/injections.scm @@ -1,7 +1,7 @@ (macro_invocation (token_tree) @content - (.set! "language" "rust")) + (#set! "language" "rust")) (macro_rule (token_tree) @content - (.set! "language" "rust")) + (#set! "language" "rust")) \ No newline at end of file diff --git a/crates/zed/src/languages/scheme/highlights.scm b/crates/zed/src/languages/scheme/highlights.scm index 201b0e9276870afeb4f3ed7eb68de302af929b33..40ba61cd055948195023e2aa25db6f032acd674e 100644 --- a/crates/zed/src/languages/scheme/highlights.scm +++ b/crates/zed/src/languages/scheme/highlights.scm @@ -14,7 +14,7 @@ (directive)] @comment ((symbol) @operator - (.match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$")) + (#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$")) (list . @@ -23,6 +23,6 @@ (list . (symbol) @keyword - (.match? @keyword + (#match? @keyword "^(define-syntax|let\\*|lambda|λ|case|=>|quote-splicing|unquote-splicing|set!|let|letrec|letrec-syntax|let-values|let\\*-values|do|else|define|cond|syntax-rules|unquote|begin|quote|let-syntax|and|if|quasiquote|letrec|delay|or|when|unless|identifier-syntax|assert|library|export|import|rename|only|except|prefix)$" )) diff --git a/crates/zed/src/languages/scheme/outline.scm b/crates/zed/src/languages/scheme/outline.scm index 188067078de2676ebaeaba90fe98d508dc7d19e0..604e052a63f71badbe98ec1debc96a519dc49256 100644 --- a/crates/zed/src/languages/scheme/outline.scm +++ b/crates/zed/src/languages/scheme/outline.scm @@ -6,5 +6,5 @@ (symbol) @name (list . (symbol) @name) ] - (.match? @start-symbol "^define") -) @item + (#match? @start-symbol "^define") +) @item \ No newline at end of file diff --git a/crates/zed/src/languages/svelte/injections.scm b/crates/zed/src/languages/svelte/injections.scm index 17719b325c0c3632e1f6d9bbf7cd131ed9362dcb..8c1ac9fcd0bb16cf59e792487985ac64d6a43f88 100755 --- a/crates/zed/src/languages/svelte/injections.scm +++ b/crates/zed/src/languages/svelte/injections.scm @@ -2,27 +2,27 @@ ; -------------- (script_element (raw_text) @content - (.set! "language" "javascript")) + (#set! "language" "javascript")) ((script_element (start_tag (attribute (quoted_attribute_value (attribute_value) @_language))) (raw_text) @content) - (.eq? @_language "ts") - (.set! "language" "typescript")) + (#eq? @_language "ts") + (#set! "language" "typescript")) ((script_element (start_tag (attribute (quoted_attribute_value (attribute_value) @_language))) (raw_text) @content) - (.eq? @_language "typescript") - (.set! "language" "typescript")) + (#eq? @_language "typescript") + (#set! "language" "typescript")) (style_element (raw_text) @content - (.set! "language" "css")) + (#set! "language" "css")) ((raw_text_expr) @content - (.set! "language" "javascript")) + (#set! "language" "javascript")) diff --git a/crates/zed/src/languages/typescript/highlights.scm b/crates/zed/src/languages/typescript/highlights.scm index 9272108670ac2729dd39f4b54f90b81eeb3218a4..bf086ea156f6ee9c2aca6bb9d2ebdd3f91997999 100644 --- a/crates/zed/src/languages/typescript/highlights.scm +++ b/crates/zed/src/languages/typescript/highlights.scm @@ -43,11 +43,11 @@ ; Special identifiers -((identifier) @method.constructor - (.match? @method.constructor "^[A-Z]")) +((identifier) @constructor + (#match? @constructor "^[A-Z]")) ((identifier) @type - (.match? @type "^[A-Z]")) + (#match? @type "^[A-Z]")) (type_identifier) @type (predefined_type) @type.builtin @@ -56,7 +56,7 @@ (shorthand_property_identifier) (shorthand_property_identifier_pattern) ] @constant -(.match? @constant "^_*[A-Z_][A-Z\\d_]*$")) + (#match? @constant "^_*[A-Z_][A-Z\\d_]*$")) ; Literals @@ -218,4 +218,4 @@ "type" "readonly" "override" -] @keyword +] @keyword \ No newline at end of file diff --git a/styles/package.json b/styles/package.json index 3a50ac537166bcde6c30b0bc822481a823cfc8a2..16e95d90d5bebb18e7cfffe88e8d0098b48eb00f 100644 --- a/styles/package.json +++ b/styles/package.json @@ -8,7 +8,6 @@ "build-licenses": "ts-node ./src/build_licenses.ts", "build-tokens": "ts-node ./src/build_tokens.ts", "build-types": "ts-node ./src/build_types.ts", - "generate-syntax": "ts-node ./src/types/extract_syntax_types.ts", "test": "vitest" }, "author": "Zed Industries (https://github.com/zed-industries/)", diff --git a/styles/src/build_themes.ts b/styles/src/build_themes.ts index 4d262f8146ed907035e384dbefd28c0b838a467a..17575663a1f88b17870b1b146b47e7086bf3e2ba 100644 --- a/styles/src/build_themes.ts +++ b/styles/src/build_themes.ts @@ -21,7 +21,9 @@ function clear_themes(theme_directory: string) { } } -const all_themes: Theme[] = themes.map((theme) => create_theme(theme)) +const all_themes: Theme[] = themes.map((theme) => + create_theme(theme) +) function write_themes(themes: Theme[], output_directory: string) { clear_themes(output_directory) @@ -32,7 +34,10 @@ function write_themes(themes: Theme[], output_directory: string) { const style_tree = app() const style_tree_json = JSON.stringify(style_tree, null, 2) const temp_path = path.join(temp_directory, `${theme.name}.json`) - const out_path = path.join(output_directory, `${theme.name}.json`) + const out_path = path.join( + output_directory, + `${theme.name}.json` + ) fs.writeFileSync(temp_path, style_tree_json) fs.renameSync(temp_path, out_path) console.log(`- ${out_path} created`) diff --git a/styles/src/build_tokens.ts b/styles/src/build_tokens.ts index 3c52b6d989640a93025ac5eafe5a959b8bc83163..fd6aa18ced50af53b6bcf4c3c386d1774c7ab00d 100644 --- a/styles/src/build_tokens.ts +++ b/styles/src/build_tokens.ts @@ -83,6 +83,8 @@ function write_tokens(themes: Theme[], tokens_directory: string) { console.log(`- ${METADATA_FILE} created`) } -const all_themes: Theme[] = themes.map((theme) => create_theme(theme)) +const all_themes: Theme[] = themes.map((theme) => + create_theme(theme) +) write_tokens(all_themes, TOKENS_DIRECTORY) diff --git a/styles/src/component/icon_button.ts b/styles/src/component/icon_button.ts index 13dfce6d7762aaf2abc59f298fb6e22583435cf1..6887fc7c30e1f234fd043bb115c2658039b5f806 100644 --- a/styles/src/component/icon_button.ts +++ b/styles/src/component/icon_button.ts @@ -10,7 +10,10 @@ export type Margin = { } interface IconButtonOptions { - layer?: Theme["lowest"] | Theme["middle"] | Theme["highest"] + layer?: + | Theme["lowest"] + | Theme["middle"] + | Theme["highest"] color?: keyof Theme["lowest"] margin?: Partial } diff --git a/styles/src/component/tab_bar_button.ts b/styles/src/component/tab_bar_button.ts index 9e7f9acfc314be75850128690d8d066dde520182..0c43e7010e5469c10f959e00f4df8d177963392f 100644 --- a/styles/src/component/tab_bar_button.ts +++ b/styles/src/component/tab_bar_button.ts @@ -12,47 +12,44 @@ type TabBarButtonProps = TabBarButtonOptions & { state?: Partial>> } -export function tab_bar_button( - theme: Theme, - { icon, color = "base" }: TabBarButtonProps -) { +export function tab_bar_button(theme: Theme, { icon, color = "base" }: TabBarButtonProps) { const button_spacing = 8 - return interactive({ - base: { - icon: { - color: foreground(theme.middle, color), - asset: icon, - dimensions: { - width: 15, - height: 15, + return ( + interactive({ + base: { + icon: { + color: foreground(theme.middle, color), + asset: icon, + dimensions: { + width: 15, + height: 15, + }, }, - }, - container: { - corner_radius: 4, - padding: { - top: 4, - bottom: 4, - left: 4, - right: 4, - }, - margin: { - left: button_spacing / 2, - right: button_spacing / 2, - }, - }, - }, - state: { - hovered: { container: { - background: background(theme.middle, color, "hovered"), + corner_radius: 4, + padding: { + top: 4, bottom: 4, left: 4, right: 4 + }, + margin: { + left: button_spacing / 2, + right: button_spacing / 2, + }, }, }, - clicked: { - container: { - background: background(theme.middle, color, "pressed"), + state: { + hovered: { + container: { + background: background(theme.middle, color, "hovered"), + + } + }, + clicked: { + container: { + background: background(theme.middle, color, "pressed"), + } }, }, - }, - }) + }) + ) } diff --git a/styles/src/component/text_button.ts b/styles/src/component/text_button.ts index 68ec01c92bf1ba12907675dbd4ee87a4f51e4b9c..58b2a1cbf2ff31a8e4fc50b9e1165bca78ec6b4a 100644 --- a/styles/src/component/text_button.ts +++ b/styles/src/component/text_button.ts @@ -9,7 +9,10 @@ import { useTheme, Theme } from "../theme" import { Margin } from "./icon_button" interface TextButtonOptions { - layer?: Theme["lowest"] | Theme["middle"] | Theme["highest"] + layer?: + | Theme["lowest"] + | Theme["middle"] + | Theme["highest"] color?: keyof Theme["lowest"] margin?: Partial text_properties?: TextProperties diff --git a/styles/src/style_tree/app.ts b/styles/src/style_tree/app.ts index ee0aa133a04bd35202d381835e257ddca2b284cc..ccfdd60a981f4d5e763ce35902b0456bf0d703cd 100644 --- a/styles/src/style_tree/app.ts +++ b/styles/src/style_tree/app.ts @@ -57,6 +57,6 @@ export default function app(): any { tooltip: tooltip(), terminal: terminal(), assistant: assistant(), - feedback: feedback(), + feedback: feedback() } } diff --git a/styles/src/style_tree/assistant.ts b/styles/src/style_tree/assistant.ts index 7df5434f91010f778d47dfc9170ef80b909df0cf..cfc1f8d813648654a8fee608ea4d00dc30893b75 100644 --- a/styles/src/style_tree/assistant.ts +++ b/styles/src/style_tree/assistant.ts @@ -8,48 +8,50 @@ type RoleCycleButton = TextStyle & { } // TODO: Replace these with zed types type RemainingTokens = TextStyle & { - background: string - margin: { top: number; right: number } + background: string, + margin: { top: number, right: number }, padding: { - right: number - left: number - top: number - bottom: number - } - corner_radius: number + right: number, + left: number, + top: number, + bottom: number, + }, + corner_radius: number, } export default function assistant(): any { const theme = useTheme() - const interactive_role = ( - color: StyleSets - ): Interactive => { - return interactive({ - base: { - ...text(theme.highest, "sans", color, { size: "sm" }), - }, - state: { - hovered: { + const interactive_role = (color: StyleSets): Interactive => { + return ( + interactive({ + base: { ...text(theme.highest, "sans", color, { size: "sm" }), - background: background(theme.highest, color, "hovered"), }, - clicked: { - ...text(theme.highest, "sans", color, { size: "sm" }), - background: background(theme.highest, color, "pressed"), + state: { + hovered: { + ...text(theme.highest, "sans", color, { size: "sm" }), + background: background(theme.highest, color, "hovered"), + }, + clicked: { + ...text(theme.highest, "sans", color, { size: "sm" }), + background: background(theme.highest, color, "pressed"), + } }, - }, - }) + }) + ) } const tokens_remaining = (color: StyleSets): RemainingTokens => { - return { - ...text(theme.highest, "mono", color, { size: "xs" }), - background: background(theme.highest, "on", "default"), - margin: { top: 12, right: 20 }, - padding: { right: 4, left: 4, top: 1, bottom: 1 }, - corner_radius: 6, - } + return ( + { + ...text(theme.highest, "mono", color, { size: "xs" }), + background: background(theme.highest, "on", "default"), + margin: { top: 12, right: 20 }, + padding: { right: 4, left: 4, top: 1, bottom: 1 }, + corner_radius: 6, + } + ) } return { @@ -91,10 +93,7 @@ export default function assistant(): any { base: { background: background(theme.middle), padding: { top: 4, bottom: 4 }, - border: border(theme.middle, "default", { - top: true, - overlay: true, - }), + border: border(theme.middle, "default", { top: true, overlay: true }), }, state: { hovered: { @@ -102,7 +101,7 @@ export default function assistant(): any { }, clicked: { background: background(theme.middle, "pressed"), - }, + } }, }), saved_at: { diff --git a/styles/src/style_tree/editor.ts b/styles/src/style_tree/editor.ts index deab45d4b21df8b7d130479c277ed317ba78d8d4..9ad008f38d4dd928af5b49c46b148df575b1c6a3 100644 --- a/styles/src/style_tree/editor.ts +++ b/styles/src/style_tree/editor.ts @@ -9,9 +9,9 @@ import { } from "./components" import hover_popover from "./hover_popover" +import { build_syntax } from "../theme/syntax" import { interactive, toggleable } from "../element" import { useTheme } from "../theme" -import chroma from "chroma-js" export default function editor(): any { const theme = useTheme() @@ -48,28 +48,16 @@ export default function editor(): any { } } + const syntax = build_syntax() + return { - text_color: theme.syntax.primary.color, + text_color: syntax.primary.color, background: background(layer), active_line_background: with_opacity(background(layer, "on"), 0.75), highlighted_line_background: background(layer, "on"), // Inline autocomplete suggestions, Co-pilot suggestions, etc. - hint: chroma - .mix( - theme.ramps.neutral(0.6).hex(), - theme.ramps.blue(0.4).hex(), - 0.45, - "lch" - ) - .hex(), - suggestion: chroma - .mix( - theme.ramps.neutral(0.4).hex(), - theme.ramps.blue(0.4).hex(), - 0.45, - "lch" - ) - .hex(), + hint: syntax.hint, + suggestion: syntax.predictive, code_actions: { indicator: toggleable({ base: interactive({ @@ -267,8 +255,8 @@ export default function editor(): any { invalid_warning_diagnostic: diagnostic(theme.middle, "base"), hover_popover: hover_popover(), link_definition: { - color: theme.syntax.link_uri.color, - underline: theme.syntax.link_uri.underline, + color: syntax.link_uri.color, + underline: syntax.link_uri.underline, }, jump_icon: interactive({ base: { @@ -318,7 +306,7 @@ export default function editor(): any { ? with_opacity(theme.ramps.green(0.5).hex(), 0.8) : with_opacity(theme.ramps.green(0.4).hex(), 0.8), }, - selections: foreground(layer, "accent"), + selections: foreground(layer, "accent") }, composition_mark: { underline: { @@ -326,6 +314,6 @@ export default function editor(): any { color: border_color(layer), }, }, - syntax: theme.syntax, + syntax, } } diff --git a/styles/src/style_tree/feedback.ts b/styles/src/style_tree/feedback.ts index 0349359533041d4425df3d0c72d120ed18499a30..b1bd96e165466521804f86d547664c209c7c4671 100644 --- a/styles/src/style_tree/feedback.ts +++ b/styles/src/style_tree/feedback.ts @@ -37,7 +37,7 @@ export default function feedback(): any { ...text(theme.highest, "mono", "on", "disabled"), background: background(theme.highest, "on", "disabled"), border: border(theme.highest, "on", "disabled"), - }, + } }, }), button_margin: 8, diff --git a/styles/src/style_tree/picker.ts b/styles/src/style_tree/picker.ts index 317f600b1e2fca3f6b8756c3ba033fa22e6b0220..28ae85478794a22211dc67cb6ec56cce4bc805f1 100644 --- a/styles/src/style_tree/picker.ts +++ b/styles/src/style_tree/picker.ts @@ -152,7 +152,7 @@ export default function picker(): any { 0.5 ), }, - }, + } }), } } diff --git a/styles/src/style_tree/project_panel.ts b/styles/src/style_tree/project_panel.ts index 51958af145b50afd25510788ff0a530cc77a5a1d..e239f9a84023088d988f74e709c6485ade8a9510 100644 --- a/styles/src/style_tree/project_panel.ts +++ b/styles/src/style_tree/project_panel.ts @@ -64,17 +64,17 @@ export default function project_panel(): any { const unselected_default_style = merge( base_properties, unselected?.default ?? {}, - {} + {}, ) const unselected_hovered_style = merge( base_properties, { background: background(theme.middle, "hovered") }, - unselected?.hovered ?? {} + unselected?.hovered ?? {}, ) const unselected_clicked_style = merge( base_properties, { background: background(theme.middle, "pressed") }, - unselected?.clicked ?? {} + unselected?.clicked ?? {}, ) const selected_default_style = merge( base_properties, @@ -82,7 +82,7 @@ export default function project_panel(): any { background: background(theme.lowest), text: text(theme.lowest, "sans", { size: "sm" }), }, - selected_style?.default ?? {} + selected_style?.default ?? {}, ) const selected_hovered_style = merge( base_properties, @@ -90,7 +90,7 @@ export default function project_panel(): any { background: background(theme.lowest, "hovered"), text: text(theme.lowest, "sans", { size: "sm" }), }, - selected_style?.hovered ?? {} + selected_style?.hovered ?? {}, ) const selected_clicked_style = merge( base_properties, @@ -98,7 +98,7 @@ export default function project_panel(): any { background: background(theme.lowest, "pressed"), text: text(theme.lowest, "sans", { size: "sm" }), }, - selected_style?.clicked ?? {} + selected_style?.clicked ?? {}, ) return toggleable({ @@ -175,7 +175,7 @@ export default function project_panel(): any { default: { icon_color: foreground(theme.middle, "variant"), }, - } + }, ), cut_entry: entry( { @@ -190,7 +190,7 @@ export default function project_panel(): any { size: "sm", }), }, - } + }, ), filename_editor: { background: background(theme.middle, "on"), diff --git a/styles/src/style_tree/status_bar.ts b/styles/src/style_tree/status_bar.ts index 45baf4e87122d73779a3b5100909cfa53e3d87ed..6261939994ac4e7ae7e06090912218d5dcfb7f54 100644 --- a/styles/src/style_tree/status_bar.ts +++ b/styles/src/style_tree/status_bar.ts @@ -34,14 +34,10 @@ export default function status_bar(): any { ...text(layer, "mono", "variant", { size: "xs" }), }, active_language: text_button({ - color: "variant", - }), - auto_update_progress_message: text(layer, "sans", "variant", { - size: "xs", - }), - auto_update_done_message: text(layer, "sans", "variant", { - size: "xs", + color: "variant" }), + auto_update_progress_message: text(layer, "sans", "variant", { size: "xs" }), + auto_update_done_message: text(layer, "sans", "variant", { size: "xs" }), lsp_status: interactive({ base: { ...diagnostic_status_container, diff --git a/styles/src/style_tree/titlebar.ts b/styles/src/style_tree/titlebar.ts index fe0c53e87dac61bdfc93688eea13e74d583017a9..177a8c5bd8db0fa2290eda5e25c4160531d81e4b 100644 --- a/styles/src/style_tree/titlebar.ts +++ b/styles/src/style_tree/titlebar.ts @@ -183,10 +183,10 @@ export function titlebar(): any { project_name_divider: text(theme.lowest, "sans", "variant"), project_menu_button: toggleable_text_button(theme, { - color: "base", + color: 'base', }), git_menu_button: toggleable_text_button(theme, { - color: "variant", + color: 'variant', }), // Collaborators diff --git a/styles/src/theme/create_theme.ts b/styles/src/theme/create_theme.ts index 6df36d7077b934f2acc45f21422159872c6f551a..d2701f8341af973a3a4511c149c983cb221fa14d 100644 --- a/styles/src/theme/create_theme.ts +++ b/styles/src/theme/create_theme.ts @@ -1,28 +1,28 @@ import { Scale, Color } from "chroma-js" +import { Syntax, ThemeSyntax, SyntaxHighlightStyle } from "./syntax" +export { Syntax, ThemeSyntax, SyntaxHighlightStyle } import { ThemeConfig, ThemeAppearance, ThemeConfigInputColors, } from "./theme_config" import { get_ramps } from "./ramps" -import { syntaxStyle } from "./syntax" -import { Syntax } from "../types/syntax" export interface Theme { name: string is_light: boolean /** - * App background, other elements that should sit directly on top of the background. - */ + * App background, other elements that should sit directly on top of the background. + */ lowest: Layer /** - * Panels, tabs, other UI surfaces that sit on top of the background. - */ + * Panels, tabs, other UI surfaces that sit on top of the background. + */ middle: Layer /** - * Editors like code buffers, conversation editors, etc. - */ + * Editors like code buffers, conversation editors, etc. + */ highest: Layer ramps: RampSet @@ -31,7 +31,7 @@ export interface Theme { modal_shadow: Shadow players: Players - syntax: Syntax + syntax?: Partial } export interface Meta { @@ -115,7 +115,12 @@ export interface Style { } export function create_theme(theme: ThemeConfig): Theme { - const { name, appearance, input_color } = theme + const { + name, + appearance, + input_color, + override: { syntax }, + } = theme const is_light = appearance === ThemeAppearance.Light const color_ramps: ThemeConfigInputColors = input_color @@ -157,11 +162,6 @@ export function create_theme(theme: ThemeConfig): Theme { "7": player(ramps.yellow), } - const syntax = syntaxStyle( - ramps, - theme.override.syntax ? theme.override.syntax : {} - ) - return { name, is_light, diff --git a/styles/src/theme/syntax.ts b/styles/src/theme/syntax.ts index db8f98de663bcb3afa8e84ea851363a3f83cbd0c..540a1d0ff9822d5a8c2cf292ddba5ace6839ac6d 100644 --- a/styles/src/theme/syntax.ts +++ b/styles/src/theme/syntax.ts @@ -1,45 +1,325 @@ import deepmerge from "deepmerge" -import { font_weights, ThemeConfigInputSyntax, RampSet } from "../common" -import { Syntax, SyntaxHighlightStyle, allSyntaxKeys } from "../types/syntax" - -// Apply defaults to any missing syntax properties that are not defined manually -function apply_defaults( - ramps: RampSet, - syntax_highlights: Partial -): Syntax { - const restKeys: (keyof Syntax)[] = allSyntaxKeys.filter( - (key) => !syntax_highlights[key] - ) +import { FontWeight, font_weights, useTheme } from "../common" +import chroma from "chroma-js" - const completeSyntax: Syntax = {} as Syntax +export interface SyntaxHighlightStyle { + color?: string + weight?: FontWeight + underline?: boolean + italic?: boolean +} - const defaults: SyntaxHighlightStyle = { - color: ramps.neutral(1).hex(), - } +export interface Syntax { + // == Text Styles ====== / + comment: SyntaxHighlightStyle + // elixir: doc comment + "comment.doc": SyntaxHighlightStyle + primary: SyntaxHighlightStyle + predictive: SyntaxHighlightStyle + hint: SyntaxHighlightStyle - for (const key of restKeys) { - { - completeSyntax[key] = { - ...defaults, - } + // === Formatted Text ====== / + emphasis: SyntaxHighlightStyle + "emphasis.strong": SyntaxHighlightStyle + title: SyntaxHighlightStyle + link_uri: SyntaxHighlightStyle + link_text: SyntaxHighlightStyle + /** md: indented_code_block, fenced_code_block, code_span */ + "text.literal": SyntaxHighlightStyle + + // == Punctuation ====== / + punctuation: SyntaxHighlightStyle + /** Example: `(`, `[`, `{`...*/ + "punctuation.bracket": SyntaxHighlightStyle + /**., ;*/ + "punctuation.delimiter": SyntaxHighlightStyle + // js, ts: ${, } in a template literal + // yaml: *, &, ---, ... + "punctuation.special": SyntaxHighlightStyle + // md: list_marker_plus, list_marker_dot, etc + "punctuation.list_marker": SyntaxHighlightStyle + + // == Strings ====== / + + string: SyntaxHighlightStyle + // css: color_value + // js: this, super + // toml: offset_date_time, local_date_time... + "string.special": SyntaxHighlightStyle + // elixir: atom, quoted_atom, keyword, quoted_keyword + // ruby: simple_symbol, delimited_symbol... + "string.special.symbol"?: SyntaxHighlightStyle + // elixir, python, yaml...: escape_sequence + "string.escape"?: SyntaxHighlightStyle + // Regular expressions + "string.regex"?: SyntaxHighlightStyle + + // == Types ====== / + // We allow Function here because all JS objects literals have this property + constructor: SyntaxHighlightStyle | Function // eslint-disable-line @typescript-eslint/ban-types + variant: SyntaxHighlightStyle + type: SyntaxHighlightStyle + // js: predefined_type + "type.builtin"?: SyntaxHighlightStyle + + // == Values + variable: SyntaxHighlightStyle + // this, ... + // css: -- (var(--foo)) + // lua: self + "variable.special"?: SyntaxHighlightStyle + // c: statement_identifier, + label: SyntaxHighlightStyle + // css: tag_name, nesting_selector, universal_selector... + tag: SyntaxHighlightStyle + // css: attribute, pseudo_element_selector (tag_name), + attribute: SyntaxHighlightStyle + // css: class_name, property_name, namespace_name... + property: SyntaxHighlightStyle + // true, false, null, nullptr + constant: SyntaxHighlightStyle + // css: @media, @import, @supports... + // js: declare, implements, interface, keyof, public... + keyword: SyntaxHighlightStyle + // note: js enum is currently defined as a keyword + enum: SyntaxHighlightStyle + // -, --, ->, !=, &&, ||, <=... + operator: SyntaxHighlightStyle + number: SyntaxHighlightStyle + boolean: SyntaxHighlightStyle + // elixir: __MODULE__, __DIR__, __ENV__, etc + // go: nil, iota + "constant.builtin"?: SyntaxHighlightStyle + + // == Functions ====== / + + function: SyntaxHighlightStyle + // lua: assert, error, loadfile, tostring, unpack... + "function.builtin"?: SyntaxHighlightStyle + // go: call_expression, method_declaration + // js: call_expression, method_definition, pair (key, arrow function) + // rust: function_item name: (identifier) + "function.definition"?: SyntaxHighlightStyle + // rust: macro_definition name: (identifier) + "function.special.definition"?: SyntaxHighlightStyle + "function.method"?: SyntaxHighlightStyle + // ruby: identifier/"defined?" // Nate note: I don't fully understand this one. + "function.method.builtin"?: SyntaxHighlightStyle + + // == Unsorted ====== / + // lua: hash_bang_line + preproc: SyntaxHighlightStyle + // elixir, python: interpolation (ex: foo in ${foo}) + // js: template_substitution + embedded: SyntaxHighlightStyle +} + +export type ThemeSyntax = Partial + +const default_syntax_highlight_style: Omit = { + weight: "normal", + underline: false, + italic: false, +} + +function build_default_syntax(): Syntax { + const theme = useTheme() + + // Make a temporary object that is allowed to be missing + // the "color" property for each style + const syntax: { + [key: string]: Omit + } = {} + + // then spread the default to each style + for (const key of Object.keys({} as Syntax)) { + syntax[key as keyof Syntax] = { + ...default_syntax_highlight_style, } } - const mergedBaseSyntax = Object.assign(completeSyntax, syntax_highlights) + // Mix the neutral and blue colors to get a + // predictive color distinct from any other color in the theme + const predictive = chroma + .mix( + theme.ramps.neutral(0.4).hex(), + theme.ramps.blue(0.4).hex(), + 0.45, + "lch" + ) + .hex() + // Mix the neutral and green colors to get a + // hint color distinct from any other color in the theme + const hint = chroma + .mix( + theme.ramps.neutral(0.6).hex(), + theme.ramps.blue(0.4).hex(), + 0.45, + "lch" + ) + .hex() - return mergedBaseSyntax + const color = { + primary: theme.ramps.neutral(1).hex(), + comment: theme.ramps.neutral(0.71).hex(), + punctuation: theme.ramps.neutral(0.86).hex(), + predictive: predictive, + hint: hint, + emphasis: theme.ramps.blue(0.5).hex(), + string: theme.ramps.orange(0.5).hex(), + function: theme.ramps.yellow(0.5).hex(), + type: theme.ramps.cyan(0.5).hex(), + constructor: theme.ramps.blue(0.5).hex(), + variant: theme.ramps.blue(0.5).hex(), + property: theme.ramps.blue(0.5).hex(), + enum: theme.ramps.orange(0.5).hex(), + operator: theme.ramps.orange(0.5).hex(), + number: theme.ramps.green(0.5).hex(), + boolean: theme.ramps.green(0.5).hex(), + constant: theme.ramps.green(0.5).hex(), + keyword: theme.ramps.blue(0.5).hex(), + } + + // Then assign colors and use Syntax to enforce each style getting it's own color + const default_syntax: Syntax = { + ...syntax, + comment: { + color: color.comment, + }, + "comment.doc": { + color: color.comment, + }, + primary: { + color: color.primary, + }, + predictive: { + color: color.predictive, + italic: true, + }, + hint: { + color: color.hint, + weight: font_weights.bold, + }, + emphasis: { + color: color.emphasis, + }, + "emphasis.strong": { + color: color.emphasis, + weight: font_weights.bold, + }, + title: { + color: color.primary, + weight: font_weights.bold, + }, + link_uri: { + color: theme.ramps.green(0.5).hex(), + underline: true, + }, + link_text: { + color: theme.ramps.orange(0.5).hex(), + italic: true, + }, + "text.literal": { + color: color.string, + }, + punctuation: { + color: color.punctuation, + }, + "punctuation.bracket": { + color: color.punctuation, + }, + "punctuation.delimiter": { + color: color.punctuation, + }, + "punctuation.special": { + color: theme.ramps.neutral(0.86).hex(), + }, + "punctuation.list_marker": { + color: color.punctuation, + }, + string: { + color: color.string, + }, + "string.special": { + color: color.string, + }, + "string.special.symbol": { + color: color.string, + }, + "string.escape": { + color: color.comment, + }, + "string.regex": { + color: color.string, + }, + constructor: { + color: theme.ramps.blue(0.5).hex(), + }, + variant: { + color: theme.ramps.blue(0.5).hex(), + }, + type: { + color: color.type, + }, + variable: { + color: color.primary, + }, + label: { + color: theme.ramps.blue(0.5).hex(), + }, + tag: { + color: theme.ramps.blue(0.5).hex(), + }, + attribute: { + color: theme.ramps.blue(0.5).hex(), + }, + property: { + color: theme.ramps.blue(0.5).hex(), + }, + constant: { + color: color.constant, + }, + keyword: { + color: color.keyword, + }, + enum: { + color: color.enum, + }, + operator: { + color: color.operator, + }, + number: { + color: color.number, + }, + boolean: { + color: color.boolean, + }, + function: { + color: color.function, + }, + preproc: { + color: color.primary, + }, + embedded: { + color: color.primary, + }, + } + + return default_syntax } -// Merge the base syntax with the theme syntax overrides -// This is a deep merge, so any nested properties will be merged as well -// This allows for a theme to only override a single property of a syntax highlight style -const merge_syntax = ( - baseSyntax: Syntax, - theme_syntax_overrides: ThemeConfigInputSyntax -): Syntax => { - return deepmerge( - baseSyntax, - theme_syntax_overrides, +export function build_syntax(): Syntax { + const theme = useTheme() + + const default_syntax: Syntax = build_default_syntax() + + if (!theme.syntax) { + return default_syntax + } + + const syntax = deepmerge>( + default_syntax, + theme.syntax, { arrayMerge: (destinationArray, sourceArray) => [ ...destinationArray, @@ -47,49 +327,6 @@ const merge_syntax = ( ], } ) -} - -/** Returns a complete Syntax object of the combined styles of a theme's syntax overrides and the default syntax styles */ -export const syntaxStyle = ( - ramps: RampSet, - theme_syntax_overrides: ThemeConfigInputSyntax -): Syntax => { - const syntax_highlights: Partial = { - comment: { color: ramps.neutral(0.71).hex() }, - "comment.doc": { color: ramps.neutral(0.71).hex() }, - primary: { color: ramps.neutral(1).hex() }, - emphasis: { color: ramps.blue(0.5).hex() }, - "emphasis.strong": { - color: ramps.blue(0.5).hex(), - weight: font_weights.bold, - }, - link_uri: { color: ramps.green(0.5).hex(), underline: true }, - link_text: { color: ramps.orange(0.5).hex(), italic: true }, - "text.literal": { color: ramps.orange(0.5).hex() }, - punctuation: { color: ramps.neutral(0.86).hex() }, - "punctuation.bracket": { color: ramps.neutral(0.86).hex() }, - "punctuation.special": { color: ramps.neutral(0.86).hex() }, - "punctuation.delimiter": { color: ramps.neutral(0.86).hex() }, - "punctuation.list_marker": { color: ramps.neutral(0.86).hex() }, - string: { color: ramps.orange(0.5).hex() }, - "string.special": { color: ramps.orange(0.5).hex() }, - "string.special.symbol": { color: ramps.orange(0.5).hex() }, - "string.escape": { color: ramps.neutral(0.71).hex() }, - "string.regex": { color: ramps.orange(0.5).hex() }, - "method.constructor": { color: ramps.blue(0.5).hex() }, - type: { color: ramps.cyan(0.5).hex() }, - label: { color: ramps.blue(0.5).hex() }, - attribute: { color: ramps.blue(0.5).hex() }, - property: { color: ramps.blue(0.5).hex() }, - constant: { color: ramps.green(0.5).hex() }, - keyword: { color: ramps.blue(0.5).hex() }, - operator: { color: ramps.orange(0.5).hex() }, - number: { color: ramps.green(0.5).hex() }, - boolean: { color: ramps.green(0.5).hex() }, - function: { color: ramps.yellow(0.5).hex() }, - } - const baseSyntax = apply_defaults(ramps, syntax_highlights) - const mergedSyntax = merge_syntax(baseSyntax, theme_syntax_overrides) - return mergedSyntax + return syntax } diff --git a/styles/src/theme/theme_config.ts b/styles/src/theme/theme_config.ts index f5f83590743278508ba16b7245c2e7fc8e4d2650..bc8f07425f9e676a27d36ec929ea9a116006c694 100644 --- a/styles/src/theme/theme_config.ts +++ b/styles/src/theme/theme_config.ts @@ -1,5 +1,5 @@ import { Scale, Color } from "chroma-js" -import { SyntaxHighlightStyle, SyntaxProperty } from "../types/syntax" +import { Syntax } from "./syntax" interface ThemeMeta { /** The name of the theme */ @@ -55,9 +55,7 @@ export type ThemeConfigInputColorsKeys = keyof ThemeConfigInputColors * } * ``` */ -export type ThemeConfigInputSyntax = Partial< - Record> -> +export type ThemeConfigInputSyntax = Partial interface ThemeConfigOverrides { syntax: ThemeConfigInputSyntax diff --git a/styles/src/theme/tokens/theme.ts b/styles/src/theme/tokens/theme.ts index d93079366961a1079df0858ceef980a0b9b59aec..f759bc813910416d88a2097134dc95654d6ab3b3 100644 --- a/styles/src/theme/tokens/theme.ts +++ b/styles/src/theme/tokens/theme.ts @@ -4,13 +4,17 @@ import { SingleOtherToken, TokenTypes, } from "@tokens-studio/types" -import { Shadow } from "../create_theme" +import { + Shadow, + SyntaxHighlightStyle, + ThemeSyntax, +} from "../create_theme" import { LayerToken, layer_token } from "./layer" import { PlayersToken, players_token } from "./players" import { color_token } from "./token" +import { Syntax } from "../syntax" import editor from "../../style_tree/editor" import { useTheme } from "../../../src/common" -import { Syntax, SyntaxHighlightStyle } from "../../types/syntax" interface ThemeTokens { name: SingleOtherToken @@ -47,7 +51,7 @@ const modal_shadow_token = (): SingleBoxShadowToken => { return create_shadow_token(shadow, "modal_shadow") } -type ThemeSyntaxColorTokens = Record +type ThemeSyntaxColorTokens = Record function syntax_highlight_style_color_tokens( syntax: Syntax diff --git a/styles/src/themes/atelier/common.ts b/styles/src/themes/atelier/common.ts index 9a0029581c565b0eb820e7bc8686f62e5e3627b2..b76ccc5b607a2f149a35114a519ddaaf2d1b254d 100644 --- a/styles/src/themes/atelier/common.ts +++ b/styles/src/themes/atelier/common.ts @@ -1,8 +1,4 @@ -import { - ThemeLicenseType, - ThemeFamilyMeta, - ThemeConfigInputSyntax, -} from "../../common" +import { ThemeLicenseType, ThemeSyntax, ThemeFamilyMeta } from "../../common" export interface Variant { colors: { @@ -33,7 +29,7 @@ export const meta: ThemeFamilyMeta = { "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/", } -export const build_syntax = (variant: Variant): ThemeConfigInputSyntax => { +export const build_syntax = (variant: Variant): ThemeSyntax => { const { colors } = variant return { primary: { color: colors.base06 }, @@ -54,6 +50,7 @@ export const build_syntax = (variant: Variant): ThemeConfigInputSyntax => { property: { color: colors.base08 }, variable: { color: colors.base06 }, "variable.special": { color: colors.base0E }, + variant: { color: colors.base0A }, keyword: { color: colors.base0E }, } } diff --git a/styles/src/themes/ayu/common.ts b/styles/src/themes/ayu/common.ts index 870445588646b57f347fe9e90e07b286b3b73790..2bd0bbf259aef2d9fc6c084f1da3c72379927026 100644 --- a/styles/src/themes/ayu/common.ts +++ b/styles/src/themes/ayu/common.ts @@ -3,8 +3,8 @@ import { chroma, color_ramp, ThemeLicenseType, + ThemeSyntax, ThemeFamilyMeta, - ThemeConfigInputSyntax, } from "../../common" export const ayu = { @@ -27,7 +27,7 @@ export const build_theme = (t: typeof dark, light: boolean) => { purple: t.syntax.constant.hex(), } - const syntax: ThemeConfigInputSyntax = { + const syntax: ThemeSyntax = { constant: { color: t.syntax.constant.hex() }, "string.regex": { color: t.syntax.regexp.hex() }, string: { color: t.syntax.string.hex() }, @@ -61,7 +61,7 @@ export const build_theme = (t: typeof dark, light: boolean) => { } } -export const build_syntax = (t: typeof dark): ThemeConfigInputSyntax => { +export const build_syntax = (t: typeof dark): ThemeSyntax => { return { constant: { color: t.syntax.constant.hex() }, "string.regex": { color: t.syntax.regexp.hex() }, diff --git a/styles/src/themes/gruvbox/gruvbox-common.ts b/styles/src/themes/gruvbox/gruvbox-common.ts index 95e45efa95122ec3ca37d2dc57360ca55ec83e85..2fa6b58faadb91b5689c5eac93baf706f6faa391 100644 --- a/styles/src/themes/gruvbox/gruvbox-common.ts +++ b/styles/src/themes/gruvbox/gruvbox-common.ts @@ -4,8 +4,8 @@ import { ThemeAppearance, ThemeLicenseType, ThemeConfig, + ThemeSyntax, ThemeFamilyMeta, - ThemeConfigInputSyntax, } from "../../common" const meta: ThemeFamilyMeta = { @@ -214,7 +214,7 @@ const build_variant = (variant: Variant): ThemeConfig => { magenta: color_ramp(chroma(variant.colors.gray)), } - const syntax: ThemeConfigInputSyntax = { + const syntax: ThemeSyntax = { primary: { color: neutral[is_light ? 0 : 8] }, "text.literal": { color: colors.blue }, comment: { color: colors.gray }, @@ -229,7 +229,7 @@ const build_variant = (variant: Variant): ThemeConfig => { "string.special.symbol": { color: colors.aqua }, "string.regex": { color: colors.orange }, type: { color: colors.yellow }, - // enum: { color: colors.orange }, + enum: { color: colors.orange }, tag: { color: colors.aqua }, constant: { color: colors.yellow }, keyword: { color: colors.red }, diff --git a/styles/src/themes/one/one-dark.ts b/styles/src/themes/one/one-dark.ts index 97f3922f36f57c7452c8face077a8b2bc8997858..f672b892ee040e60745f3d0f8bd6875c743ed46a 100644 --- a/styles/src/themes/one/one-dark.ts +++ b/styles/src/themes/one/one-dark.ts @@ -54,6 +54,7 @@ export const theme: ThemeConfig = { syntax: { boolean: { color: color.orange }, comment: { color: color.grey }, + enum: { color: color.red }, "emphasis.strong": { color: color.orange }, function: { color: color.blue }, keyword: { color: color.purple }, @@ -72,7 +73,8 @@ export const theme: ThemeConfig = { "text.literal": { color: color.green }, type: { color: color.teal }, "variable.special": { color: color.orange }, - "method.constructor": { color: color.blue }, + variant: { color: color.blue }, + constructor: { color: color.blue }, }, }, } diff --git a/styles/src/themes/one/one-light.ts b/styles/src/themes/one/one-light.ts index 655428757898a7f07f4524377721ab62ef1f5b53..c3de7826c96679fb1c1f2b1a9d81324687d919b9 100644 --- a/styles/src/themes/one/one-light.ts +++ b/styles/src/themes/one/one-light.ts @@ -55,6 +55,7 @@ export const theme: ThemeConfig = { syntax: { boolean: { color: color.orange }, comment: { color: color.grey }, + enum: { color: color.red }, "emphasis.strong": { color: color.orange }, function: { color: color.blue }, keyword: { color: color.purple }, @@ -72,6 +73,7 @@ export const theme: ThemeConfig = { "text.literal": { color: color.green }, type: { color: color.teal }, "variable.special": { color: color.orange }, + variant: { color: color.blue }, }, }, } diff --git a/styles/src/themes/rose-pine/common.ts b/styles/src/themes/rose-pine/common.ts index decccc0a6dc8b1062ec8d5a88a699350a79bf322..5c5482a754a634bd2338af2613327554ec36d13c 100644 --- a/styles/src/themes/rose-pine/common.ts +++ b/styles/src/themes/rose-pine/common.ts @@ -1,4 +1,4 @@ -import { ThemeConfigInputSyntax } from "../../common" +import { ThemeSyntax } from "../../common" export const color = { default: { @@ -54,7 +54,7 @@ export const color = { }, } -export const syntax = (c: typeof color.default): ThemeConfigInputSyntax => { +export const syntax = (c: typeof color.default): Partial => { return { comment: { color: c.muted }, operator: { color: c.pine }, diff --git a/styles/src/types/extract_syntax_types.ts b/styles/src/types/extract_syntax_types.ts deleted file mode 100644 index eb21d2418b9c830099cffc0c03f9ecf4c88ba7ed..0000000000000000000000000000000000000000 --- a/styles/src/types/extract_syntax_types.ts +++ /dev/null @@ -1,111 +0,0 @@ -import fs from "fs" -import path from "path" -import readline from "readline" - -function escapeTypeName(name: string): string { - return `'${name.replace("@", "").toLowerCase()}'` -} - -const generatedNote = `// This file is generated by extract_syntax_types.ts -// Do not edit this file directly -// It is generated from the highlight.scm files in the zed crate - -// To regenerate this file manually: -// 'npm run extract-syntax-types' from ./styles` - -const defaultTextProperty = ` /** Default text color */ - | 'primary'` - -const main = async () => { - const pathFromRoot = "crates/zed/src/languages" - const directoryPath = path.join(__dirname, "../../../", pathFromRoot) - const stylesMap: Record> = {} - const propertyLanguageMap: Record> = {} - - const processFile = async (filePath: string, language: string) => { - const fileStream = fs.createReadStream(filePath) - const rl = readline.createInterface({ - input: fileStream, - crlfDelay: Infinity, - }) - - for await (const line of rl) { - const cleanedLine = line.replace(/"@[a-zA-Z0-9_.]*"/g, "") - const match = cleanedLine.match(/@(\w+\.*)*/g) - if (match) { - match.forEach((property) => { - const formattedProperty = escapeTypeName(property) - // Only add non-empty properties - if (formattedProperty !== "''") { - if (!propertyLanguageMap[formattedProperty]) { - propertyLanguageMap[formattedProperty] = new Set() - } - propertyLanguageMap[formattedProperty].add(language) - } - }) - } - } - } - - const directories = fs - .readdirSync(directoryPath, { withFileTypes: true }) - .filter((dirent) => dirent.isDirectory()) - .map((dirent) => dirent.name) - - for (const dir of directories) { - const highlightsFilePath = path.join( - directoryPath, - dir, - "highlights.scm" - ) - if (fs.existsSync(highlightsFilePath)) { - await processFile(highlightsFilePath, dir) - } - } - - for (const [language, properties] of Object.entries(stylesMap)) { - console.log(`${language}: ${Array.from(properties).join(", ")}`) - } - - const sortedProperties = Object.entries(propertyLanguageMap).sort( - ([propA], [propB]) => propA.localeCompare(propB) - ) - - const outStream = fs.createWriteStream(path.join(__dirname, "syntax.ts")) - let allProperties = "" - const syntaxKeys = [] - for (const [property, languages] of sortedProperties) { - let languagesArray = Array.from(languages) - const moreThanSeven = languagesArray.length > 7 - // Limit to the first 7 languages, append "..." if more than 7 - languagesArray = languagesArray.slice(0, 7) - if (moreThanSeven) { - languagesArray.push("...") - } - const languagesString = languagesArray.join(", ") - const comment = `/** ${languagesString} */` - allProperties += ` ${comment}\n | ${property} \n` - syntaxKeys.push(property) - } - outStream.write(`${generatedNote} - -export type SyntaxHighlightStyle = { - color: string, - fade_out?: number, - italic?: boolean, - underline?: boolean, - weight?: string, -} - -export type Syntax = Record -export type SyntaxOverride = Partial - -export type SyntaxProperty = \n${defaultTextProperty}\n\n${allProperties} - -export const allSyntaxKeys: SyntaxProperty[] = [\n ${syntaxKeys.join( - ",\n " - )}\n]`) - outStream.end() -} - -main().catch(console.error) diff --git a/styles/src/types/syntax.ts b/styles/src/types/syntax.ts deleted file mode 100644 index 9b23dbde3cc799090e1dd848706f2b96a88e7ba6..0000000000000000000000000000000000000000 --- a/styles/src/types/syntax.ts +++ /dev/null @@ -1,202 +0,0 @@ -// This file is generated by extract_syntax_types.ts -// Do not edit this file directly -// It is generated from the highlight.scm files in the zed crate - -// To regenerate this file manually: -// 'npm run extract-syntax-types' from ./styles - -export type SyntaxHighlightStyle = { - color: string - fade_out?: number - italic?: boolean - underline?: boolean - weight?: string -} - -export type Syntax = Record -export type SyntaxOverride = Partial - -export type SyntaxProperty = - /** Default text color */ - | "primary" - - /** elixir */ - | "__attribute__" - /** elixir */ - | "__name__" - /** elixir */ - | "_sigil_name" - /** css, heex, lua */ - | "attribute" - /** javascript, lua, tsx, typescript, yaml */ - | "boolean" - /** elixir */ - | "comment.doc" - /** elixir */ - | "comment.unused" - /** bash, c, cpp, css, elixir, elm, erb, ... */ - | "comment" - /** elixir, go, javascript, lua, php, python, racket, ... */ - | "constant.builtin" - /** bash, c, cpp, elixir, elm, glsl, heex, ... */ - | "constant" - /** glsl */ - | "delimiter" - /** bash, elixir, javascript, python, ruby, tsx, typescript */ - | "embedded" - /** markdown */ - | "emphasis.strong" - /** markdown */ - | "emphasis" - /** go, python, racket, ruby, scheme */ - | "escape" - /** lua */ - | "field" - /** lua, php, python */ - | "function.builtin" - /** elm, lua, rust */ - | "function.definition" - /** ruby */ - | "function.method.builtin" - /** go, javascript, php, python, ruby, rust, tsx, ... */ - | "function.method" - /** rust */ - | "function.special.definition" - /** c, cpp, glsl, rust */ - | "function.special" - /** bash, c, cpp, css, elixir, elm, glsl, ... */ - | "function" - /** elm */ - | "identifier" - /** glsl */ - | "keyword.function" - /** bash, c, cpp, css, elixir, elm, erb, ... */ - | "keyword" - /** c, cpp, glsl */ - | "label" - /** markdown */ - | "link_text" - /** markdown */ - | "link_uri" - /** lua, php, tsx, typescript */ - | "method.constructor" - /** lua */ - | "method" - /** heex */ - | "module" - /** svelte */ - | "none" - /** bash, c, cpp, css, elixir, glsl, go, ... */ - | "number" - /** bash, c, cpp, css, elixir, elm, glsl, ... */ - | "operator" - /** lua */ - | "parameter" - /** lua */ - | "preproc" - /** bash, c, cpp, css, glsl, go, html, ... */ - | "property" - /** c, cpp, elixir, elm, heex, html, javascript, ... */ - | "punctuation.bracket" - /** c, cpp, css, elixir, elm, heex, javascript, ... */ - | "punctuation.delimiter" - /** markdown */ - | "punctuation.list_marker" - /** elixir, javascript, python, ruby, tsx, typescript, yaml */ - | "punctuation.special" - /** elixir */ - | "punctuation" - /** glsl */ - | "storageclass" - /** elixir, elm, yaml */ - | "string.escape" - /** elixir, javascript, racket, ruby, tsx, typescript */ - | "string.regex" - /** elixir, ruby */ - | "string.special.symbol" - /** css, elixir, toml */ - | "string.special" - /** bash, c, cpp, css, elixir, elm, glsl, ... */ - | "string" - /** svelte */ - | "tag.delimiter" - /** css, heex, php, svelte */ - | "tag" - /** markdown */ - | "text.literal" - /** markdown */ - | "title" - /** javascript, php, rust, tsx, typescript */ - | "type.builtin" - /** glsl */ - | "type.qualifier" - /** c, cpp, css, elixir, elm, glsl, go, ... */ - | "type" - /** glsl, php */ - | "variable.builtin" - /** cpp, css, javascript, lua, racket, ruby, rust, ... */ - | "variable.special" - /** c, cpp, elm, glsl, go, javascript, lua, ... */ - | "variable" - -export const allSyntaxKeys: SyntaxProperty[] = [ - "__attribute__", - "__name__", - "_sigil_name", - "attribute", - "boolean", - "comment.doc", - "comment.unused", - "comment", - "constant.builtin", - "constant", - "delimiter", - "embedded", - "emphasis.strong", - "emphasis", - "escape", - "field", - "function.builtin", - "function.definition", - "function.method.builtin", - "function.method", - "function.special.definition", - "function.special", - "function", - "identifier", - "keyword.function", - "keyword", - "label", - "link_text", - "link_uri", - "method.constructor", - "method", - "module", - "none", - "number", - "operator", - "parameter", - "preproc", - "property", - "punctuation.bracket", - "punctuation.delimiter", - "punctuation.list_marker", - "punctuation.special", - "punctuation", - "storageclass", - "string.escape", - "string.regex", - "string.special.symbol", - "string.special", - "string", - "tag.delimiter", - "tag", - "text.literal", - "title", - "type.builtin", - "type.qualifier", - "type", - "variable.builtin", - "variable.special", - "variable", -] diff --git a/styles/tsconfig.json b/styles/tsconfig.json index a1913027b705df7d349c78bcc6b74bb96851fe8c..281bd74b215bd16426bb6a8f9d68ddeb5a5bea43 100644 --- a/styles/tsconfig.json +++ b/styles/tsconfig.json @@ -24,5 +24,7 @@ "useUnknownInCatchVariables": false, "baseUrl": "." }, - "exclude": ["node_modules"] + "exclude": [ + "node_modules" + ] } From 884cee6dfda9f4b887976cb14f87e82ac6b87fc0 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 2 Aug 2023 14:05:03 -0600 Subject: [PATCH 115/160] Get tests compiling returning WindowHandle from add_window --- crates/collab/src/tests.rs | 5 +- crates/collab/src/tests/integration_tests.rs | 52 +- .../src/incoming_call_notification.rs | 4 +- .../src/project_shared_notification.rs | 4 +- crates/command_palette/src/command_palette.rs | 4 +- crates/copilot/src/sign_in.rs | 8 +- crates/diagnostics/src/diagnostics.rs | 8 +- crates/editor/src/editor_tests.rs | 627 ++++++++++-------- crates/editor/src/element.rs | 30 +- crates/editor/src/inlay_hint_cache.rs | 30 +- .../src/test/editor_lsp_test_context.rs | 5 +- crates/editor/src/test/editor_test_context.rs | 12 +- crates/file_finder/src/file_finder.rs | 230 +++---- crates/gpui/src/app.rs | 26 +- crates/gpui/src/app/window.rs | 8 +- crates/language_tools/src/lsp_log_tests.rs | 4 +- crates/project_panel/src/project_panel.rs | 32 +- crates/project_symbols/src/project_symbols.rs | 4 +- crates/search/src/buffer_search.rs | 19 +- crates/search/src/project_search.rs | 16 +- crates/terminal_view/src/terminal_view.rs | 4 +- crates/workspace/src/pane.rs | 30 +- crates/workspace/src/workspace.rs | 108 +-- crates/zed/src/zed.rs | 34 +- 24 files changed, 726 insertions(+), 578 deletions(-) diff --git a/crates/collab/src/tests.rs b/crates/collab/src/tests.rs index b1d0bedb2cf23c856f320aacabb8d2fb489f2e2a..4804f5b0f1f24033fc79c12a6af5d87096a49a84 100644 --- a/crates/collab/src/tests.rs +++ b/crates/collab/src/tests.rs @@ -495,8 +495,9 @@ impl TestClient { // We use a workspace container so that we don't need to remove the window in order to // drop the workspace and we can use a ViewHandle instead. - let (window_id, container) = cx.add_window(|_| WorkspaceContainer { workspace: None }); - let workspace = cx.add_view(window_id, |cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|_| WorkspaceContainer { workspace: None }); + let container = window.root(cx); + let workspace = window.add_view(cx, |cx| Workspace::test_new(project.clone(), cx)); container.update(cx, |container, cx| { container.workspace = Some(workspace.downgrade()); cx.notify(); diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index ab94f16a07f011b8166f7b7ff779539b89401034..1a8e6d938d6d6caac2b8caee501e1088ddeea5b3 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -7,8 +7,7 @@ use client::{User, RECEIVE_TIMEOUT}; use collections::HashSet; use editor::{ test::editor_test_context::EditorTestContext, ConfirmCodeAction, ConfirmCompletion, - ConfirmRename, Editor, ExcerptRange, MultiBuffer, Redo, Rename, ToOffset, ToggleCodeActions, - Undo, + ConfirmRename, Editor, ExcerptRange, MultiBuffer, Redo, Rename, ToggleCodeActions, Undo, }; use fs::{repository::GitFileStatus, FakeFs, Fs as _, LineEnding, RemoveOptions}; use futures::StreamExt as _; @@ -1208,7 +1207,7 @@ async fn test_share_project( cx_c: &mut TestAppContext, ) { deterministic.forbid_parking(); - let (window_b, _) = cx_b.add_window(|_| EmptyView); + let window_b = cx_b.add_window(|_| EmptyView); let mut server = TestServer::start(&deterministic).await; let client_a = server.create_client(cx_a, "user_a").await; let client_b = server.create_client(cx_b, "user_b").await; @@ -1316,7 +1315,7 @@ async fn test_share_project( .await .unwrap(); - let editor_b = cx_b.add_view(window_b, |cx| Editor::for_buffer(buffer_b, None, cx)); + let editor_b = window_b.add_view(cx_b, |cx| Editor::for_buffer(buffer_b, None, cx)); // Client A sees client B's selection deterministic.run_until_parked(); @@ -1499,8 +1498,8 @@ async fn test_host_disconnect( deterministic.run_until_parked(); assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared())); - let (window_id_b, workspace_b) = - cx_b.add_window(|cx| Workspace::test_new(project_b.clone(), cx)); + let window_b = cx_b.add_window(|cx| Workspace::test_new(project_b.clone(), cx)); + let workspace_b = window_b.root(cx_b); let editor_b = workspace_b .update(cx_b, |workspace, cx| { workspace.open_path((worktree_id, "b.txt"), None, true, cx) @@ -1509,9 +1508,7 @@ async fn test_host_disconnect( .unwrap() .downcast::() .unwrap(); - assert!(cx_b - .read_window(window_id_b, |cx| editor_b.is_focused(cx)) - .unwrap()); + assert!(window_b.read_with(cx_b, |cx| editor_b.is_focused(cx))); editor_b.update(cx_b, |editor, cx| editor.insert("X", cx)); assert!(cx_b.is_window_edited(workspace_b.window_id())); @@ -1525,7 +1522,7 @@ async fn test_host_disconnect( assert!(worktree_a.read_with(cx_a, |tree, _| !tree.as_local().unwrap().is_shared())); // Ensure client B's edited state is reset and that the whole window is blurred. - cx_b.read_window(window_id_b, |cx| { + window_b.read_with(cx_b, |cx| { assert_eq!(cx.focused_view_id(), None); }); assert!(!cx_b.is_window_edited(workspace_b.window_id())); @@ -3445,13 +3442,11 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor( .update(cx_a, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx)) .await .unwrap(); - let (window_a, _) = cx_a.add_window(|_| EmptyView); - let editor_a = cx_a.add_view(window_a, |cx| { - Editor::for_buffer(buffer_a, Some(project_a), cx) - }); + let window_a = cx_a.add_window(|_| EmptyView); + let editor_a = window_a.add_view(cx_a, |cx| Editor::for_buffer(buffer_a, Some(project_a), cx)); let mut editor_cx_a = EditorTestContext { cx: cx_a, - window_id: window_a, + window_id: window_a.id(), editor: editor_a, }; @@ -3460,13 +3455,11 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor( .update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx)) .await .unwrap(); - let (window_b, _) = cx_b.add_window(|_| EmptyView); - let editor_b = cx_b.add_view(window_b, |cx| { - Editor::for_buffer(buffer_b, Some(project_b), cx) - }); + let window_b = cx_b.add_window(|_| EmptyView); + let editor_b = window_b.add_view(cx_b, |cx| Editor::for_buffer(buffer_b, Some(project_b), cx)); let mut editor_cx_b = EditorTestContext { cx: cx_b, - window_id: window_b, + window_id: window_b.id(), editor: editor_b, }; @@ -4205,8 +4198,8 @@ async fn test_collaborating_with_completion( .update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx)) .await .unwrap(); - let (window_b, _) = cx_b.add_window(|_| EmptyView); - let editor_b = cx_b.add_view(window_b, |cx| { + let window_b = cx_b.add_window(|_| EmptyView); + let editor_b = window_b.add_view(cx_b, |cx| { Editor::for_buffer(buffer_b.clone(), Some(project_b.clone()), cx) }); @@ -5316,7 +5309,8 @@ async fn test_collaborating_with_code_actions( // Join the project as client B. let project_b = client_b.build_remote_project(project_id, cx_b).await; - let (_window_b, workspace_b) = cx_b.add_window(|cx| Workspace::test_new(project_b.clone(), cx)); + let window_b = cx_b.add_window(|cx| Workspace::test_new(project_b.clone(), cx)); + let workspace_b = window_b.root(cx_b); let editor_b = workspace_b .update(cx_b, |workspace, cx| { workspace.open_path((worktree_id, "main.rs"), None, true, cx) @@ -5540,7 +5534,8 @@ async fn test_collaborating_with_renames( .unwrap(); let project_b = client_b.build_remote_project(project_id, cx_b).await; - let (_window_b, workspace_b) = cx_b.add_window(|cx| Workspace::test_new(project_b.clone(), cx)); + let window_b = cx_b.add_window(|cx| Workspace::test_new(project_b.clone(), cx)); + let workspace_b = window_b.root(cx_b); let editor_b = workspace_b .update(cx_b, |workspace, cx| { workspace.open_path((worktree_id, "one.rs"), None, true, cx) @@ -5571,6 +5566,7 @@ async fn test_collaborating_with_renames( .unwrap(); prepare_rename.await.unwrap(); editor_b.update(cx_b, |editor, cx| { + use editor::ToOffset; let rename = editor.pending_rename().unwrap(); let buffer = editor.buffer().read(cx).snapshot(cx); assert_eq!( @@ -7601,8 +7597,8 @@ async fn test_on_input_format_from_host_to_guest( .update(cx_a, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx)) .await .unwrap(); - let (window_a, _) = cx_a.add_window(|_| EmptyView); - let editor_a = cx_a.add_view(window_a, |cx| { + let window_a = cx_a.add_window(|_| EmptyView); + let editor_a = window_a.add_view(cx_a, |cx| { Editor::for_buffer(buffer_a, Some(project_a.clone()), cx) }); @@ -7730,8 +7726,8 @@ async fn test_on_input_format_from_guest_to_host( .update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx)) .await .unwrap(); - let (window_b, _) = cx_b.add_window(|_| EmptyView); - let editor_b = cx_b.add_view(window_b, |cx| { + let window_b = cx_b.add_window(|_| EmptyView); + let editor_b = window_b.add_view(cx_b, |cx| { Editor::for_buffer(buffer_b, Some(project_b.clone()), cx) }); diff --git a/crates/collab_ui/src/incoming_call_notification.rs b/crates/collab_ui/src/incoming_call_notification.rs index 4066b5b229a536da0b49e0ad8c5b7ab492968e18..a9c5e697a5f60d0cb6f9c0e6baf7cac50aba192a 100644 --- a/crates/collab_ui/src/incoming_call_notification.rs +++ b/crates/collab_ui/src/incoming_call_notification.rs @@ -31,7 +31,7 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { for screen in cx.platform().screens() { let screen_bounds = screen.bounds(); - let (window_id, _) = cx.add_window( + let window = cx.add_window( WindowOptions { bounds: WindowBounds::Fixed(RectF::new( screen_bounds.upper_right() @@ -49,7 +49,7 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { |_| IncomingCallNotification::new(incoming_call.clone(), app_state.clone()), ); - notification_windows.push(window_id); + notification_windows.push(window.id()); } } } diff --git a/crates/collab_ui/src/project_shared_notification.rs b/crates/collab_ui/src/project_shared_notification.rs index fea6118bdf4055d2b4bb862d1cde876b9dd8c60f..03ab91623b43270bf2592ced0f460b474fd0c435 100644 --- a/crates/collab_ui/src/project_shared_notification.rs +++ b/crates/collab_ui/src/project_shared_notification.rs @@ -26,7 +26,7 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { for screen in cx.platform().screens() { let screen_bounds = screen.bounds(); - let (window_id, _) = cx.add_window( + let window = cx.add_window( WindowOptions { bounds: WindowBounds::Fixed(RectF::new( screen_bounds.upper_right() - vec2f(PADDING + window_size.x(), PADDING), @@ -52,7 +52,7 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { notification_windows .entry(*project_id) .or_insert(Vec::new()) - .push(window_id); + .push(window.id()); } } room::Event::RemoteProjectUnshared { project_id } => { diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 7461fb28c7382bfaaf9f97385579e161251276fc..7d4b4126b702774bf8c295d3b61f904ff7ebf80c 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -295,7 +295,9 @@ mod tests { let app_state = init_test(cx); let project = Project::test(app_state.fs.clone(), [], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); + let window_id = window.id(); let editor = cx.add_view(window_id, |cx| { let mut editor = Editor::single_line(None, cx); editor.set_text("abc", cx); diff --git a/crates/copilot/src/sign_in.rs b/crates/copilot/src/sign_in.rs index fec8f27c9730d776f4311498635772fb8a2791a5..659bee7445f0696d32bf7532c902907d7ddcf11c 100644 --- a/crates/copilot/src/sign_in.rs +++ b/crates/copilot/src/sign_in.rs @@ -27,7 +27,7 @@ pub fn init(cx: &mut AppContext) { if let Some(code_verification_handle) = code_verification.as_mut() { let window_id = code_verification_handle.id(); let updated = cx.update_window(window_id, |cx| { - code_verification_handle.update(cx, |code_verification, cx| { + code_verification_handle.update_root(cx, |code_verification, cx| { code_verification.set_status(status.clone(), cx) }); cx.activate_window(); @@ -41,9 +41,9 @@ pub fn init(cx: &mut AppContext) { } Status::Authorized | Status::Unauthorized => { if let Some(code_verification) = code_verification.as_ref() { - let window_id = code_verification.window_id(); + let window_id = code_verification.id(); cx.update_window(window_id, |cx| { - code_verification.update(cx, |code_verification, cx| { + code_verification.update_root(cx, |code_verification, cx| { code_verification.set_status(status, cx) }); @@ -54,7 +54,7 @@ pub fn init(cx: &mut AppContext) { } _ => { if let Some(code_verification) = code_verification.take() { - cx.update_window(code_verification.window_id(), |cx| cx.remove_window()); + code_verification.update(cx, |cx| cx.remove_window()); } } } diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index d0cd437946a54cf6cb5446fecd0d310b1c82a269..2444465be666124adb706bcf1833c50c77cee081 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -855,7 +855,9 @@ mod tests { let language_server_id = LanguageServerId(0); let project = Project::test(fs.clone(), ["/test".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); + let window_id = window.id(); // Create some diagnostics project.update(cx, |project, cx| { @@ -1248,7 +1250,9 @@ mod tests { let server_id_1 = LanguageServerId(100); let server_id_2 = LanguageServerId(101); let project = Project::test(fs.clone(), ["/test".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); + let window_id = window.id(); let view = cx.add_view(window_id, |cx| { ProjectDiagnosticsEditor::new(project.clone(), workspace.downgrade(), cx) diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index eb03d2bdc0f103c2b94352312d3e86df860c821c..96921643d45a1b7c1083dab5df471b3bd95adb2d 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -48,36 +48,40 @@ fn test_edit_events(cx: &mut TestAppContext) { }); let events = Rc::new(RefCell::new(Vec::new())); - let (_, editor1) = cx.add_window({ - let events = events.clone(); - |cx| { - cx.subscribe(&cx.handle(), move |_, _, event, _| { - if matches!( - event, - Event::Edited | Event::BufferEdited | Event::DirtyChanged - ) { - events.borrow_mut().push(("editor1", event.clone())); - } - }) - .detach(); - Editor::for_buffer(buffer.clone(), None, cx) - } - }); - let (_, editor2) = cx.add_window({ - let events = events.clone(); - |cx| { - cx.subscribe(&cx.handle(), move |_, _, event, _| { - if matches!( - event, - Event::Edited | Event::BufferEdited | Event::DirtyChanged - ) { - events.borrow_mut().push(("editor2", event.clone())); - } - }) - .detach(); - Editor::for_buffer(buffer.clone(), None, cx) - } - }); + let editor1 = cx + .add_window({ + let events = events.clone(); + |cx| { + cx.subscribe(&cx.handle(), move |_, _, event, _| { + if matches!( + event, + Event::Edited | Event::BufferEdited | Event::DirtyChanged + ) { + events.borrow_mut().push(("editor1", event.clone())); + } + }) + .detach(); + Editor::for_buffer(buffer.clone(), None, cx) + } + }) + .detach(cx); + let editor2 = cx + .add_window({ + let events = events.clone(); + |cx| { + cx.subscribe(&cx.handle(), move |_, _, event, _| { + if matches!( + event, + Event::Edited | Event::BufferEdited | Event::DirtyChanged + ) { + events.borrow_mut().push(("editor2", event.clone())); + } + }) + .detach(); + Editor::for_buffer(buffer.clone(), None, cx) + } + }) + .detach(cx); assert_eq!(mem::take(&mut *events.borrow_mut()), []); // Mutating editor 1 will emit an `Edited` event only for that editor. @@ -173,7 +177,9 @@ fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) { let buffer = cx.add_model(|cx| language::Buffer::new(0, "123456", cx)); let group_interval = buffer.read_with(cx, |buffer, _| buffer.transaction_group_interval()); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let (_, editor) = cx.add_window(|cx| build_editor(buffer.clone(), cx)); + let editor = cx + .add_window(|cx| build_editor(buffer.clone(), cx)) + .detach(cx); editor.update(cx, |editor, cx| { editor.start_transaction_at(now, cx); @@ -343,10 +349,12 @@ fn test_ime_composition(cx: &mut TestAppContext) { fn test_selection_with_mouse(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, editor) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\nddddddd\n", cx); - build_editor(buffer, cx) - }); + let editor = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\nddddddd\n", cx); + build_editor(buffer, cx) + }) + .detach(cx); editor.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx); }); @@ -410,10 +418,12 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) { fn test_canceling_pending_selection(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx); @@ -456,10 +466,12 @@ fn test_clone(cx: &mut TestAppContext) { true, ); - let (_, editor) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple(&text, cx); - build_editor(buffer, cx) - }); + let editor = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple(&text, cx); + build_editor(buffer, cx) + }) + .detach(cx); editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| s.select_ranges(selection_ranges.clone())); @@ -473,9 +485,11 @@ fn test_clone(cx: &mut TestAppContext) { ); }); - let (_, cloned_editor) = editor.update(cx, |editor, cx| { - cx.add_window(Default::default(), |cx| editor.clone(cx)) - }); + let cloned_editor = editor + .update(cx, |editor, cx| { + cx.add_window(Default::default(), |cx| editor.clone(cx)) + }) + .detach(cx); let snapshot = editor.update(cx, |e, cx| e.snapshot(cx)); let cloned_snapshot = cloned_editor.update(cx, |e, cx| e.snapshot(cx)); @@ -509,7 +523,9 @@ async fn test_navigation_history(cx: &mut TestAppContext) { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, [], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + let window_id = window.id(); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); cx.add_view(window_id, |cx| { let buffer = MultiBuffer::build_simple(&sample_text(300, 5, 'a'), cx); @@ -618,10 +634,12 @@ async fn test_navigation_history(cx: &mut TestAppContext) { fn test_cancel(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(3, 4), false, 1, cx); @@ -661,9 +679,10 @@ fn test_cancel(cx: &mut TestAppContext) { fn test_fold_action(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple( - &" + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple( + &" impl Foo { // Hello! @@ -680,11 +699,12 @@ fn test_fold_action(cx: &mut TestAppContext) { } } " - .unindent(), - cx, - ); - build_editor(buffer.clone(), cx) - }); + .unindent(), + cx, + ); + build_editor(buffer.clone(), cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { @@ -752,7 +772,9 @@ fn test_move_cursor(cx: &mut TestAppContext) { init_test(cx, |_| {}); let buffer = cx.update(|cx| MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx)); - let (_, view) = cx.add_window(|cx| build_editor(buffer.clone(), cx)); + let view = cx + .add_window(|cx| build_editor(buffer.clone(), cx)) + .detach(cx); buffer.update(cx, |buffer, cx| { buffer.edit( @@ -827,10 +849,12 @@ fn test_move_cursor(cx: &mut TestAppContext) { fn test_move_cursor_multibyte(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcde\nαβγδε\n", cx); - build_editor(buffer.clone(), cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcde\nαβγδε\n", cx); + build_editor(buffer.clone(), cx) + }) + .detach(cx); assert_eq!('ⓐ'.len_utf8(), 3); assert_eq!('α'.len_utf8(), 2); @@ -932,10 +956,12 @@ fn test_move_cursor_multibyte(cx: &mut TestAppContext) { fn test_move_cursor_different_line_lengths(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx); - build_editor(buffer.clone(), cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx); + build_editor(buffer.clone(), cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([empty_range(0, "ⓐⓑⓒⓓⓔ".len())]); @@ -982,10 +1008,12 @@ fn test_move_cursor_different_line_lengths(cx: &mut TestAppContext) { fn test_beginning_end_of_line(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("abc\n def", cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("abc\n def", cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -1145,10 +1173,12 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { fn test_prev_next_word_boundary(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("use std::str::{foo, bar}\n\n {baz.qux()}", cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("use std::str::{foo, bar}\n\n {baz.qux()}", cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -1197,10 +1227,13 @@ fn test_prev_next_word_boundary(cx: &mut TestAppContext) { fn test_prev_next_word_bounds_with_soft_wrap(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("use one::{\n two::three::four::five\n};", cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = + MultiBuffer::build_simple("use one::{\n two::three::four::five\n};", cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.set_wrap_width(Some(140.), cx); @@ -1530,10 +1563,12 @@ async fn test_delete_to_beginning_of_line(cx: &mut gpui::TestAppContext) { fn test_delete_to_word_boundary(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("one two three four", cx); - build_editor(buffer.clone(), cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("one two three four", cx); + build_editor(buffer.clone(), cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { @@ -1566,10 +1601,12 @@ fn test_delete_to_word_boundary(cx: &mut TestAppContext) { fn test_newline(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("aaaa\n bbbb\n", cx); - build_editor(buffer.clone(), cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("aaaa\n bbbb\n", cx); + build_editor(buffer.clone(), cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { @@ -1589,9 +1626,10 @@ fn test_newline(cx: &mut TestAppContext) { fn test_newline_with_old_selections(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, editor) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple( - " + let editor = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple( + " a b( X @@ -1600,19 +1638,20 @@ fn test_newline_with_old_selections(cx: &mut TestAppContext) { X ) " - .unindent() - .as_str(), - cx, - ); - let mut editor = build_editor(buffer.clone(), cx); - 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 - }); + .unindent() + .as_str(), + cx, + ); + let mut editor = build_editor(buffer.clone(), cx); + 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 + }) + .detach(cx); editor.update(cx, |editor, cx| { // Edit the buffer directly, deleting ranges surrounding the editor's selections @@ -1817,12 +1856,14 @@ async fn test_newline_comments(cx: &mut gpui::TestAppContext) { fn test_insert_with_old_selections(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, editor) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("a( X ), b( Y ), c( Z )", cx); - let mut editor = build_editor(buffer.clone(), cx); - editor.change_selections(None, cx, |s| s.select_ranges([3..4, 11..12, 19..20])); - editor - }); + let editor = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("a( X ), b( Y ), c( Z )", cx); + let mut editor = build_editor(buffer.clone(), cx); + editor.change_selections(None, cx, |s| s.select_ranges([3..4, 11..12, 19..20])); + editor + }) + .detach(cx); editor.update(cx, |editor, cx| { // Edit the buffer directly, deleting ranges surrounding the editor's selections @@ -2329,10 +2370,12 @@ async fn test_delete(cx: &mut gpui::TestAppContext) { fn test_delete_line(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -2352,10 +2395,12 @@ fn test_delete_line(cx: &mut TestAppContext) { ); }); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)]) @@ -2654,10 +2699,12 @@ async fn test_manipulate_lines_with_multi_selection(cx: &mut TestAppContext) { fn test_duplicate_line(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -2680,10 +2727,12 @@ fn test_duplicate_line(cx: &mut TestAppContext) { ); }); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -2707,10 +2756,12 @@ fn test_duplicate_line(cx: &mut TestAppContext) { fn test_move_line_up_down(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.fold_ranges( vec![ @@ -2806,10 +2857,12 @@ fn test_move_line_up_down(cx: &mut TestAppContext) { fn test_move_line_up_down_with_blocks(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, editor) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx); - build_editor(buffer, cx) - }); + let editor = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx); + build_editor(buffer, cx) + }) + .detach(cx); editor.update(cx, |editor, cx| { let snapshot = editor.buffer.read(cx).snapshot(cx); editor.insert_blocks( @@ -2834,102 +2887,94 @@ fn test_move_line_up_down_with_blocks(cx: &mut TestAppContext) { fn test_transpose(cx: &mut TestAppContext) { init_test(cx, |_| {}); - _ = cx - .add_window(|cx| { - let mut editor = build_editor(MultiBuffer::build_simple("abc", cx), cx); + _ = cx.add_window(|cx| { + let mut editor = build_editor(MultiBuffer::build_simple("abc", cx), cx); - 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.ranges(cx), [2..2]); + 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.ranges(cx), [2..2]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "bca"); - assert_eq!(editor.selections.ranges(cx), [3..3]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bca"); + assert_eq!(editor.selections.ranges(cx), [3..3]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "bac"); - assert_eq!(editor.selections.ranges(cx), [3..3]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bac"); + assert_eq!(editor.selections.ranges(cx), [3..3]); - editor - }) - .1; + editor + }); - _ = cx - .add_window(|cx| { - let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); + _ = cx.add_window(|cx| { + let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); - 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.ranges(cx), [3..3]); + 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.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.ranges(cx), [5..5]); + 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.ranges(cx), [5..5]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "acbde\n"); - assert_eq!(editor.selections.ranges(cx), [6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "acbde\n"); + assert_eq!(editor.selections.ranges(cx), [6..6]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "acbd\ne"); - assert_eq!(editor.selections.ranges(cx), [6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "acbd\ne"); + assert_eq!(editor.selections.ranges(cx), [6..6]); - editor - }) - .1; + editor + }); - _ = cx - .add_window(|cx| { - let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); + _ = cx.add_window(|cx| { + let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); - 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.ranges(cx), [2..2, 3..3, 5..5]); + 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.ranges(cx), [2..2, 3..3, 5..5]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "bcade\n"); - assert_eq!(editor.selections.ranges(cx), [3..3, 4..4, 6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bcade\n"); + 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.ranges(cx), [4..4, 6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bcda\ne"); + 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.ranges(cx), [4..4, 6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bcade\n"); + 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.ranges(cx), [5..5, 6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bcaed\n"); + assert_eq!(editor.selections.ranges(cx), [5..5, 6..6]); - editor - }) - .1; + editor + }); - _ = cx - .add_window(|cx| { - let mut editor = build_editor(MultiBuffer::build_simple("🍐🏀✋", cx), cx); + _ = cx.add_window(|cx| { + let mut editor = build_editor(MultiBuffer::build_simple("🍐🏀✋", cx), cx); - 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.ranges(cx), [8..8]); + 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.ranges(cx), [8..8]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "🏀✋🍐"); - assert_eq!(editor.selections.ranges(cx), [11..11]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "🏀✋🍐"); + assert_eq!(editor.selections.ranges(cx), [11..11]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "🏀🍐✋"); - assert_eq!(editor.selections.ranges(cx), [11..11]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "🏀🍐✋"); + assert_eq!(editor.selections.ranges(cx), [11..11]); - editor - }) - .1; + editor + }); } #[gpui::test] @@ -3132,10 +3177,12 @@ async fn test_paste_multiline(cx: &mut gpui::TestAppContext) { fn test_select_all(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("abc\nde\nfgh", cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("abc\nde\nfgh", cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.select_all(&SelectAll, cx); assert_eq!( @@ -3149,10 +3196,12 @@ fn test_select_all(cx: &mut TestAppContext) { fn test_select_line(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple(&sample_text(6, 5, 'a'), cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple(&sample_text(6, 5, 'a'), cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -3196,10 +3245,12 @@ fn test_select_line(cx: &mut TestAppContext) { fn test_split_selection_into_lines(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple(&sample_text(9, 5, 'a'), cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple(&sample_text(9, 5, 'a'), cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.fold_ranges( vec![ @@ -3267,10 +3318,12 @@ fn test_split_selection_into_lines(cx: &mut TestAppContext) { fn test_add_selection_above_below(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, view) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("abc\ndefghi\n\njk\nlmno\n", cx); - build_editor(buffer, cx) - }); + let view = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("abc\ndefghi\n\njk\nlmno\n", cx); + build_editor(buffer, cx) + }) + .detach(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { @@ -3555,7 +3608,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let (_, view) = cx.add_window(|cx| build_editor(buffer, cx)); + let view = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; @@ -3718,7 +3771,7 @@ async fn test_autoindent_selections(cx: &mut gpui::TestAppContext) { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let (_, editor) = cx.add_window(|cx| build_editor(buffer, cx)); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); editor .condition(cx, |editor, cx| !editor.buffer.read(cx).is_parsing(cx)) .await; @@ -4281,7 +4334,7 @@ async fn test_surround_with_pair(cx: &mut gpui::TestAppContext) { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let (_, view) = cx.add_window(|cx| build_editor(buffer, cx)); + let view = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; @@ -4429,7 +4482,7 @@ async fn test_delete_autoclose_pair(cx: &mut gpui::TestAppContext) { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let (_, editor) = cx.add_window(|cx| build_editor(buffer, cx)); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); editor .condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; @@ -4519,7 +4572,7 @@ async fn test_snippets(cx: &mut gpui::TestAppContext) { ); let buffer = cx.update(|cx| MultiBuffer::build_simple(&text, cx)); - let (_, editor) = cx.add_window(|cx| build_editor(buffer, cx)); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); editor.update(cx, |editor, cx| { let snippet = Snippet::parse("f(${1:one}, ${2:two}, ${1:three})$0").unwrap(); @@ -4649,7 +4702,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) { let fake_server = fake_servers.next().await.unwrap(); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let (_, editor) = cx.add_window(|cx| build_editor(buffer, cx)); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); assert!(cx.read(|cx| editor.is_dirty(cx))); @@ -4761,7 +4814,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) { let fake_server = fake_servers.next().await.unwrap(); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let (_, editor) = cx.add_window(|cx| build_editor(buffer, cx)); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); assert!(cx.read(|cx| editor.is_dirty(cx))); @@ -4875,7 +4928,7 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) { let fake_server = fake_servers.next().await.unwrap(); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let (_, editor) = cx.add_window(|cx| build_editor(buffer, cx)); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); let format = editor.update(cx, |editor, cx| { @@ -5653,7 +5706,7 @@ fn test_editing_disjoint_excerpts(cx: &mut TestAppContext) { multibuffer }); - let (_, view) = cx.add_window(|cx| build_editor(multibuffer, cx)); + let view = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx); view.update(cx, |view, cx| { assert_eq!(view.text(cx), "aaaa\nbbbb"); view.change_selections(None, cx, |s| { @@ -5723,7 +5776,7 @@ fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) { multibuffer }); - let (_, view) = cx.add_window(|cx| build_editor(multibuffer, cx)); + let view = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx); view.update(cx, |view, cx| { let (expected_text, selection_ranges) = marked_text_ranges( indoc! {" @@ -5799,22 +5852,24 @@ fn test_refresh_selections(cx: &mut TestAppContext) { multibuffer }); - let (_, editor) = cx.add_window(|cx| { - let mut editor = build_editor(multibuffer.clone(), cx); - let snapshot = editor.snapshot(cx); - 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!( - editor.selections.ranges(cx), - [ - Point::new(1, 3)..Point::new(1, 3), - Point::new(2, 1)..Point::new(2, 1), - ] - ); - editor - }); + let editor = cx + .add_window(|cx| { + let mut editor = build_editor(multibuffer.clone(), cx); + let snapshot = editor.snapshot(cx); + 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!( + editor.selections.ranges(cx), + [ + Point::new(1, 3)..Point::new(1, 3), + Point::new(2, 1)..Point::new(2, 1), + ] + ); + editor + }) + .detach(cx); // Refreshing selections is a no-op when excerpts haven't changed. editor.update(cx, |editor, cx| { @@ -5884,16 +5939,18 @@ fn test_refresh_selections_while_selecting_with_mouse(cx: &mut TestAppContext) { multibuffer }); - let (_, editor) = cx.add_window(|cx| { - let mut editor = build_editor(multibuffer.clone(), cx); - let snapshot = editor.snapshot(cx); - editor.begin_selection(Point::new(1, 3).to_display_point(&snapshot), false, 1, cx); - assert_eq!( - editor.selections.ranges(cx), - [Point::new(1, 3)..Point::new(1, 3)] - ); - editor - }); + let editor = cx + .add_window(|cx| { + let mut editor = build_editor(multibuffer.clone(), cx); + let snapshot = editor.snapshot(cx); + editor.begin_selection(Point::new(1, 3).to_display_point(&snapshot), false, 1, cx); + assert_eq!( + editor.selections.ranges(cx), + [Point::new(1, 3)..Point::new(1, 3)] + ); + editor + }) + .detach(cx); multibuffer.update(cx, |multibuffer, cx| { multibuffer.remove_excerpts([excerpt1_id.unwrap()], cx); @@ -5956,7 +6013,7 @@ async fn test_extra_newline_insertion(cx: &mut gpui::TestAppContext) { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let (_, view) = cx.add_window(|cx| build_editor(buffer, cx)); + let view = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; @@ -5992,10 +6049,12 @@ async fn test_extra_newline_insertion(cx: &mut gpui::TestAppContext) { fn test_highlighted_ranges(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, editor) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple(&sample_text(16, 8, 'a'), cx); - build_editor(buffer.clone(), cx) - }); + let editor = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple(&sample_text(16, 8, 'a'), cx); + build_editor(buffer.clone(), cx) + }) + .detach(cx); editor.update(cx, |editor, cx| { struct Type1; @@ -6084,16 +6143,20 @@ async fn test_following(cx: &mut gpui::TestAppContext) { .unwrap(); cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)) }); - let (_, leader) = cx.add_window(|cx| build_editor(buffer.clone(), cx)); - let (_, follower) = cx.update(|cx| { - cx.add_window( - WindowOptions { - bounds: WindowBounds::Fixed(RectF::from_points(vec2f(0., 0.), vec2f(10., 80.))), - ..Default::default() - }, - |cx| build_editor(buffer.clone(), cx), - ) - }); + let leader = cx + .add_window(|cx| build_editor(buffer.clone(), cx)) + .detach(cx); + let follower = cx + .update(|cx| { + cx.add_window( + WindowOptions { + bounds: WindowBounds::Fixed(RectF::from_points(vec2f(0., 0.), vec2f(10., 80.))), + ..Default::default() + }, + |cx| build_editor(buffer.clone(), cx), + ) + }) + .detach(cx); let is_still_following = Rc::new(RefCell::new(true)); let follower_edit_event_count = Rc::new(RefCell::new(0)); @@ -6224,7 +6287,9 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, ["/file.rs".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); let leader = pane.update(cx, |_, cx| { @@ -6968,7 +7033,7 @@ async fn test_copilot_multibuffer( ); multibuffer }); - let (_, editor) = cx.add_window(|cx| build_editor(multibuffer, cx)); + let editor = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx); handle_copilot_completion_request( &copilot_lsp, @@ -7098,7 +7163,7 @@ async fn test_copilot_disabled_globs( ); multibuffer }); - let (_, editor) = cx.add_window(|cx| build_editor(multibuffer, cx)); + let editor = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx); let mut copilot_requests = copilot_lsp .handle_request::(move |_params, _cx| async move { @@ -7177,7 +7242,9 @@ async fn test_on_type_formatting_not_triggered(cx: &mut gpui::TestAppContext) { .await; let project = Project::test(fs, ["/a".as_ref()], cx).await; project.update(cx, |project, _| project.languages().add(Arc::new(language))); - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() @@ -7282,7 +7349,7 @@ async fn test_language_server_restart_due_to_settings_change(cx: &mut gpui::Test .await; let project = Project::test(fs, ["/a".as_ref()], cx).await; project.update(cx, |project, _| project.languages().add(Arc::new(language))); - let (_, _workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let _window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let _buffer = project .update(cx, |project, cx| { project.open_local_buffer("/a/main.rs", cx) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 750beaea1380ee676c15a3d895c633a91bbe6c12..dc40e7fb8568aeec2bf5d4fe6f4168e4847c3558 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -3002,10 +3002,12 @@ mod tests { fn test_layout_line_numbers(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, editor) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx); - Editor::new(EditorMode::Full, buffer, None, None, cx) - }); + let editor = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx); + Editor::new(EditorMode::Full, buffer, None, None, cx) + }) + .detach(cx); let element = EditorElement::new(editor.read_with(cx, |editor, cx| editor.style(cx))); let layouts = editor.update(cx, |editor, cx| { @@ -3021,10 +3023,12 @@ mod tests { fn test_layout_with_placeholder_text_and_blocks(cx: &mut TestAppContext) { init_test(cx, |_| {}); - let (_, editor) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple("", cx); - Editor::new(EditorMode::Full, buffer, None, None, cx) - }); + let editor = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple("", cx); + Editor::new(EditorMode::Full, buffer, None, None, cx) + }) + .detach(cx); editor.update(cx, |editor, cx| { editor.set_placeholder_text("hello", cx); @@ -3231,10 +3235,12 @@ mod tests { info!( "Creating editor with mode {editor_mode:?}, width {editor_width} and text '{input_text}'" ); - let (_, editor) = cx.add_window(|cx| { - let buffer = MultiBuffer::build_simple(&input_text, cx); - Editor::new(editor_mode, buffer, None, None, cx) - }); + let editor = cx + .add_window(|cx| { + let buffer = MultiBuffer::build_simple(&input_text, cx); + Editor::new(editor_mode, buffer, None, None, cx) + }) + .detach(cx); let mut element = EditorElement::new(editor.read_with(cx, |editor, cx| editor.style(cx))); let (_, layout_state) = editor.update(cx, |editor, cx| { diff --git a/crates/editor/src/inlay_hint_cache.rs b/crates/editor/src/inlay_hint_cache.rs index 63076ba234d52c53556bb9fc9a8a43acbf314a96..089cbb29958c727a0b7760018833a279534a225a 100644 --- a/crates/editor/src/inlay_hint_cache.rs +++ b/crates/editor/src/inlay_hint_cache.rs @@ -1136,7 +1136,9 @@ mod tests { ) .await; let project = Project::test(fs, ["/a".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() @@ -1836,7 +1838,9 @@ mod tests { .await; let project = Project::test(fs, ["/a".as_ref()], cx).await; project.update(cx, |project, _| project.languages().add(Arc::new(language))); - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() @@ -1989,7 +1993,9 @@ mod tests { project.update(cx, |project, _| { project.languages().add(Arc::clone(&language)) }); - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() @@ -2075,8 +2081,9 @@ mod tests { deterministic.run_until_parked(); cx.foreground().run_until_parked(); - let (_, editor) = - cx.add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx)); + let editor = cx + .add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx)) + .detach(cx); let editor_edited = Arc::new(AtomicBool::new(false)); let fake_server = fake_servers.next().await.unwrap(); let closure_editor_edited = Arc::clone(&editor_edited); @@ -2328,7 +2335,9 @@ all hints should be invalidated and requeried for all of its visible excerpts" project.update(cx, |project, _| { project.languages().add(Arc::clone(&language)) }); - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() @@ -2373,8 +2382,9 @@ all hints should be invalidated and requeried for all of its visible excerpts" deterministic.run_until_parked(); cx.foreground().run_until_parked(); - let (_, editor) = - cx.add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx)); + let editor = cx + .add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx)) + .detach(cx); let editor_edited = Arc::new(AtomicBool::new(false)); let fake_server = fake_servers.next().await.unwrap(); let closure_editor_edited = Arc::clone(&editor_edited); @@ -2562,7 +2572,9 @@ all hints should be invalidated and requeried for all of its visible excerpts" let project = Project::test(fs, ["/a".as_ref()], cx).await; project.update(cx, |project, _| project.languages().add(Arc::new(language))); - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() diff --git a/crates/editor/src/test/editor_lsp_test_context.rs b/crates/editor/src/test/editor_lsp_test_context.rs index 0fe49d4d0462216b28ea9273e9490e96a7bc3a9d..f53115f224a1cfe6cb4a3c634786c7e7e8c18305 100644 --- a/crates/editor/src/test/editor_lsp_test_context.rs +++ b/crates/editor/src/test/editor_lsp_test_context.rs @@ -69,7 +69,8 @@ impl<'a> EditorLspTestContext<'a> { .insert_tree("/root", json!({ "dir": { file_name.clone(): "" }})) .await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); project .update(cx, |project, cx| { project.find_or_create_local_worktree("/root", true, cx) @@ -98,7 +99,7 @@ impl<'a> EditorLspTestContext<'a> { Self { cx: EditorTestContext { cx, - window_id, + window_id: window.id(), editor, }, lsp, diff --git a/crates/editor/src/test/editor_test_context.rs b/crates/editor/src/test/editor_test_context.rs index bac70f139a6be8732e9b2b8bde9bce2b63144418..c7ea1b4f3852301e300c5ff3f1db1dff65f342a2 100644 --- a/crates/editor/src/test/editor_test_context.rs +++ b/crates/editor/src/test/editor_test_context.rs @@ -32,16 +32,14 @@ impl<'a> EditorTestContext<'a> { let buffer = project .update(cx, |project, cx| project.create_buffer("", None, cx)) .unwrap(); - let (window_id, editor) = cx.update(|cx| { - cx.add_window(Default::default(), |cx| { - cx.focus_self(); - build_editor(MultiBuffer::build_from_buffer(buffer, cx), cx) - }) + let window = cx.add_window(|cx| { + cx.focus_self(); + build_editor(MultiBuffer::build_from_buffer(buffer, cx), cx) }); - + let editor = window.root(cx); Self { cx, - window_id, + window_id: window.id(), editor, } } diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index b6701f12d6eb057d6bb7e8ae2a91fca3dbe37f58..2c9d9c0c71e390c256e7db785ee06d707039a8a1 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -617,8 +617,9 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); - cx.dispatch_action(window_id, Toggle); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + cx.dispatch_action(window.id(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); finder @@ -631,8 +632,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window_id, SelectNext); - cx.dispatch_action(window_id, Confirm); + cx.dispatch_action(window.id(), SelectNext); + cx.dispatch_action(window.id(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -671,8 +672,9 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); - cx.dispatch_action(window_id, Toggle); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + cx.dispatch_action(window.id(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); let file_query = &first_file_name[..3]; @@ -704,8 +706,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window_id, SelectNext); - cx.dispatch_action(window_id, Confirm); + cx.dispatch_action(window.id(), SelectNext); + cx.dispatch_action(window.id(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -754,8 +756,9 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); - cx.dispatch_action(window_id, Toggle); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + cx.dispatch_action(window.id(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); let file_query = &first_file_name[..3]; @@ -787,8 +790,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window_id, SelectNext); - cx.dispatch_action(window_id, Confirm); + cx.dispatch_action(window.id(), SelectNext); + cx.dispatch_action(window.id(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -837,19 +840,23 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/dir".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); - let (_, finder) = cx.add_window(|cx| { - Picker::new( - FileFinderDelegate::new( - workspace.downgrade(), - workspace.read(cx).project().clone(), - None, - Vec::new(), + let workspace = cx + .add_window(|cx| Workspace::test_new(project, cx)) + .detach(cx); + let finder = cx + .add_window(|cx| { + Picker::new( + FileFinderDelegate::new( + workspace.downgrade(), + workspace.read(cx).project().clone(), + None, + Vec::new(), + cx, + ), cx, - ), - cx, - ) - }); + ) + }) + .detach(cx); let query = test_path_like("hi"); finder @@ -931,19 +938,23 @@ mod tests { cx, ) .await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); - let (_, finder) = cx.add_window(|cx| { - Picker::new( - FileFinderDelegate::new( - workspace.downgrade(), - workspace.read(cx).project().clone(), - None, - Vec::new(), + let workspace = cx + .add_window(|cx| Workspace::test_new(project, cx)) + .detach(cx); + let finder = cx + .add_window(|cx| { + Picker::new( + FileFinderDelegate::new( + workspace.downgrade(), + workspace.read(cx).project().clone(), + None, + Vec::new(), + cx, + ), cx, - ), - cx, - ) - }); + ) + }) + .detach(cx); finder .update(cx, |f, cx| { f.delegate_mut().spawn_search(test_path_like("hi"), cx) @@ -967,19 +978,23 @@ mod tests { cx, ) .await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); - let (_, finder) = cx.add_window(|cx| { - Picker::new( - FileFinderDelegate::new( - workspace.downgrade(), - workspace.read(cx).project().clone(), - None, - Vec::new(), + let workspace = cx + .add_window(|cx| Workspace::test_new(project, cx)) + .detach(cx); + let finder = cx + .add_window(|cx| { + Picker::new( + FileFinderDelegate::new( + workspace.downgrade(), + workspace.read(cx).project().clone(), + None, + Vec::new(), + cx, + ), cx, - ), - cx, - ) - }); + ) + }) + .detach(cx); // Even though there is only one worktree, that worktree's filename // is included in the matching, because the worktree is a single file. @@ -1015,61 +1030,6 @@ mod tests { finder.read_with(cx, |f, _| assert_eq!(f.delegate().matches.len(), 0)); } - #[gpui::test] - async fn test_multiple_matches_with_same_relative_path(cx: &mut TestAppContext) { - let app_state = init_test(cx); - app_state - .fs - .as_fake() - .insert_tree( - "/root", - json!({ - "dir1": { "a.txt": "" }, - "dir2": { "a.txt": "" } - }), - ) - .await; - - let project = Project::test( - app_state.fs.clone(), - ["/root/dir1".as_ref(), "/root/dir2".as_ref()], - cx, - ) - .await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); - - let (_, finder) = cx.add_window(|cx| { - Picker::new( - FileFinderDelegate::new( - workspace.downgrade(), - workspace.read(cx).project().clone(), - None, - Vec::new(), - cx, - ), - cx, - ) - }); - - // Run a search that matches two files with the same relative path. - finder - .update(cx, |f, cx| { - f.delegate_mut().spawn_search(test_path_like("a.t"), cx) - }) - .await; - - // Can switch between different matches with the same relative path. - finder.update(cx, |finder, cx| { - let delegate = finder.delegate_mut(); - assert_eq!(delegate.matches.len(), 2); - assert_eq!(delegate.selected_index(), 0); - delegate.set_selected_index(1, cx); - assert_eq!(delegate.selected_index(), 1); - delegate.set_selected_index(0, cx); - assert_eq!(delegate.selected_index(), 0); - }); - } - #[gpui::test] async fn test_path_distance_ordering(cx: &mut TestAppContext) { let app_state = init_test(cx); @@ -1089,7 +1049,9 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project, cx)) + .detach(cx); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1); @@ -1103,18 +1065,20 @@ mod tests { worktree_id, path: Arc::from(Path::new("/root/dir2/b.txt")), })); - let (_, finder) = cx.add_window(|cx| { - Picker::new( - FileFinderDelegate::new( - workspace.downgrade(), - workspace.read(cx).project().clone(), - b_path, - Vec::new(), + let finder = cx + .add_window(|cx| { + Picker::new( + FileFinderDelegate::new( + workspace.downgrade(), + workspace.read(cx).project().clone(), + b_path, + Vec::new(), + cx, + ), cx, - ), - cx, - ) - }); + ) + }) + .detach(cx); finder .update(cx, |f, cx| { @@ -1151,19 +1115,23 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); - let (_, finder) = cx.add_window(|cx| { - Picker::new( - FileFinderDelegate::new( - workspace.downgrade(), - workspace.read(cx).project().clone(), - None, - Vec::new(), + let workspace = cx + .add_window(|cx| Workspace::test_new(project, cx)) + .detach(cx); + let finder = cx + .add_window(|cx| { + Picker::new( + FileFinderDelegate::new( + workspace.downgrade(), + workspace.read(cx).project().clone(), + None, + Vec::new(), + cx, + ), cx, - ), - cx, - ) - }); + ) + }) + .detach(cx); finder .update(cx, |f, cx| { f.delegate_mut().spawn_search(test_path_like("dir"), cx) @@ -1198,7 +1166,9 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + let window_id = window.id(); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1); @@ -1404,7 +1374,9 @@ mod tests { .detach(); deterministic.run_until_parked(); - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + let window_id = window.id(); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1,); diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 9c0e50647c6138fc94ee388220cb65d0112e3dd6..45169ed3af4af5e8f6806c3aaefcaa0f422a6059 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1424,7 +1424,7 @@ impl AppContext { &mut self, window_id: usize, build_root_view: F, - ) -> Option> + ) -> Option> where V: View, F: FnOnce(&mut ViewContext) -> V, @@ -3826,6 +3826,15 @@ impl WindowHandle { self.read_with(cx, |cx| cx.root_view().clone().downcast().unwrap()) } + /// Keep this window open until it's explicitly closed. + // + // TODO: Implement window dropping behavior when we don't call this. + pub fn detach(mut self, cx: &impl BorrowAppContext) -> ViewHandle { + let root = self.root(cx); + self.any_handle.ref_counts.take(); + root + } + pub fn read_with(&self, cx: &C, read: F) -> R where C: BorrowAppContext, @@ -3893,7 +3902,7 @@ impl WindowHandle { pub struct AnyWindowHandle { window_id: usize, root_view_type: TypeId, - ref_counts: Arc>, + ref_counts: Option>>, #[cfg(any(test, feature = "test-support"))] handle_id: usize, @@ -3913,7 +3922,7 @@ impl AnyWindowHandle { Self { window_id, root_view_type: TypeId::of::(), - ref_counts, + ref_counts: Some(ref_counts), #[cfg(any(test, feature = "test-support"))] handle_id, } @@ -3937,7 +3946,16 @@ impl AnyWindowHandle { impl Drop for AnyWindowHandle { fn drop(&mut self) { - self.ref_counts.lock().dec_window(self.window_id) + if let Some(ref_counts) = self.ref_counts.as_ref() { + ref_counts.lock().dec_window(self.window_id); + + #[cfg(any(test, feature = "test-support"))] + ref_counts + .lock() + .leak_detector + .lock() + .handle_dropped(self.window_id, self.handle_id); + } } } diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 9dc5d99bc5e8ac0b0994aae8b66169151d9b0b93..7cdcbc2c8fc593452fcc9025fc71545eda3f5ceb 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -15,7 +15,7 @@ use crate::{ util::post_inc, Action, AnyView, AnyViewHandle, AppContext, BorrowAppContext, BorrowWindowContext, Effect, Element, Entity, Handle, LayoutContext, MouseRegion, MouseRegionId, SceneBuilder, Subscription, - View, ViewContext, ViewHandle, WindowInvalidation, + View, ViewContext, ViewHandle, WindowHandle, WindowInvalidation, }; use anyhow::{anyhow, bail, Result}; use collections::{HashMap, HashSet}; @@ -1151,15 +1151,15 @@ impl<'a> WindowContext<'a> { self.window.platform_window.prompt(level, msg, answers) } - pub fn replace_root_view(&mut self, build_root_view: F) -> ViewHandle + pub fn replace_root_view(&mut self, build_root_view: F) -> WindowHandle where V: View, F: FnOnce(&mut ViewContext) -> V, { let root_view = self.add_view(|cx| build_root_view(cx)); - self.window.root_view = Some(root_view.clone().into_any()); self.window.focused_view_id = Some(root_view.id()); - root_view + self.window.root_view = Some(root_view.into_any()); + WindowHandle::new(self.window_id, self.ref_counts.clone()) } pub fn add_view(&mut self, build_view: F) -> ViewHandle diff --git a/crates/language_tools/src/lsp_log_tests.rs b/crates/language_tools/src/lsp_log_tests.rs index d4a16b5758a2a905c0e621b368a9653114828ec4..ce05a417ad8fc6cebc61ee236d2289b8b73e2170 100644 --- a/crates/language_tools/src/lsp_log_tests.rs +++ b/crates/language_tools/src/lsp_log_tests.rs @@ -61,7 +61,9 @@ async fn test_lsp_logs(cx: &mut TestAppContext) { .receive_notification::() .await; - let (_, log_view) = cx.add_window(|cx| LspLogView::new(project.clone(), log_store.clone(), cx)); + let log_view = cx + .add_window(|cx| LspLogView::new(project.clone(), log_store.clone(), cx)) + .detach(cx); language_server.notify::(lsp::LogMessageParams { message: "hello from the server".into(), diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 0be52646e631ef1446f168dc3ecf1ce7b9ef0075..fdc5ea108a812459f374fdd0a1386fe31bb9830a 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1780,7 +1780,9 @@ mod tests { .await; let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); assert_eq!( visible_entries_as_strings(&panel, 0..50, cx), @@ -1868,7 +1870,9 @@ mod tests { .await; let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); + let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "root1", cx); @@ -2219,7 +2223,9 @@ mod tests { .await; let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); + let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "root1", cx); @@ -2319,7 +2325,9 @@ mod tests { .await; let project = Project::test(fs.clone(), ["/root1".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); panel.update(cx, |panel, cx| { @@ -2392,7 +2400,9 @@ mod tests { .await; let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); + let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); toggle_expand_dir(&panel, "src/test", cx); @@ -2481,7 +2491,9 @@ mod tests { .await; let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); + let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "src/", cx); @@ -2627,7 +2639,9 @@ mod tests { .await; let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); let new_search_events_count = Arc::new(AtomicUsize::new(0)); @@ -2714,7 +2728,9 @@ mod tests { .await; let project = Project::test(fs.clone(), ["/project_root".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); panel.update(cx, |panel, cx| { diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index cbf914230d3b316370083b2cdcb3535631344dba..8471f3a3a7014d2034438839f76ae9b4214ded52 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -326,7 +326,9 @@ mod tests { }, ); - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); + let window_id = window.id(); // Create the project symbols view. let symbols = cx.add_view(window_id, |cx| { diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 45842aa5617b4f87cf306aebdead2d9ae96d455f..1e635432bd5c138f81410f3ac40ee461830ddb17 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -849,11 +849,13 @@ mod tests { cx, ) }); - let (window_id, _root_view) = cx.add_window(|_| EmptyView); + let window = cx.add_window(|_| EmptyView); - let editor = cx.add_view(window_id, |cx| Editor::for_buffer(buffer.clone(), None, cx)); + let editor = cx.add_view(window.id(), |cx| { + Editor::for_buffer(buffer.clone(), None, cx) + }); - let search_bar = cx.add_view(window_id, |cx| { + let search_bar = cx.add_view(window.id(), |cx| { let mut search_bar = BufferSearchBar::new(cx); search_bar.set_active_pane_item(Some(&editor), cx); search_bar.show(cx); @@ -1229,7 +1231,8 @@ mod tests { "Should pick a query with multiple results" ); let buffer = cx.add_model(|cx| Buffer::new(0, buffer_text, cx)); - let (window_id, _root_view) = cx.add_window(|_| EmptyView); + let window = cx.add_window(|_| EmptyView); + let window_id = window.id(); let editor = cx.add_view(window_id, |cx| Editor::for_buffer(buffer.clone(), None, cx)); @@ -1416,11 +1419,13 @@ mod tests { "# .unindent(); let buffer = cx.add_model(|cx| Buffer::new(0, buffer_text, cx)); - let (window_id, _root_view) = cx.add_window(|_| EmptyView); + let window = cx.add_window(|_| EmptyView); - let editor = cx.add_view(window_id, |cx| Editor::for_buffer(buffer.clone(), None, cx)); + let editor = cx.add_view(window.id(), |cx| { + Editor::for_buffer(buffer.clone(), None, cx) + }); - let search_bar = cx.add_view(window_id, |cx| { + let search_bar = cx.add_view(window.id(), |cx| { let mut search_bar = BufferSearchBar::new(cx); search_bar.set_active_pane_item(Some(&editor), cx); search_bar.show(cx); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 1b4e32f4b832483c160293a5d792b39d62a1a628..e57edd3b14709aea1056965b59e173bc9e404a23 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1447,7 +1447,9 @@ pub mod tests { .await; let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let search = cx.add_model(|cx| ProjectSearch::new(project, cx)); - let (_, search_view) = cx.add_window(|cx| ProjectSearchView::new(search.clone(), cx)); + let search_view = cx + .add_window(|cx| ProjectSearchView::new(search.clone(), cx)) + .detach(cx); search_view.update(cx, |search_view, cx| { search_view @@ -1564,7 +1566,9 @@ pub mod tests { ) .await; let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + let window_id = window.id(); let active_item = cx.read(|cx| { workspace @@ -1748,7 +1752,9 @@ pub mod tests { let worktree_id = project.read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() }); - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project, cx)) + .detach(cx); let active_item = cx.read(|cx| { workspace @@ -1866,7 +1872,9 @@ pub mod tests { ) .await; let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + let window_id = window.id(); workspace.update(cx, |workspace, cx| { ProjectSearchView::deploy(workspace, &workspace::NewSearch, cx) }); diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index e108a05ccc00bf3a47127c0ced234f0cc4dd332b..874978b4fc567526e6bd17d4f6edd3fa9a670c3c 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -1070,7 +1070,9 @@ mod tests { }); let project = Project::test(params.fs.clone(), [], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); (project, workspace) } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index ee658c9cc92b3a4fa24a56f986e895547a190ad1..98883fac3372246d462585be76eb0bfd1a20bbae 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -1972,7 +1972,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, None, cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); pane.update(cx, |pane, cx| { @@ -1987,7 +1988,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, None, cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); // 1. Add with a destination index @@ -2065,7 +2067,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, None, cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); // 1. Add with a destination index @@ -2141,7 +2144,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, None, cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); // singleton view @@ -2209,7 +2213,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, None, cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); add_labeled_item(&pane, "A", false, cx); @@ -2256,7 +2261,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, None, cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx); @@ -2276,7 +2282,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, None, cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); add_labeled_item(&pane, "A", true, cx); @@ -2299,7 +2306,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, None, cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx); @@ -2319,7 +2327,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, None, cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx); @@ -2339,7 +2348,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, None, cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); add_labeled_item(&pane, "A", false, cx); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 434975216ad977df75cdd960f27fdb6ed4306f02..3222ea2eb8cab97976c81ad6ad5c43668cf46655 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -793,7 +793,7 @@ impl Workspace { DB.next_id().await.unwrap_or(0) }; - let workspace = requesting_window_id + let window = requesting_window_id .and_then(|window_id| { cx.update(|cx| { cx.replace_root_view(window_id, |cx| { @@ -852,9 +852,9 @@ impl Workspace { ) }, ) - .1 }); + let workspace = window.root(&cx); (app_state.initialize_workspace)( workspace.downgrade(), serialized_workspace.is_some(), @@ -864,7 +864,7 @@ impl Workspace { .await .log_err(); - cx.update_window(workspace.window_id(), |cx| cx.activate_window()); + window.update(&mut cx, |cx| cx.activate_window()); let workspace = workspace.downgrade(); notify_if_database_failed(&workspace, &mut cx); @@ -3977,7 +3977,7 @@ pub fn join_remote_project( .await?; let window_bounds_override = window_bounds_env_override(&cx); - let (_, workspace) = cx.add_window( + let window = cx.add_window( (app_state.build_window_options)( window_bounds_override, None, @@ -3985,6 +3985,7 @@ pub fn join_remote_project( ), |cx| Workspace::new(0, project, app_state.clone(), cx), ); + let workspace = window.root(&cx); (app_state.initialize_workspace)( workspace.downgrade(), false, @@ -4113,10 +4114,11 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, [], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); // Adding an item with no ambiguity renders the tab without detail. - let item1 = cx.add_view(window_id, |_| { + let item1 = window.add_view(cx, |_| { let mut item = TestItem::new(); item.tab_descriptions = Some(vec!["c", "b1/c", "a/b1/c"]); item @@ -4128,7 +4130,7 @@ mod tests { // Adding an item that creates ambiguity increases the level of detail on // both tabs. - let item2 = cx.add_view(window_id, |_| { + let item2 = window.add_view(cx, |_| { let mut item = TestItem::new(); item.tab_descriptions = Some(vec!["c", "b2/c", "a/b2/c"]); item @@ -4142,7 +4144,7 @@ mod tests { // Adding an item that creates ambiguity increases the level of detail only // on the ambiguous tabs. In this case, the ambiguity can't be resolved so // we stop at the highest detail available. - let item3 = cx.add_view(window_id, |_| { + let item3 = window.add_view(cx, |_| { let mut item = TestItem::new(); item.tab_descriptions = Some(vec!["c", "b2/c", "a/b2/c"]); item @@ -4177,16 +4179,17 @@ mod tests { .await; let project = Project::test(fs, ["root1".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); let worktree_id = project.read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() }); - let item1 = cx.add_view(window_id, |cx| { + let item1 = window.add_view(cx, |cx| { TestItem::new().with_project_items(&[TestProjectItem::new(1, "one.txt", cx)]) }); - let item2 = cx.add_view(window_id, |cx| { + let item2 = window.add_view(cx, |cx| { TestItem::new().with_project_items(&[TestProjectItem::new(2, "two.txt", cx)]) }); @@ -4201,14 +4204,14 @@ mod tests { ); }); assert_eq!( - cx.current_window_title(window_id).as_deref(), + cx.current_window_title(window.id()).as_deref(), Some("one.txt — root1") ); // Add a second item to a non-empty pane workspace.update(cx, |workspace, cx| workspace.add_item(Box::new(item2), cx)); assert_eq!( - cx.current_window_title(window_id).as_deref(), + cx.current_window_title(window.id()).as_deref(), Some("two.txt — root1") ); project.read_with(cx, |project, cx| { @@ -4227,7 +4230,7 @@ mod tests { .await .unwrap(); assert_eq!( - cx.current_window_title(window_id).as_deref(), + cx.current_window_title(window.id()).as_deref(), Some("one.txt — root1") ); project.read_with(cx, |project, cx| { @@ -4247,14 +4250,14 @@ mod tests { .await .unwrap(); assert_eq!( - cx.current_window_title(window_id).as_deref(), + cx.current_window_title(window.id()).as_deref(), Some("one.txt — root1, root2") ); // Remove a project folder project.update(cx, |project, cx| project.remove_worktree(worktree_id, cx)); assert_eq!( - cx.current_window_title(window_id).as_deref(), + cx.current_window_title(window.id()).as_deref(), Some("one.txt — root2") ); } @@ -4267,18 +4270,19 @@ mod tests { fs.insert_tree("/root", json!({ "one": "" })).await; let project = Project::test(fs, ["root".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = window.root(cx); // When there are no dirty items, there's nothing to do. - let item1 = cx.add_view(window_id, |_| TestItem::new()); + let item1 = window.add_view(cx, |_| TestItem::new()); workspace.update(cx, |w, cx| w.add_item(Box::new(item1.clone()), cx)); let task = workspace.update(cx, |w, cx| w.prepare_to_close(false, cx)); assert!(task.await.unwrap()); // When there are dirty untitled items, prompt to save each one. If the user // cancels any prompt, then abort. - let item2 = cx.add_view(window_id, |_| TestItem::new().with_dirty(true)); - let item3 = cx.add_view(window_id, |cx| { + let item2 = window.add_view(cx, |_| TestItem::new().with_dirty(true)); + let item3 = window.add_view(cx, |cx| { TestItem::new() .with_dirty(true) .with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]) @@ -4289,9 +4293,9 @@ mod tests { }); let task = workspace.update(cx, |w, cx| w.prepare_to_close(false, cx)); cx.foreground().run_until_parked(); - cx.simulate_prompt_answer(window_id, 2 /* cancel */); + cx.simulate_prompt_answer(window.id(), 2 /* cancel */); cx.foreground().run_until_parked(); - assert!(!cx.has_pending_prompt(window_id)); + assert!(!cx.has_pending_prompt(window.id())); assert!(!task.await.unwrap()); } @@ -4302,26 +4306,27 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, None, cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); - let item1 = cx.add_view(window_id, |cx| { + let item1 = window.add_view(cx, |cx| { TestItem::new() .with_dirty(true) .with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]) }); - let item2 = cx.add_view(window_id, |cx| { + let item2 = window.add_view(cx, |cx| { TestItem::new() .with_dirty(true) .with_conflict(true) .with_project_items(&[TestProjectItem::new(2, "2.txt", cx)]) }); - let item3 = cx.add_view(window_id, |cx| { + let item3 = window.add_view(cx, |cx| { TestItem::new() .with_dirty(true) .with_conflict(true) .with_project_items(&[TestProjectItem::new(3, "3.txt", cx)]) }); - let item4 = cx.add_view(window_id, |cx| { + let item4 = window.add_view(cx, |cx| { TestItem::new() .with_dirty(true) .with_project_items(&[TestProjectItem::new_untitled(cx)]) @@ -4349,10 +4354,10 @@ mod tests { assert_eq!(pane.items_len(), 4); assert_eq!(pane.active_item().unwrap().id(), item1.id()); }); - assert!(cx.has_pending_prompt(window_id)); + assert!(cx.has_pending_prompt(window.id())); // Confirm saving item 1. - cx.simulate_prompt_answer(window_id, 0); + cx.simulate_prompt_answer(window.id(), 0); cx.foreground().run_until_parked(); // Item 1 is saved. There's a prompt to save item 3. @@ -4363,10 +4368,10 @@ mod tests { assert_eq!(pane.items_len(), 3); assert_eq!(pane.active_item().unwrap().id(), item3.id()); }); - assert!(cx.has_pending_prompt(window_id)); + assert!(cx.has_pending_prompt(window.id())); // Cancel saving item 3. - cx.simulate_prompt_answer(window_id, 1); + cx.simulate_prompt_answer(window.id(), 1); cx.foreground().run_until_parked(); // Item 3 is reloaded. There's a prompt to save item 4. @@ -4377,10 +4382,10 @@ mod tests { assert_eq!(pane.items_len(), 2); assert_eq!(pane.active_item().unwrap().id(), item4.id()); }); - assert!(cx.has_pending_prompt(window_id)); + assert!(cx.has_pending_prompt(window.id())); // Confirm saving item 4. - cx.simulate_prompt_answer(window_id, 0); + cx.simulate_prompt_answer(window.id(), 0); cx.foreground().run_until_parked(); // There's a prompt for a path for item 4. @@ -4404,13 +4409,14 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, [], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); // Create several workspace items with single project entries, and two // workspace items with multiple project entries. let single_entry_items = (0..=4) .map(|project_entry_id| { - cx.add_view(window_id, |cx| { + window.add_view(cx, |cx| { TestItem::new() .with_dirty(true) .with_project_items(&[TestProjectItem::new( @@ -4421,7 +4427,7 @@ mod tests { }) }) .collect::>(); - let item_2_3 = cx.add_view(window_id, |cx| { + let item_2_3 = window.add_view(cx, |cx| { TestItem::new() .with_dirty(true) .with_singleton(false) @@ -4430,7 +4436,7 @@ mod tests { single_entry_items[3].read(cx).project_items[0].clone(), ]) }); - let item_3_4 = cx.add_view(window_id, |cx| { + let item_3_4 = window.add_view(cx, |cx| { TestItem::new() .with_dirty(true) .with_singleton(false) @@ -4482,7 +4488,7 @@ mod tests { &[ProjectEntryId::from_proto(0)] ); }); - cx.simulate_prompt_answer(window_id, 0); + cx.simulate_prompt_answer(window.id(), 0); cx.foreground().run_until_parked(); left_pane.read_with(cx, |pane, cx| { @@ -4491,7 +4497,7 @@ mod tests { &[ProjectEntryId::from_proto(2)] ); }); - cx.simulate_prompt_answer(window_id, 0); + cx.simulate_prompt_answer(window.id(), 0); cx.foreground().run_until_parked(); close.await.unwrap(); @@ -4507,10 +4513,11 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, [], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - let item = cx.add_view(window_id, |cx| { + let item = window.add_view(cx, |cx| { TestItem::new().with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]) }); let item_id = item.id(); @@ -4550,7 +4557,7 @@ mod tests { item.read_with(cx, |item, _| assert_eq!(item.save_count, 2)); // Deactivating the window still saves the file. - cx.simulate_window_activation(Some(window_id)); + cx.simulate_window_activation(Some(window.id())); item.update(cx, |item, cx| { cx.focus_self(); item.is_dirty = true; @@ -4592,7 +4599,7 @@ mod tests { pane.update(cx, |pane, cx| pane.close_items(cx, move |id| id == item_id)) .await .unwrap(); - assert!(!cx.has_pending_prompt(window_id)); + assert!(!cx.has_pending_prompt(window.id())); item.read_with(cx, |item, _| assert_eq!(item.save_count, 5)); // Add the item again, ensuring autosave is prevented if the underlying file has been deleted. @@ -4613,7 +4620,7 @@ mod tests { let _close_items = pane.update(cx, |pane, cx| pane.close_items(cx, move |id| id == item_id)); deterministic.run_until_parked(); - assert!(cx.has_pending_prompt(window_id)); + assert!(cx.has_pending_prompt(window.id())); item.read_with(cx, |item, _| assert_eq!(item.save_count, 5)); } @@ -4624,9 +4631,10 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, [], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); - let item = cx.add_view(window_id, |cx| { + let item = window.add_view(cx, |cx| { TestItem::new().with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]) }); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); @@ -4677,7 +4685,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, [], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); let panel = workspace.update(cx, |workspace, cx| { let panel = cx.add_view(|_| TestPanel::new(DockPosition::Right)); @@ -4824,7 +4833,8 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, [], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); let (panel_1, panel_2) = workspace.update(cx, |workspace, cx| { // Add panel_1 on the left, panel_2 on the right. @@ -4979,7 +4989,7 @@ mod tests { // If focus is transferred to another view that's not a panel or another pane, we still show // the panel as zoomed. - let focus_receiver = cx.add_view(window_id, |_| EmptyView); + let focus_receiver = window.add_view(cx, |_| EmptyView); focus_receiver.update(cx, |_, cx| cx.focus_self()); workspace.read_with(cx, |workspace, _| { assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any())); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 4b0bf1cd4c6aec42aa2d636b474828ef452cbe03..1770c5648e1fd2f8fe2a5ed31354f5525629a04f 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -983,7 +983,9 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project, cx)) + .detach(cx); let entries = cx.read(|cx| workspace.file_project_paths(cx)); let file1 = entries[0].clone(); @@ -1295,7 +1297,9 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + let window_id = window.id(); // Open a file within an existing worktree. workspace @@ -1336,7 +1340,9 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; project.update(cx, |project, _| project.languages().add(rust_lang())); - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + let window_id = window.id(); let worktree = cx.read(|cx| workspace.read(cx).worktrees(cx).next().unwrap()); // Create a new untitled buffer @@ -1429,7 +1435,9 @@ mod tests { let project = Project::test(app_state.fs.clone(), [], cx).await; project.update(cx, |project, _| project.languages().add(rust_lang())); - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + let window_id = window.id(); // Create a new untitled buffer cx.dispatch_action(window_id, NewFile); @@ -1480,7 +1488,9 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + let window_id = window.id(); let entries = cx.read(|cx| workspace.file_project_paths(cx)); let file1 = entries[0].clone(); @@ -1554,7 +1564,9 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project.clone(), cx)) + .detach(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); let entries = cx.read(|cx| workspace.file_project_paths(cx)); @@ -1831,7 +1843,9 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; - let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = cx + .add_window(|cx| Workspace::test_new(project, cx)) + .detach(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); let entries = cx.read(|cx| workspace.file_project_paths(cx)); @@ -2073,7 +2087,8 @@ mod tests { cx.foreground().run_until_parked(); - let (window_id, _view) = cx.add_window(|_| TestView); + let window = cx.add_window(|_| TestView); + let window_id = window.id(); // Test loading the keymap base at all assert_key_bindings_for( @@ -2243,7 +2258,8 @@ mod tests { cx.foreground().run_until_parked(); - let (window_id, _view) = cx.add_window(|_| TestView); + let window = cx.add_window(|_| TestView); + let window_id = window.id(); // Test loading the keymap base at all assert_key_bindings_for( From 8e36da1382e84c87c5d3576a848eb06645bb21ab Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 2 Aug 2023 15:02:55 -0600 Subject: [PATCH 116/160] Get tests passing --- crates/gpui/src/app.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 45169ed3af4af5e8f6806c3aaefcaa0f422a6059..bd615522c2610ee1d8e76c4675c98d738ef8a460 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -3831,7 +3831,14 @@ impl WindowHandle { // TODO: Implement window dropping behavior when we don't call this. pub fn detach(mut self, cx: &impl BorrowAppContext) -> ViewHandle { let root = self.root(cx); - self.any_handle.ref_counts.take(); + let ref_counts = self.any_handle.ref_counts.take(); + #[cfg(any(test, feature = "test-support"))] + ref_counts + .unwrap() + .lock() + .leak_detector + .lock() + .handle_dropped(self.id(), self.any_handle.handle_id); root } From df4480ba52aede20b416afb87a0b0e17eb025682 Mon Sep 17 00:00:00 2001 From: Julia Date: Wed, 2 Aug 2023 17:33:56 -0400 Subject: [PATCH 117/160] Use the same font size for hovered state of LSP status This element is used for the update state as well for some reason so while we don't normally ever see this state, it is used when the status is acting as the restart to update button --- styles/src/style_tree/status_bar.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/src/style_tree/status_bar.ts b/styles/src/style_tree/status_bar.ts index 6261939994ac4e7ae7e06090912218d5dcfb7f54..d35b721c6cefcc50fc19ea526164ad967fa2578e 100644 --- a/styles/src/style_tree/status_bar.ts +++ b/styles/src/style_tree/status_bar.ts @@ -49,7 +49,7 @@ export default function status_bar(): any { }, state: { hovered: { - message: text(layer, "sans"), + message: text(layer, "sans", { size: "xs" }), icon_color: foreground(layer), background: background(layer, "hovered"), }, From 3c938a7377bbc2a3147f71da53ef05a1f45eaa5a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 3 Aug 2023 08:10:16 -0600 Subject: [PATCH 118/160] WIP --- crates/gpui/src/app.rs | 16 ++++++++++++---- crates/gpui/src/app/test_app_context.rs | 2 ++ crates/gpui/src/app/window.rs | 2 ++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index bd615522c2610ee1d8e76c4675c98d738ef8a460..9b847e9c0cfdea426902ea59e93cec3a0c349fdf 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -130,10 +130,12 @@ pub trait BorrowAppContext { } pub trait BorrowWindowContext { - fn read_with(&self, window_id: usize, f: F) -> T + type Return; + + fn read_with(&self, window_id: usize, f: F) -> Self::Return where F: FnOnce(&WindowContext) -> T; - fn update(&mut self, window_id: usize, f: F) -> T + fn update(&mut self, window_id: usize, f: F) -> Self::Return where F: FnOnce(&mut WindowContext) -> T; } @@ -3358,6 +3360,8 @@ impl BorrowAppContext for ViewContext<'_, '_, V> { } impl BorrowWindowContext for ViewContext<'_, '_, V> { + type Return = T; + fn read_with T>(&self, window_id: usize, f: F) -> T { BorrowWindowContext::read_with(&*self.window_context, window_id, f) } @@ -3463,6 +3467,8 @@ impl BorrowAppContext for LayoutContext<'_, '_, '_, V> { } impl BorrowWindowContext for LayoutContext<'_, '_, '_, V> { + type Return = T; + fn read_with T>(&self, window_id: usize, f: F) -> T { BorrowWindowContext::read_with(&*self.view_context, window_id, f) } @@ -3515,6 +3521,8 @@ impl BorrowAppContext for EventContext<'_, '_, '_, V> { } impl BorrowWindowContext for EventContext<'_, '_, '_, V> { + type Return = T; + fn read_with T>(&self, window_id: usize, f: F) -> T { BorrowWindowContext::read_with(&*self.view_context, window_id, f) } @@ -4013,7 +4021,7 @@ impl ViewHandle { cx.read_view(self) } - pub fn read_with(&self, cx: &C, read: F) -> S + pub fn read_with(&self, cx: &C, read: F) -> C::Return where C: BorrowWindowContext, F: FnOnce(&T, &ViewContext) -> S, @@ -4024,7 +4032,7 @@ impl ViewHandle { }) } - pub fn update(&self, cx: &mut C, update: F) -> S + pub fn update(&self, cx: &mut C, update: F) -> C::Return where C: BorrowWindowContext, F: FnOnce(&mut T, &mut ViewContext) -> S, diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 80f10374665f9c2215ca4b2582088dd43df3bb04..5c7947a44827d3eb23e6a490c7fdfaacd9e90bfb 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -406,6 +406,8 @@ impl BorrowAppContext for TestAppContext { } impl BorrowWindowContext for TestAppContext { + type Return = T; + fn read_with T>(&self, window_id: usize, f: F) -> T { self.cx .borrow() diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 7cdcbc2c8fc593452fcc9025fc71545eda3f5ceb..671d2b38c77c9d71201e77c87fd8ef21d077b24b 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -142,6 +142,8 @@ impl BorrowAppContext for WindowContext<'_> { } impl BorrowWindowContext for WindowContext<'_> { + type Return = T; + fn read_with T>(&self, window_id: usize, f: F) -> T { if self.window_id == window_id { f(self) From ee1b4a52cc41cb7c331ad9936f1c1cbfb220057e Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Thu, 3 Aug 2023 18:57:43 -0400 Subject: [PATCH 119/160] Add `PathExt` trait (#2823) This PR adds a `PathExt` trait. It pulls in our existing `compact()` function, as a method, and then adds a method, and testing, for `icon_suffix()`. A test was added to fix: - https://github.com/zed-industries/community/issues/1877 Release Notes: - Fixed a bug where file icons would not be registered for files with with `.` characters in their name ([#1877](https://github.com/zed-industries/community/issues/1877)). --- crates/editor/src/items.rs | 9 +- crates/project_panel/src/file_associations.rs | 11 +- .../src/highlighted_workspace_location.rs | 3 +- crates/recent_projects/src/recent_projects.rs | 3 +- crates/util/src/paths.rs | 118 ++++++++++++------ 5 files changed, 88 insertions(+), 56 deletions(-) diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 7c8fe12aa068cfd97566142d6436f0ce4f0300d2..b99977a60eb45dc3a0a616169067063e6c4e691f 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -28,7 +28,10 @@ use std::{ path::{Path, PathBuf}, }; use text::Selection; -use util::{paths::FILE_ROW_COLUMN_DELIMITER, ResultExt, TryFutureExt}; +use util::{ + paths::{PathExt, FILE_ROW_COLUMN_DELIMITER}, + ResultExt, TryFutureExt, +}; use workspace::item::{BreadcrumbText, FollowableItemHandle}; use workspace::{ item::{FollowableItem, Item, ItemEvent, ItemHandle, ProjectItem}, @@ -546,9 +549,7 @@ impl Item for Editor { .and_then(|f| f.as_local())? .abs_path(cx); - let file_path = util::paths::compact(&file_path) - .to_string_lossy() - .to_string(); + let file_path = file_path.compact().to_string_lossy().to_string(); Some(file_path.into()) } diff --git a/crates/project_panel/src/file_associations.rs b/crates/project_panel/src/file_associations.rs index 2694fa1697f31d76fb4f37e1632c184ac2e9ce8f..f2692b96db2c317e1fc4d7e96c9d5109ac502258 100644 --- a/crates/project_panel/src/file_associations.rs +++ b/crates/project_panel/src/file_associations.rs @@ -4,7 +4,7 @@ use collections::HashMap; use gpui::{AppContext, AssetSource}; use serde_derive::Deserialize; -use util::iife; +use util::{iife, paths::PathExt}; #[derive(Deserialize, Debug)] struct TypeConfig { @@ -48,14 +48,7 @@ impl FileAssociations { // FIXME: Associate a type with the languages and have the file's langauge // override these associations iife!({ - let suffix = path - .file_name() - .and_then(|os_str| os_str.to_str()) - .and_then(|file_name| { - file_name - .find('.') - .and_then(|dot_index| file_name.get(dot_index + 1..)) - })?; + let suffix = path.icon_suffix()?; this.suffixes .get(suffix) diff --git a/crates/recent_projects/src/highlighted_workspace_location.rs b/crates/recent_projects/src/highlighted_workspace_location.rs index d3ecfb74fb637bf64d283c99ca8d939ec4acd5e3..f915cb24edf89cd1c6f0797e2fc7b5f8c790399f 100644 --- a/crates/recent_projects/src/highlighted_workspace_location.rs +++ b/crates/recent_projects/src/highlighted_workspace_location.rs @@ -5,6 +5,7 @@ use gpui::{ elements::{Label, LabelStyle}, AnyElement, Element, View, }; +use util::paths::PathExt; use workspace::WorkspaceLocation; pub struct HighlightedText { @@ -61,7 +62,7 @@ impl HighlightedWorkspaceLocation { .paths() .iter() .map(|path| { - let path = util::paths::compact(&path); + let path = path.compact(); let highlighted_text = Self::highlights_for_path( path.as_ref(), &string_match.positions, diff --git a/crates/recent_projects/src/recent_projects.rs b/crates/recent_projects/src/recent_projects.rs index 5bf9ba6ccfefb6f89c46a3ed1b934e931d7ce827..7a09ac259f5039ec9ff4f5656ab6b10bd5a3527d 100644 --- a/crates/recent_projects/src/recent_projects.rs +++ b/crates/recent_projects/src/recent_projects.rs @@ -11,6 +11,7 @@ use highlighted_workspace_location::HighlightedWorkspaceLocation; use ordered_float::OrderedFloat; use picker::{Picker, PickerDelegate, PickerEvent}; use std::sync::Arc; +use util::paths::PathExt; use workspace::{ notifications::simple_message_notification::MessageNotification, Workspace, WorkspaceLocation, WORKSPACE_DB, @@ -134,7 +135,7 @@ impl PickerDelegate for RecentProjectsDelegate { let combined_string = location .paths() .iter() - .map(|path| util::paths::compact(&path).to_string_lossy().into_owned()) + .map(|path| path.compact().to_string_lossy().into_owned()) .collect::>() .join(""); StringMatchCandidate::new(id, combined_string) diff --git a/crates/util/src/paths.rs b/crates/util/src/paths.rs index 5df0ed12e96dd13af148bafc1d2682585389cc57..7e0b240570f249b7dc97b17ea0fc85581fd44410 100644 --- a/crates/util/src/paths.rs +++ b/crates/util/src/paths.rs @@ -30,49 +30,47 @@ pub mod legacy { } } -/// Compacts a given file path by replacing the user's home directory -/// prefix with a tilde (`~`). -/// -/// # Arguments -/// -/// * `path` - A reference to a `Path` representing the file path to compact. -/// -/// # Examples -/// -/// ``` -/// use std::path::{Path, PathBuf}; -/// use util::paths::compact; -/// let path: PathBuf = [ -/// util::paths::HOME.to_string_lossy().to_string(), -/// "some_file.txt".to_string(), -/// ] -/// .iter() -/// .collect(); -/// if cfg!(target_os = "linux") || cfg!(target_os = "macos") { -/// assert_eq!(compact(&path).to_str(), Some("~/some_file.txt")); -/// } else { -/// assert_eq!(compact(&path).to_str(), path.to_str()); -/// } -/// ``` -/// -/// # Returns -/// -/// * A `PathBuf` containing the compacted file path. If the input path -/// does not have the user's home directory prefix, or if we are not on -/// Linux or macOS, the original path is returned unchanged. -pub fn compact(path: &Path) -> PathBuf { - if cfg!(target_os = "linux") || cfg!(target_os = "macos") { - match path.strip_prefix(HOME.as_path()) { - Ok(relative_path) => { - let mut shortened_path = PathBuf::new(); - shortened_path.push("~"); - shortened_path.push(relative_path); - shortened_path +pub trait PathExt { + fn compact(&self) -> PathBuf; + fn icon_suffix(&self) -> Option<&str>; +} + +impl> PathExt for T { + /// Compacts a given file path by replacing the user's home directory + /// prefix with a tilde (`~`). + /// + /// # Returns + /// + /// * A `PathBuf` containing the compacted file path. If the input path + /// does not have the user's home directory prefix, or if we are not on + /// Linux or macOS, the original path is returned unchanged. + fn compact(&self) -> PathBuf { + if cfg!(target_os = "linux") || cfg!(target_os = "macos") { + match self.as_ref().strip_prefix(HOME.as_path()) { + Ok(relative_path) => { + let mut shortened_path = PathBuf::new(); + shortened_path.push("~"); + shortened_path.push(relative_path); + shortened_path + } + Err(_) => self.as_ref().to_path_buf(), } - Err(_) => path.to_path_buf(), + } else { + self.as_ref().to_path_buf() } - } else { - path.to_path_buf() + } + + fn icon_suffix(&self) -> Option<&str> { + let file_name = self.as_ref().file_name()?.to_str()?; + + if file_name.starts_with(".") { + return file_name.strip_prefix("."); + } + + self.as_ref() + .extension() + .map(|extension| extension.to_str()) + .flatten() } } @@ -279,4 +277,42 @@ mod tests { ); } } + + #[test] + fn test_path_compact() { + let path: PathBuf = [ + HOME.to_string_lossy().to_string(), + "some_file.txt".to_string(), + ] + .iter() + .collect(); + if cfg!(target_os = "linux") || cfg!(target_os = "macos") { + assert_eq!(path.compact().to_str(), Some("~/some_file.txt")); + } else { + assert_eq!(path.compact().to_str(), path.to_str()); + } + } + + #[test] + fn test_path_suffix() { + // No dots in name + let path = Path::new("/a/b/c/file_name.rs"); + assert_eq!(path.icon_suffix(), Some("rs")); + + // Single dot in name + let path = Path::new("/a/b/c/file.name.rs"); + assert_eq!(path.icon_suffix(), Some("rs")); + + // Multiple dots in name + let path = Path::new("/a/b/c/long.file.name.rs"); + assert_eq!(path.icon_suffix(), Some("rs")); + + // Hidden file, no extension + let path = Path::new("/a/b/c/.gitignore"); + assert_eq!(path.icon_suffix(), Some("gitignore")); + + // Hidden file, with extension + let path = Path::new("/a/b/c/.eslintrc.js"); + assert_eq!(path.icon_suffix(), Some("eslintrc.js")); + } } From afcc0d621b8524d4b3cfa9a5ed19b00c11666348 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 3 Aug 2023 17:03:39 -0600 Subject: [PATCH 120/160] WIP --- crates/editor/src/editor_tests.rs | 98 ++++---- crates/editor/src/element.rs | 6 +- crates/editor/src/inlay_hint_cache.rs | 14 +- crates/file_finder/src/file_finder.rs | 20 +- crates/gpui/src/app.rs | 264 ++++++++++++--------- crates/gpui/src/app/test_app_context.rs | 10 +- crates/gpui/src/app/window.rs | 10 +- crates/language_tools/src/lsp_log_tests.rs | 2 +- crates/project_panel/src/project_panel.rs | 8 +- crates/search/src/project_search.rs | 4 +- crates/terminal_view/src/terminal_view.rs | 2 +- crates/workspace/src/workspace.rs | 108 ++++----- crates/zed/src/zed.rs | 6 +- 13 files changed, 295 insertions(+), 257 deletions(-) diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 96921643d45a1b7c1083dab5df471b3bd95adb2d..a114cd437b16bbad580d6e732bb004ac352d822a 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -64,7 +64,7 @@ fn test_edit_events(cx: &mut TestAppContext) { Editor::for_buffer(buffer.clone(), None, cx) } }) - .detach(cx); + .root(cx); let editor2 = cx .add_window({ let events = events.clone(); @@ -81,7 +81,7 @@ fn test_edit_events(cx: &mut TestAppContext) { Editor::for_buffer(buffer.clone(), None, cx) } }) - .detach(cx); + .root(cx); assert_eq!(mem::take(&mut *events.borrow_mut()), []); // Mutating editor 1 will emit an `Edited` event only for that editor. @@ -179,7 +179,7 @@ fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) { let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let editor = cx .add_window(|cx| build_editor(buffer.clone(), cx)) - .detach(cx); + .root(cx); editor.update(cx, |editor, cx| { editor.start_transaction_at(now, cx); @@ -354,7 +354,7 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\nddddddd\n", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); editor.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx); }); @@ -423,7 +423,7 @@ fn test_canceling_pending_selection(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx); @@ -471,7 +471,7 @@ fn test_clone(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple(&text, cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| s.select_ranges(selection_ranges.clone())); @@ -489,7 +489,7 @@ fn test_clone(cx: &mut TestAppContext) { .update(cx, |editor, cx| { cx.add_window(Default::default(), |cx| editor.clone(cx)) }) - .detach(cx); + .root(cx); let snapshot = editor.update(cx, |e, cx| e.snapshot(cx)); let cloned_snapshot = cloned_editor.update(cx, |e, cx| e.snapshot(cx)); @@ -639,7 +639,7 @@ fn test_cancel(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(3, 4), false, 1, cx); @@ -704,7 +704,7 @@ fn test_fold_action(cx: &mut TestAppContext) { ); build_editor(buffer.clone(), cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { @@ -774,7 +774,7 @@ fn test_move_cursor(cx: &mut TestAppContext) { let buffer = cx.update(|cx| MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx)); let view = cx .add_window(|cx| build_editor(buffer.clone(), cx)) - .detach(cx); + .root(cx); buffer.update(cx, |buffer, cx| { buffer.edit( @@ -854,7 +854,7 @@ fn test_move_cursor_multibyte(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcde\nαβγδε\n", cx); build_editor(buffer.clone(), cx) }) - .detach(cx); + .root(cx); assert_eq!('ⓐ'.len_utf8(), 3); assert_eq!('α'.len_utf8(), 2); @@ -961,7 +961,7 @@ fn test_move_cursor_different_line_lengths(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx); build_editor(buffer.clone(), cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([empty_range(0, "ⓐⓑⓒⓓⓔ".len())]); @@ -1013,7 +1013,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\n def", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -1178,7 +1178,7 @@ fn test_prev_next_word_boundary(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("use std::str::{foo, bar}\n\n {baz.qux()}", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -1233,7 +1233,7 @@ fn test_prev_next_word_bounds_with_soft_wrap(cx: &mut TestAppContext) { MultiBuffer::build_simple("use one::{\n two::three::four::five\n};", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.set_wrap_width(Some(140.), cx); @@ -1568,7 +1568,7 @@ fn test_delete_to_word_boundary(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("one two three four", cx); build_editor(buffer.clone(), cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { @@ -1606,7 +1606,7 @@ fn test_newline(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("aaaa\n bbbb\n", cx); build_editor(buffer.clone(), cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { @@ -1651,7 +1651,7 @@ fn test_newline_with_old_selections(cx: &mut TestAppContext) { }); editor }) - .detach(cx); + .root(cx); editor.update(cx, |editor, cx| { // Edit the buffer directly, deleting ranges surrounding the editor's selections @@ -1863,7 +1863,7 @@ fn test_insert_with_old_selections(cx: &mut TestAppContext) { editor.change_selections(None, cx, |s| s.select_ranges([3..4, 11..12, 19..20])); editor }) - .detach(cx); + .root(cx); editor.update(cx, |editor, cx| { // Edit the buffer directly, deleting ranges surrounding the editor's selections @@ -2375,7 +2375,7 @@ fn test_delete_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -2400,7 +2400,7 @@ fn test_delete_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)]) @@ -2704,7 +2704,7 @@ fn test_duplicate_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -2732,7 +2732,7 @@ fn test_duplicate_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -2761,7 +2761,7 @@ fn test_move_line_up_down(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.fold_ranges( vec![ @@ -2862,7 +2862,7 @@ fn test_move_line_up_down_with_blocks(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); editor.update(cx, |editor, cx| { let snapshot = editor.buffer.read(cx).snapshot(cx); editor.insert_blocks( @@ -3182,7 +3182,7 @@ fn test_select_all(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\nde\nfgh", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.select_all(&SelectAll, cx); assert_eq!( @@ -3201,7 +3201,7 @@ fn test_select_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple(&sample_text(6, 5, 'a'), cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -3250,7 +3250,7 @@ fn test_split_selection_into_lines(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple(&sample_text(9, 5, 'a'), cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.fold_ranges( vec![ @@ -3323,7 +3323,7 @@ fn test_add_selection_above_below(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\ndefghi\n\njk\nlmno\n", cx); build_editor(buffer, cx) }) - .detach(cx); + .root(cx); view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { @@ -3608,7 +3608,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let view = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); + let view = cx.add_window(|cx| build_editor(buffer, cx)).root(cx); view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; @@ -3771,7 +3771,7 @@ async fn test_autoindent_selections(cx: &mut gpui::TestAppContext) { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx); editor .condition(cx, |editor, cx| !editor.buffer.read(cx).is_parsing(cx)) .await; @@ -4334,7 +4334,7 @@ async fn test_surround_with_pair(cx: &mut gpui::TestAppContext) { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let view = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); + let view = cx.add_window(|cx| build_editor(buffer, cx)).root(cx); view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; @@ -4482,7 +4482,7 @@ async fn test_delete_autoclose_pair(cx: &mut gpui::TestAppContext) { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx); editor .condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; @@ -4572,7 +4572,7 @@ async fn test_snippets(cx: &mut gpui::TestAppContext) { ); let buffer = cx.update(|cx| MultiBuffer::build_simple(&text, cx)); - let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx); editor.update(cx, |editor, cx| { let snippet = Snippet::parse("f(${1:one}, ${2:two}, ${1:three})$0").unwrap(); @@ -4702,7 +4702,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) { let fake_server = fake_servers.next().await.unwrap(); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx); editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); assert!(cx.read(|cx| editor.is_dirty(cx))); @@ -4814,7 +4814,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) { let fake_server = fake_servers.next().await.unwrap(); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx); editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); assert!(cx.read(|cx| editor.is_dirty(cx))); @@ -4928,7 +4928,7 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) { let fake_server = fake_servers.next().await.unwrap(); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let editor = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); + let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx); editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); let format = editor.update(cx, |editor, cx| { @@ -5706,7 +5706,7 @@ fn test_editing_disjoint_excerpts(cx: &mut TestAppContext) { multibuffer }); - let view = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx); + let view = cx.add_window(|cx| build_editor(multibuffer, cx)).root(cx); view.update(cx, |view, cx| { assert_eq!(view.text(cx), "aaaa\nbbbb"); view.change_selections(None, cx, |s| { @@ -5776,7 +5776,7 @@ fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) { multibuffer }); - let view = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx); + let view = cx.add_window(|cx| build_editor(multibuffer, cx)).root(cx); view.update(cx, |view, cx| { let (expected_text, selection_ranges) = marked_text_ranges( indoc! {" @@ -5869,7 +5869,7 @@ fn test_refresh_selections(cx: &mut TestAppContext) { ); editor }) - .detach(cx); + .root(cx); // Refreshing selections is a no-op when excerpts haven't changed. editor.update(cx, |editor, cx| { @@ -5950,7 +5950,7 @@ fn test_refresh_selections_while_selecting_with_mouse(cx: &mut TestAppContext) { ); editor }) - .detach(cx); + .root(cx); multibuffer.update(cx, |multibuffer, cx| { multibuffer.remove_excerpts([excerpt1_id.unwrap()], cx); @@ -6013,7 +6013,7 @@ async fn test_extra_newline_insertion(cx: &mut gpui::TestAppContext) { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let view = cx.add_window(|cx| build_editor(buffer, cx)).detach(cx); + let view = cx.add_window(|cx| build_editor(buffer, cx)).root(cx); view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; @@ -6054,7 +6054,7 @@ fn test_highlighted_ranges(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple(&sample_text(16, 8, 'a'), cx); build_editor(buffer.clone(), cx) }) - .detach(cx); + .root(cx); editor.update(cx, |editor, cx| { struct Type1; @@ -6145,7 +6145,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) { }); let leader = cx .add_window(|cx| build_editor(buffer.clone(), cx)) - .detach(cx); + .root(cx); let follower = cx .update(|cx| { cx.add_window( @@ -6156,7 +6156,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) { |cx| build_editor(buffer.clone(), cx), ) }) - .detach(cx); + .root(cx); let is_still_following = Rc::new(RefCell::new(true)); let follower_edit_event_count = Rc::new(RefCell::new(0)); @@ -6289,7 +6289,7 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) { let project = Project::test(fs, ["/file.rs".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); let leader = pane.update(cx, |_, cx| { @@ -7033,7 +7033,7 @@ async fn test_copilot_multibuffer( ); multibuffer }); - let editor = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx); + let editor = cx.add_window(|cx| build_editor(multibuffer, cx)).root(cx); handle_copilot_completion_request( &copilot_lsp, @@ -7163,7 +7163,7 @@ async fn test_copilot_disabled_globs( ); multibuffer }); - let editor = cx.add_window(|cx| build_editor(multibuffer, cx)).detach(cx); + let editor = cx.add_window(|cx| build_editor(multibuffer, cx)).root(cx); let mut copilot_requests = copilot_lsp .handle_request::(move |_params, _cx| async move { @@ -7244,7 +7244,7 @@ async fn test_on_type_formatting_not_triggered(cx: &mut gpui::TestAppContext) { project.update(cx, |project, _| project.languages().add(Arc::new(language))); let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index dc40e7fb8568aeec2bf5d4fe6f4168e4847c3558..2d4b273f5ef0523f8ef8d9d9cd107c7e30bd659d 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -3007,7 +3007,7 @@ mod tests { let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx); Editor::new(EditorMode::Full, buffer, None, None, cx) }) - .detach(cx); + .root(cx); let element = EditorElement::new(editor.read_with(cx, |editor, cx| editor.style(cx))); let layouts = editor.update(cx, |editor, cx| { @@ -3028,7 +3028,7 @@ mod tests { let buffer = MultiBuffer::build_simple("", cx); Editor::new(EditorMode::Full, buffer, None, None, cx) }) - .detach(cx); + .root(cx); editor.update(cx, |editor, cx| { editor.set_placeholder_text("hello", cx); @@ -3240,7 +3240,7 @@ mod tests { let buffer = MultiBuffer::build_simple(&input_text, cx); Editor::new(editor_mode, buffer, None, None, cx) }) - .detach(cx); + .root(cx); let mut element = EditorElement::new(editor.read_with(cx, |editor, cx| editor.style(cx))); let (_, layout_state) = editor.update(cx, |editor, cx| { diff --git a/crates/editor/src/inlay_hint_cache.rs b/crates/editor/src/inlay_hint_cache.rs index 089cbb29958c727a0b7760018833a279534a225a..47a27c049f91658fdd848381f86207642bce15c9 100644 --- a/crates/editor/src/inlay_hint_cache.rs +++ b/crates/editor/src/inlay_hint_cache.rs @@ -1138,7 +1138,7 @@ mod tests { let project = Project::test(fs, ["/a".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() @@ -1840,7 +1840,7 @@ mod tests { project.update(cx, |project, _| project.languages().add(Arc::new(language))); let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() @@ -1995,7 +1995,7 @@ mod tests { }); let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() @@ -2083,7 +2083,7 @@ mod tests { cx.foreground().run_until_parked(); let editor = cx .add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx)) - .detach(cx); + .root(cx); let editor_edited = Arc::new(AtomicBool::new(false)); let fake_server = fake_servers.next().await.unwrap(); let closure_editor_edited = Arc::clone(&editor_edited); @@ -2337,7 +2337,7 @@ all hints should be invalidated and requeried for all of its visible excerpts" }); let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() @@ -2384,7 +2384,7 @@ all hints should be invalidated and requeried for all of its visible excerpts" cx.foreground().run_until_parked(); let editor = cx .add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx)) - .detach(cx); + .root(cx); let editor_edited = Arc::new(AtomicBool::new(false)); let fake_server = fake_servers.next().await.unwrap(); let closure_editor_edited = Arc::clone(&editor_edited); @@ -2574,7 +2574,7 @@ all hints should be invalidated and requeried for all of its visible excerpts" project.update(cx, |project, _| project.languages().add(Arc::new(language))); let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let worktree_id = workspace.update(cx, |workspace, cx| { workspace.project().read_with(cx, |project, cx| { project.worktrees(cx).next().unwrap().read(cx).id() diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 2c9d9c0c71e390c256e7db785ee06d707039a8a1..12bf3242627619d390409bba044c0fa9cdcce3d4 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -842,7 +842,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/dir".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project, cx)) - .detach(cx); + .root(cx); let finder = cx .add_window(|cx| { Picker::new( @@ -856,7 +856,7 @@ mod tests { cx, ) }) - .detach(cx); + .root(cx); let query = test_path_like("hi"); finder @@ -940,7 +940,7 @@ mod tests { .await; let workspace = cx .add_window(|cx| Workspace::test_new(project, cx)) - .detach(cx); + .root(cx); let finder = cx .add_window(|cx| { Picker::new( @@ -954,7 +954,7 @@ mod tests { cx, ) }) - .detach(cx); + .root(cx); finder .update(cx, |f, cx| { f.delegate_mut().spawn_search(test_path_like("hi"), cx) @@ -980,7 +980,7 @@ mod tests { .await; let workspace = cx .add_window(|cx| Workspace::test_new(project, cx)) - .detach(cx); + .root(cx); let finder = cx .add_window(|cx| { Picker::new( @@ -994,7 +994,7 @@ mod tests { cx, ) }) - .detach(cx); + .root(cx); // Even though there is only one worktree, that worktree's filename // is included in the matching, because the worktree is a single file. @@ -1051,7 +1051,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project, cx)) - .detach(cx); + .root(cx); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1); @@ -1078,7 +1078,7 @@ mod tests { cx, ) }) - .detach(cx); + .root(cx); finder .update(cx, |f, cx| { @@ -1117,7 +1117,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project, cx)) - .detach(cx); + .root(cx); let finder = cx .add_window(|cx| { Picker::new( @@ -1131,7 +1131,7 @@ mod tests { cx, ) }) - .detach(cx); + .root(cx); finder .update(cx, |f, cx| { f.delegate_mut().spawn_search(test_path_like("dir"), cx) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 9b847e9c0cfdea426902ea59e93cec3a0c349fdf..dce0b0e5f0ceca28e7503027720cfc39be351e24 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -130,12 +130,12 @@ pub trait BorrowAppContext { } pub trait BorrowWindowContext { - type Return; + type Result; - fn read_with(&self, window_id: usize, f: F) -> Self::Return + fn read_window_with(&self, window_id: usize, f: F) -> Self::Result where F: FnOnce(&WindowContext) -> T; - fn update(&mut self, window_id: usize, f: F) -> Self::Return + fn update_window(&mut self, window_id: usize, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T; } @@ -458,6 +458,26 @@ impl BorrowAppContext for AsyncAppContext { } } +impl BorrowWindowContext for AsyncAppContext { + type Result = Option; + + fn read_window_with(&self, window_id: usize, f: F) -> Self::Result + where + F: FnOnce(&WindowContext) -> T, + { + self.0.borrow().read_with(|cx| cx.read_window(window_id, f)) + } + + fn update_window(&mut self, window_id: usize, f: F) -> Self::Result + where + F: FnOnce(&mut WindowContext) -> T, + { + self.0 + .borrow_mut() + .update(|cx| cx.update_window(window_id, f)) + } +} + type ActionCallback = dyn FnMut(&mut dyn AnyView, &dyn Action, &mut WindowContext, usize); type GlobalActionCallback = dyn FnMut(&dyn Action, &mut AppContext); @@ -2162,6 +2182,24 @@ impl BorrowAppContext for AppContext { } } +impl BorrowWindowContext for AppContext { + type Result = Option; + + fn read_window_with(&self, window_id: usize, f: F) -> Self::Result + where + F: FnOnce(&WindowContext) -> T, + { + AppContext::read_window(self, window_id, f) + } + + fn update_window(&mut self, window_id: usize, f: F) -> Self::Result + where + F: FnOnce(&mut WindowContext) -> T, + { + AppContext::update_window(self, window_id, f) + } +} + #[derive(Debug)] pub enum ParentId { View(usize), @@ -3360,14 +3398,18 @@ impl BorrowAppContext for ViewContext<'_, '_, V> { } impl BorrowWindowContext for ViewContext<'_, '_, V> { - type Return = T; + type Result = T; - fn read_with T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_with(&*self.window_context, window_id, f) + fn read_window_with T>(&self, window_id: usize, f: F) -> T { + BorrowWindowContext::read_window_with(&*self.window_context, window_id, f) } - fn update T>(&mut self, window_id: usize, f: F) -> T { - BorrowWindowContext::update(&mut *self.window_context, window_id, f) + fn update_window T>( + &mut self, + window_id: usize, + f: F, + ) -> T { + BorrowWindowContext::update_window(&mut *self.window_context, window_id, f) } } @@ -3467,14 +3509,18 @@ impl BorrowAppContext for LayoutContext<'_, '_, '_, V> { } impl BorrowWindowContext for LayoutContext<'_, '_, '_, V> { - type Return = T; + type Result = T; - fn read_with T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_with(&*self.view_context, window_id, f) + fn read_window_with T>(&self, window_id: usize, f: F) -> T { + BorrowWindowContext::read_window_with(&*self.view_context, window_id, f) } - fn update T>(&mut self, window_id: usize, f: F) -> T { - BorrowWindowContext::update(&mut *self.view_context, window_id, f) + fn update_window T>( + &mut self, + window_id: usize, + f: F, + ) -> T { + BorrowWindowContext::update_window(&mut *self.view_context, window_id, f) } } @@ -3521,14 +3567,18 @@ impl BorrowAppContext for EventContext<'_, '_, '_, V> { } impl BorrowWindowContext for EventContext<'_, '_, '_, V> { - type Return = T; + type Result = T; - fn read_with T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_with(&*self.view_context, window_id, f) + fn read_window_with T>(&self, window_id: usize, f: F) -> T { + BorrowWindowContext::read_window_with(&*self.view_context, window_id, f) } - fn update T>(&mut self, window_id: usize, f: F) -> T { - BorrowWindowContext::update(&mut *self.view_context, window_id, f) + fn update_window T>( + &mut self, + window_id: usize, + f: F, + ) -> T { + BorrowWindowContext::update_window(&mut *self.view_context, window_id, f) } } @@ -3830,32 +3880,16 @@ impl WindowHandle { self.any_handle.id() } - pub fn root(&self, cx: &impl BorrowAppContext) -> ViewHandle { + pub fn root(&self, cx: &C) -> C::Result> { self.read_with(cx, |cx| cx.root_view().clone().downcast().unwrap()) } - /// Keep this window open until it's explicitly closed. - // - // TODO: Implement window dropping behavior when we don't call this. - pub fn detach(mut self, cx: &impl BorrowAppContext) -> ViewHandle { - let root = self.root(cx); - let ref_counts = self.any_handle.ref_counts.take(); - #[cfg(any(test, feature = "test-support"))] - ref_counts - .unwrap() - .lock() - .leak_detector - .lock() - .handle_dropped(self.id(), self.any_handle.handle_id); - root - } - - pub fn read_with(&self, cx: &C, read: F) -> R + pub fn read_with(&self, cx: &C, read: F) -> C::Result where - C: BorrowAppContext, + C: BorrowWindowContext, F: FnOnce(&WindowContext) -> R, { - cx.read_with(|cx| cx.read_window(self.id(), read).unwrap()) + cx.read_window_with(self.id(), |cx| read(cx)) } pub fn update(&self, cx: &mut C, update: F) -> R @@ -3891,9 +3925,9 @@ impl WindowHandle { root_view.read(cx) } - pub fn read_root_with(&self, cx: &C, read: F) -> R + pub fn read_root_with(&self, cx: &C, read: F) -> C::Result where - C: BorrowAppContext, + C: BorrowWindowContext, F: FnOnce(&V, &ViewContext) -> R, { self.read_with(cx, |cx| { @@ -4021,25 +4055,25 @@ impl ViewHandle { cx.read_view(self) } - pub fn read_with(&self, cx: &C, read: F) -> C::Return + pub fn read_with(&self, cx: &C, read: F) -> C::Result where C: BorrowWindowContext, F: FnOnce(&T, &ViewContext) -> S, { - cx.read_with(self.window_id, |cx| { + cx.read_window_with(self.window_id, |cx| { let cx = ViewContext::immutable(cx, self.view_id); read(cx.read_view(self), &cx) }) } - pub fn update(&self, cx: &mut C, update: F) -> C::Return + pub fn update(&self, cx: &mut C, update: F) -> C::Result where C: BorrowWindowContext, F: FnOnce(&mut T, &mut ViewContext) -> S, { let mut update = Some(update); - cx.update(self.window_id, |cx| { + cx.update_window(self.window_id, |cx| { cx.update_view(self, &mut |view, cx| { let update = update.take().unwrap(); update(view, cx) @@ -5005,7 +5039,7 @@ mod tests { } #[crate::test(self)] - fn test_entity_release_hooks(cx: &mut AppContext) { + fn test_entity_release_hooks(cx: &mut TestAppContext) { struct Model { released: Rc>, } @@ -5048,7 +5082,7 @@ mod tests { let model = cx.add_model(|_| Model { released: model_released.clone(), }); - let window = cx.add_window(Default::default(), |_| View { + let window = cx.add_window(|_| View { released: view_released.clone(), }); let view = window.root(cx); @@ -5056,16 +5090,18 @@ mod tests { assert!(!model_released.get()); assert!(!view_released.get()); - cx.observe_release(&model, { - let model_release_observed = model_release_observed.clone(); - move |_, _| model_release_observed.set(true) - }) - .detach(); - cx.observe_release(&view, { - let view_release_observed = view_release_observed.clone(); - move |_, _| view_release_observed.set(true) - }) - .detach(); + cx.update(|cx| { + cx.observe_release(&model, { + let model_release_observed = model_release_observed.clone(); + move |_, _| model_release_observed.set(true) + }) + .detach(); + cx.observe_release(&view, { + let view_release_observed = view_release_observed.clone(); + move |_, _| view_release_observed.set(true) + }) + .detach(); + }); cx.update(move |_| { drop(model); @@ -5795,7 +5831,7 @@ mod tests { } #[crate::test(self)] - fn test_dispatch_action(cx: &mut AppContext) { + fn test_dispatch_action(cx: &mut TestAppContext) { struct ViewA { id: usize, child: Option, @@ -5846,68 +5882,70 @@ mod tests { impl_actions!(test, [Action]); let actions = Rc::new(RefCell::new(Vec::new())); + let observed_actions = Rc::new(RefCell::new(Vec::new())); - cx.add_global_action({ - let actions = actions.clone(); - move |_: &Action, _: &mut AppContext| { - actions.borrow_mut().push("global".to_string()); - } - }); + cx.update(|cx| { + cx.add_global_action({ + let actions = actions.clone(); + move |_: &Action, _: &mut AppContext| { + actions.borrow_mut().push("global".to_string()); + } + }); - cx.add_action({ - let actions = actions.clone(); - move |view: &mut ViewA, action: &Action, cx| { - assert_eq!(action.0, "bar"); - cx.propagate_action(); - actions.borrow_mut().push(format!("{} a", view.id)); - } - }); + cx.add_action({ + let actions = actions.clone(); + move |view: &mut ViewA, action: &Action, cx| { + assert_eq!(action.0, "bar"); + cx.propagate_action(); + actions.borrow_mut().push(format!("{} a", view.id)); + } + }); - cx.add_action({ - let actions = actions.clone(); - move |view: &mut ViewA, _: &Action, cx| { - if view.id != 1 { - cx.add_view(|cx| { - cx.propagate_action(); // Still works on a nested ViewContext - ViewB { id: 5, child: None } - }); + cx.add_action({ + let actions = actions.clone(); + move |view: &mut ViewA, _: &Action, cx| { + if view.id != 1 { + cx.add_view(|cx| { + cx.propagate_action(); // Still works on a nested ViewContext + ViewB { id: 5, child: None } + }); + } + actions.borrow_mut().push(format!("{} b", view.id)); } - actions.borrow_mut().push(format!("{} b", view.id)); - } - }); + }); - cx.add_action({ - let actions = actions.clone(); - move |view: &mut ViewB, _: &Action, cx| { - cx.propagate_action(); - actions.borrow_mut().push(format!("{} c", view.id)); - } - }); + cx.add_action({ + let actions = actions.clone(); + move |view: &mut ViewB, _: &Action, cx| { + cx.propagate_action(); + actions.borrow_mut().push(format!("{} c", view.id)); + } + }); - cx.add_action({ - let actions = actions.clone(); - move |view: &mut ViewB, _: &Action, cx| { - cx.propagate_action(); - actions.borrow_mut().push(format!("{} d", view.id)); - } - }); + cx.add_action({ + let actions = actions.clone(); + move |view: &mut ViewB, _: &Action, cx| { + cx.propagate_action(); + actions.borrow_mut().push(format!("{} d", view.id)); + } + }); - cx.capture_action({ - let actions = actions.clone(); - move |view: &mut ViewA, _: &Action, cx| { - cx.propagate_action(); - actions.borrow_mut().push(format!("{} capture", view.id)); - } - }); + cx.capture_action({ + let actions = actions.clone(); + move |view: &mut ViewA, _: &Action, cx| { + cx.propagate_action(); + actions.borrow_mut().push(format!("{} capture", view.id)); + } + }); - let observed_actions = Rc::new(RefCell::new(Vec::new())); - cx.observe_actions({ - let observed_actions = observed_actions.clone(); - move |action_id, _| observed_actions.borrow_mut().push(action_id) - }) - .detach(); + cx.observe_actions({ + let observed_actions = observed_actions.clone(); + move |action_id, _| observed_actions.borrow_mut().push(action_id) + }) + .detach(); + }); - let window = cx.add_window(Default::default(), |_| ViewA { id: 1, child: None }); + let window = cx.add_window(|_| ViewA { id: 1, child: None }); let view_1 = window.root(cx); let view_2 = window.update(cx, |cx| { let child = cx.add_view(|_| ViewB { id: 2, child: None }); @@ -5956,7 +5994,7 @@ mod tests { // Remove view_1, which doesn't propagate the action - let window = cx.add_window(Default::default(), |_| ViewB { id: 2, child: None }); + let window = cx.add_window(|_| ViewB { id: 2, child: None }); let view_2 = window.root(cx); let view_3 = window.update(cx, |cx| { let child = cx.add_view(|_| ViewA { id: 3, child: None }); @@ -6457,7 +6495,7 @@ mod tests { } #[crate::test(self)] - fn test_refresh_windows(cx: &mut AppContext) { + fn test_refresh_windows(cx: &mut TestAppContext) { struct View(usize); impl super::Entity for View { @@ -6474,7 +6512,7 @@ mod tests { } } - let window = cx.add_window(Default::default(), |_| View(0)); + let window = cx.add_window(|_| View(0)); let root_view = window.root(cx); window.update(cx, |cx| { assert_eq!( diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 5c7947a44827d3eb23e6a490c7fdfaacd9e90bfb..0165c52e9f3fff9453c43484208c202a6a39138a 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -406,16 +406,20 @@ impl BorrowAppContext for TestAppContext { } impl BorrowWindowContext for TestAppContext { - type Return = T; + type Result = T; - fn read_with T>(&self, window_id: usize, f: F) -> T { + fn read_window_with T>(&self, window_id: usize, f: F) -> T { self.cx .borrow() .read_window(window_id, f) .expect("window was closed") } - fn update T>(&mut self, window_id: usize, f: F) -> T { + fn update_window T>( + &mut self, + window_id: usize, + f: F, + ) -> T { self.cx .borrow_mut() .update_window(window_id, f) diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 671d2b38c77c9d71201e77c87fd8ef21d077b24b..0149c310daaadd773e54dd58314261eb1864ecb6 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -142,9 +142,9 @@ impl BorrowAppContext for WindowContext<'_> { } impl BorrowWindowContext for WindowContext<'_> { - type Return = T; + type Result = T; - fn read_with T>(&self, window_id: usize, f: F) -> T { + fn read_window_with T>(&self, window_id: usize, f: F) -> T { if self.window_id == window_id { f(self) } else { @@ -152,7 +152,11 @@ impl BorrowWindowContext for WindowContext<'_> { } } - fn update T>(&mut self, window_id: usize, f: F) -> T { + fn update_window T>( + &mut self, + window_id: usize, + f: F, + ) -> T { if self.window_id == window_id { f(self) } else { diff --git a/crates/language_tools/src/lsp_log_tests.rs b/crates/language_tools/src/lsp_log_tests.rs index ce05a417ad8fc6cebc61ee236d2289b8b73e2170..d26000ebc73b022c15dbf02ccdb3053763264118 100644 --- a/crates/language_tools/src/lsp_log_tests.rs +++ b/crates/language_tools/src/lsp_log_tests.rs @@ -63,7 +63,7 @@ async fn test_lsp_logs(cx: &mut TestAppContext) { let log_view = cx .add_window(|cx| LspLogView::new(project.clone(), log_store.clone(), cx)) - .detach(cx); + .root(cx); language_server.notify::(lsp::LogMessageParams { message: "hello from the server".into(), diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index fdc5ea108a812459f374fdd0a1386fe31bb9830a..021ea2d3bc3a817342e9eac684496ffeee5026bb 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1782,7 +1782,7 @@ mod tests { let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); assert_eq!( visible_entries_as_strings(&panel, 0..50, cx), @@ -2327,7 +2327,7 @@ mod tests { let project = Project::test(fs.clone(), ["/root1".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); panel.update(cx, |panel, cx| { @@ -2641,7 +2641,7 @@ mod tests { let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); let new_search_events_count = Arc::new(AtomicUsize::new(0)); @@ -2730,7 +2730,7 @@ mod tests { let project = Project::test(fs.clone(), ["/project_root".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); panel.update(cx, |panel, cx| { diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index e57edd3b14709aea1056965b59e173bc9e404a23..0db66b4e378a56c97e2e2d1290742e52e1329bda 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1449,7 +1449,7 @@ pub mod tests { let search = cx.add_model(|cx| ProjectSearch::new(project, cx)); let search_view = cx .add_window(|cx| ProjectSearchView::new(search.clone(), cx)) - .detach(cx); + .root(cx); search_view.update(cx, |search_view, cx| { search_view @@ -1754,7 +1754,7 @@ pub mod tests { }); let workspace = cx .add_window(|cx| Workspace::test_new(project, cx)) - .detach(cx); + .root(cx); let active_item = cx.read(|cx| { workspace diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 874978b4fc567526e6bd17d4f6edd3fa9a670c3c..a600046ac2861fb7b0b1250c65d4b31c1af3166c 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -1072,7 +1072,7 @@ mod tests { let project = Project::test(params.fs.clone(), [], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); (project, workspace) } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 3222ea2eb8cab97976c81ad6ad5c43668cf46655..2efa9f8daac69c872bda6cb3f7936d52d8d0222b 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -793,68 +793,60 @@ impl Workspace { DB.next_id().await.unwrap_or(0) }; - let window = requesting_window_id - .and_then(|window_id| { - cx.update(|cx| { - cx.replace_root_view(window_id, |cx| { - Workspace::new( - workspace_id, - project_handle.clone(), - app_state.clone(), - cx, - ) - }) + let window = requesting_window_id.and_then(|window_id| { + cx.update(|cx| { + cx.replace_root_view(window_id, |cx| { + Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx) }) }) - .unwrap_or_else(|| { - let window_bounds_override = window_bounds_env_override(&cx); - let (bounds, display) = if let Some(bounds) = window_bounds_override { - (Some(bounds), None) - } else { - serialized_workspace - .as_ref() - .and_then(|serialized_workspace| { - let display = serialized_workspace.display?; - let mut bounds = serialized_workspace.bounds?; - - // Stored bounds are relative to the containing display. - // So convert back to global coordinates if that screen still exists - if let WindowBounds::Fixed(mut window_bounds) = bounds { - if let Some(screen) = cx.platform().screen_by_id(display) { - let screen_bounds = screen.bounds(); - window_bounds.set_origin_x( - window_bounds.origin_x() + screen_bounds.origin_x(), - ); - window_bounds.set_origin_y( - window_bounds.origin_y() + screen_bounds.origin_y(), - ); - bounds = WindowBounds::Fixed(window_bounds); - } else { - // Screen no longer exists. Return none here. - return None; - } + }); + let window = window.unwrap_or_else(|| { + let window_bounds_override = window_bounds_env_override(&cx); + let (bounds, display) = if let Some(bounds) = window_bounds_override { + (Some(bounds), None) + } else { + serialized_workspace + .as_ref() + .and_then(|serialized_workspace| { + let display = serialized_workspace.display?; + let mut bounds = serialized_workspace.bounds?; + + // Stored bounds are relative to the containing display. + // So convert back to global coordinates if that screen still exists + if let WindowBounds::Fixed(mut window_bounds) = bounds { + if let Some(screen) = cx.platform().screen_by_id(display) { + let screen_bounds = screen.bounds(); + window_bounds.set_origin_x( + window_bounds.origin_x() + screen_bounds.origin_x(), + ); + window_bounds.set_origin_y( + window_bounds.origin_y() + screen_bounds.origin_y(), + ); + bounds = WindowBounds::Fixed(window_bounds); + } else { + // Screen no longer exists. Return none here. + return None; } + } - Some((bounds, display)) - }) - .unzip() - }; - - // Use the serialized workspace to construct the new window - cx.add_window( - (app_state.build_window_options)(bounds, display, cx.platform().as_ref()), - |cx| { - Workspace::new( - workspace_id, - project_handle.clone(), - app_state.clone(), - cx, - ) - }, - ) - }); + Some((bounds, display)) + }) + .unzip() + }; + + // Use the serialized workspace to construct the new window + cx.add_window( + (app_state.build_window_options)(bounds, display, cx.platform().as_ref()), + |cx| { + Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx) + }, + ) + }); + + // We haven't yielded the main thread since obtaining the window handle, + // so the window exists. + let workspace = window.root(&cx).unwrap(); - let workspace = window.root(&cx); (app_state.initialize_workspace)( workspace.downgrade(), serialized_workspace.is_some(), @@ -3985,7 +3977,7 @@ pub fn join_remote_project( ), |cx| Workspace::new(0, project, app_state.clone(), cx), ); - let workspace = window.root(&cx); + let workspace = window.root(&cx).unwrap(); (app_state.initialize_workspace)( workspace.downgrade(), false, diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 1770c5648e1fd2f8fe2a5ed31354f5525629a04f..a459122cfc9a29b209f8d6cbcf7031f739781857 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -985,7 +985,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project, cx)) - .detach(cx); + .root(cx); let entries = cx.read(|cx| workspace.file_project_paths(cx)); let file1 = entries[0].clone(); @@ -1566,7 +1566,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project.clone(), cx)) - .detach(cx); + .root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); let entries = cx.read(|cx| workspace.file_project_paths(cx)); @@ -1845,7 +1845,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let workspace = cx .add_window(|cx| Workspace::test_new(project, cx)) - .detach(cx); + .root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); let entries = cx.read(|cx| workspace.file_project_paths(cx)); From 485c0a482ee8e7b2a2014f1129ca060d4554af0c Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 3 Aug 2023 17:11:47 -0600 Subject: [PATCH 121/160] Don't refcount window handles --- crates/collab/src/tests/integration_tests.rs | 4 +- .../src/incoming_call_notification.rs | 2 +- .../src/project_shared_notification.rs | 2 +- crates/command_palette/src/command_palette.rs | 2 +- crates/copilot/src/sign_in.rs | 4 +- crates/diagnostics/src/diagnostics.rs | 4 +- crates/editor/src/editor_tests.rs | 2 +- .../src/test/editor_lsp_test_context.rs | 2 +- crates/editor/src/test/editor_test_context.rs | 2 +- crates/file_finder/src/file_finder.rs | 22 ++-- crates/gpui/src/app.rs | 100 ++++-------------- crates/gpui/src/app/ref_counts.rs | 22 ---- crates/gpui/src/app/test_app_context.rs | 4 +- crates/gpui/src/app/window.rs | 2 +- crates/project_panel/src/project_panel.rs | 8 +- crates/project_symbols/src/project_symbols.rs | 2 +- crates/search/src/buffer_search.rs | 10 +- crates/search/src/project_search.rs | 4 +- crates/workspace/src/workspace.rs | 36 +++---- crates/zed/src/zed.rs | 12 +-- 20 files changed, 83 insertions(+), 163 deletions(-) diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index 1a8e6d938d6d6caac2b8caee501e1088ddeea5b3..037f97f71abc8a5961b3693c461522af985fbb55 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -3446,7 +3446,7 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor( let editor_a = window_a.add_view(cx_a, |cx| Editor::for_buffer(buffer_a, Some(project_a), cx)); let mut editor_cx_a = EditorTestContext { cx: cx_a, - window_id: window_a.id(), + window_id: window_a.window_id(), editor: editor_a, }; @@ -3459,7 +3459,7 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor( let editor_b = window_b.add_view(cx_b, |cx| Editor::for_buffer(buffer_b, Some(project_b), cx)); let mut editor_cx_b = EditorTestContext { cx: cx_b, - window_id: window_b.id(), + window_id: window_b.window_id(), editor: editor_b, }; diff --git a/crates/collab_ui/src/incoming_call_notification.rs b/crates/collab_ui/src/incoming_call_notification.rs index a9c5e697a5f60d0cb6f9c0e6baf7cac50aba192a..770f5d5795c980df75a4ce0f888f72745f63970e 100644 --- a/crates/collab_ui/src/incoming_call_notification.rs +++ b/crates/collab_ui/src/incoming_call_notification.rs @@ -49,7 +49,7 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { |_| IncomingCallNotification::new(incoming_call.clone(), app_state.clone()), ); - notification_windows.push(window.id()); + notification_windows.push(window.window_id()); } } } diff --git a/crates/collab_ui/src/project_shared_notification.rs b/crates/collab_ui/src/project_shared_notification.rs index 03ab91623b43270bf2592ced0f460b474fd0c435..5be7e33bf3cea049569ce294dbb3d8b1942cf38f 100644 --- a/crates/collab_ui/src/project_shared_notification.rs +++ b/crates/collab_ui/src/project_shared_notification.rs @@ -52,7 +52,7 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { notification_windows .entry(*project_id) .or_insert(Vec::new()) - .push(window.id()); + .push(window.window_id()); } } room::Event::RemoteProjectUnshared { project_id } => { diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 7d4b4126b702774bf8c295d3b61f904ff7ebf80c..935358c2a126bfd59f90ffe89f7b7825063af8c9 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -297,7 +297,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), [], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let editor = cx.add_view(window_id, |cx| { let mut editor = Editor::single_line(None, cx); editor.set_text("abc", cx); diff --git a/crates/copilot/src/sign_in.rs b/crates/copilot/src/sign_in.rs index 659bee7445f0696d32bf7532c902907d7ddcf11c..0d5bb28ed688897e67ecccd816215f68ce573fd7 100644 --- a/crates/copilot/src/sign_in.rs +++ b/crates/copilot/src/sign_in.rs @@ -25,7 +25,7 @@ pub fn init(cx: &mut AppContext) { match &status { crate::Status::SigningIn { prompt } => { if let Some(code_verification_handle) = code_verification.as_mut() { - let window_id = code_verification_handle.id(); + let window_id = code_verification_handle.window_id(); let updated = cx.update_window(window_id, |cx| { code_verification_handle.update_root(cx, |code_verification, cx| { code_verification.set_status(status.clone(), cx) @@ -41,7 +41,7 @@ pub fn init(cx: &mut AppContext) { } Status::Authorized | Status::Unauthorized => { if let Some(code_verification) = code_verification.as_ref() { - let window_id = code_verification.id(); + let window_id = code_verification.window_id(); cx.update_window(window_id, |cx| { code_verification.update_root(cx, |code_verification, cx| { code_verification.set_status(status, cx) diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 2444465be666124adb706bcf1833c50c77cee081..f2db0a7763054d19ea85b591de6e8b8d63272740 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -857,7 +857,7 @@ mod tests { let project = Project::test(fs.clone(), ["/test".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); // Create some diagnostics project.update(cx, |project, cx| { @@ -1252,7 +1252,7 @@ mod tests { let project = Project::test(fs.clone(), ["/test".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let view = cx.add_view(window_id, |cx| { ProjectDiagnosticsEditor::new(project.clone(), workspace.downgrade(), cx) diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index a114cd437b16bbad580d6e732bb004ac352d822a..e8913505cab0d579afa7d1621fa54398a985844e 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -525,7 +525,7 @@ async fn test_navigation_history(cx: &mut TestAppContext) { let project = Project::test(fs, [], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); cx.add_view(window_id, |cx| { let buffer = MultiBuffer::build_simple(&sample_text(300, 5, 'a'), cx); diff --git a/crates/editor/src/test/editor_lsp_test_context.rs b/crates/editor/src/test/editor_lsp_test_context.rs index f53115f224a1cfe6cb4a3c634786c7e7e8c18305..d25ca7bb88a86383166288fcb1ac6cd5cfd5997f 100644 --- a/crates/editor/src/test/editor_lsp_test_context.rs +++ b/crates/editor/src/test/editor_lsp_test_context.rs @@ -99,7 +99,7 @@ impl<'a> EditorLspTestContext<'a> { Self { cx: EditorTestContext { cx, - window_id: window.id(), + window_id: window.window_id(), editor, }, lsp, diff --git a/crates/editor/src/test/editor_test_context.rs b/crates/editor/src/test/editor_test_context.rs index c7ea1b4f3852301e300c5ff3f1db1dff65f342a2..ac519764fdd8b671a92070118ec9b4937d135c64 100644 --- a/crates/editor/src/test/editor_test_context.rs +++ b/crates/editor/src/test/editor_test_context.rs @@ -39,7 +39,7 @@ impl<'a> EditorTestContext<'a> { let editor = window.root(cx); Self { cx, - window_id: window.id(), + window_id: window.window_id(), editor, } } diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 12bf3242627619d390409bba044c0fa9cdcce3d4..84a45b083e6fdef0a2b4145e756f495fdc255300 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -619,7 +619,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.id(), Toggle); + cx.dispatch_action(window.window_id(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); finder @@ -632,8 +632,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.id(), SelectNext); - cx.dispatch_action(window.id(), Confirm); + cx.dispatch_action(window.window_id(), SelectNext); + cx.dispatch_action(window.window_id(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -674,7 +674,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.id(), Toggle); + cx.dispatch_action(window.window_id(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); let file_query = &first_file_name[..3]; @@ -706,8 +706,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.id(), SelectNext); - cx.dispatch_action(window.id(), Confirm); + cx.dispatch_action(window.window_id(), SelectNext); + cx.dispatch_action(window.window_id(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -758,7 +758,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.id(), Toggle); + cx.dispatch_action(window.window_id(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); let file_query = &first_file_name[..3]; @@ -790,8 +790,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.id(), SelectNext); - cx.dispatch_action(window.id(), Confirm); + cx.dispatch_action(window.window_id(), SelectNext); + cx.dispatch_action(window.window_id(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -1168,7 +1168,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1); @@ -1376,7 +1376,7 @@ mod tests { let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1,); diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index dce0b0e5f0ceca28e7503027720cfc39be351e24..90f910d255ff595bd1e2c0e1173296180e10c8fc 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1337,7 +1337,7 @@ impl AppContext { .open_window(window_id, window_options, this.foreground.clone()); let window = this.build_window(window_id, platform_window, build_root_view); this.windows.insert(window_id, window); - WindowHandle::new(window_id, this.ref_counts.clone()) + WindowHandle::new(window_id) }) } @@ -3863,21 +3863,21 @@ impl Clone for WeakModelHandle { impl Copy for WeakModelHandle {} pub struct WindowHandle { - any_handle: AnyWindowHandle, - view_type: PhantomData, + window_id: usize, + root_view_type: PhantomData, } #[allow(dead_code)] impl WindowHandle { - fn new(window_id: usize, ref_counts: Arc>) -> Self { + fn new(window_id: usize) -> Self { WindowHandle { - any_handle: AnyWindowHandle::new::(window_id, ref_counts), - view_type: PhantomData, + window_id, + root_view_type: PhantomData, } } - pub fn id(&self) -> usize { - self.any_handle.id() + pub fn window_id(&self) -> usize { + self.window_id } pub fn root(&self, cx: &C) -> C::Result> { @@ -3889,7 +3889,7 @@ impl WindowHandle { C: BorrowWindowContext, F: FnOnce(&WindowContext) -> R, { - cx.read_window_with(self.id(), |cx| read(cx)) + cx.read_window_with(self.window_id(), |cx| read(cx)) } pub fn update(&self, cx: &mut C, update: F) -> R @@ -3897,7 +3897,7 @@ impl WindowHandle { C: BorrowAppContext, F: FnOnce(&mut WindowContext) -> R, { - cx.update(|cx| cx.update_window(self.id(), update).unwrap()) + cx.update(|cx| cx.update_window(self.window_id(), update).unwrap()) } pub fn update_root(&self, cx: &mut C, update: F) -> R @@ -3905,7 +3905,7 @@ impl WindowHandle { C: BorrowAppContext, F: FnOnce(&mut V, &mut ViewContext) -> R, { - let window_id = self.id(); + let window_id = self.window_id(); cx.update(|cx| { cx.update_window(window_id, |cx| { cx.root_view() @@ -3920,7 +3920,9 @@ impl WindowHandle { pub fn read_root<'a>(&self, cx: &'a AppContext) -> &'a V { let root_view = cx - .read_window(self.id(), |cx| cx.root_view().clone().downcast().unwrap()) + .read_window(self.window_id(), |cx| { + cx.root_view().clone().downcast().unwrap() + }) .unwrap(); root_view.read(cx) } @@ -3948,66 +3950,6 @@ impl WindowHandle { } } -pub struct AnyWindowHandle { - window_id: usize, - root_view_type: TypeId, - ref_counts: Option>>, - - #[cfg(any(test, feature = "test-support"))] - handle_id: usize, -} - -impl AnyWindowHandle { - fn new(window_id: usize, ref_counts: Arc>) -> Self { - ref_counts.lock().inc_window(window_id); - - #[cfg(any(test, feature = "test-support"))] - let handle_id = ref_counts - .lock() - .leak_detector - .lock() - .handle_created(None, window_id); - - Self { - window_id, - root_view_type: TypeId::of::(), - ref_counts: Some(ref_counts), - #[cfg(any(test, feature = "test-support"))] - handle_id, - } - } - - pub fn id(&self) -> usize { - self.window_id - } - - pub fn downcast(self) -> Option> { - if TypeId::of::() == self.root_view_type { - Some(WindowHandle { - any_handle: self, - view_type: PhantomData, - }) - } else { - None - } - } -} - -impl Drop for AnyWindowHandle { - fn drop(&mut self) { - if let Some(ref_counts) = self.ref_counts.as_ref() { - ref_counts.lock().dec_window(self.window_id); - - #[cfg(any(test, feature = "test-support"))] - ref_counts - .lock() - .leak_detector - .lock() - .handle_dropped(self.window_id, self.handle_id); - } - } -} - #[repr(transparent)] pub struct ViewHandle { any_handle: AnyViewHandle, @@ -6281,7 +6223,7 @@ mod tests { // Check that global actions do not have a binding, even if a binding does exist in another view assert_eq!( - &available_actions(window.id(), view_1.id(), cx), + &available_actions(window.window_id(), view_1.id(), cx), &[ ("test::Action1", vec![Keystroke::parse("a").unwrap()]), ("test::GlobalAction", vec![]) @@ -6290,7 +6232,7 @@ mod tests { // Check that view 1 actions and bindings are available even when called from view 2 assert_eq!( - &available_actions(window.id(), view_2.id(), cx), + &available_actions(window.window_id(), view_2.id(), cx), &[ ("test::Action1", vec![Keystroke::parse("a").unwrap()]), ("test::Action2", vec![Keystroke::parse("b").unwrap()]), @@ -6353,7 +6295,7 @@ mod tests { ]); }); - let actions = cx.available_actions(window.id(), view.id()); + let actions = cx.available_actions(window.window_id(), view.id()); assert_eq!( actions[0].1.as_any().downcast_ref::(), Some(&ActionWithArg { arg: false }) @@ -6639,25 +6581,25 @@ mod tests { [("window 2", false), ("window 3", true)] ); - cx.simulate_window_activation(Some(window_2.id())); + cx.simulate_window_activation(Some(window_2.window_id())); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 3", false), ("window 2", true)] ); - cx.simulate_window_activation(Some(window_1.id())); + cx.simulate_window_activation(Some(window_1.window_id())); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 2", false), ("window 1", true)] ); - cx.simulate_window_activation(Some(window_3.id())); + cx.simulate_window_activation(Some(window_3.window_id())); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 1", false), ("window 3", true)] ); - cx.simulate_window_activation(Some(window_3.id())); + cx.simulate_window_activation(Some(window_3.window_id())); assert_eq!(mem::take(&mut *events.borrow_mut()), []); } diff --git a/crates/gpui/src/app/ref_counts.rs b/crates/gpui/src/app/ref_counts.rs index 74563d05bc00d403dd768fe08fd269da9a8bfb5a..f0c1699f165ea8100ccdfe1facbfb8a3ac1a2d8e 100644 --- a/crates/gpui/src/app/ref_counts.rs +++ b/crates/gpui/src/app/ref_counts.rs @@ -25,7 +25,6 @@ struct ElementStateRefCount { pub struct RefCounts { entity_counts: HashMap, element_state_counts: HashMap, - dropped_windows: HashSet, dropped_models: HashSet, dropped_views: HashSet<(usize, usize)>, dropped_element_states: HashSet, @@ -44,18 +43,6 @@ impl RefCounts { } } - pub fn inc_window(&mut self, window_id: usize) { - match self.entity_counts.entry(window_id) { - Entry::Occupied(mut entry) => { - *entry.get_mut() += 1; - } - Entry::Vacant(entry) => { - entry.insert(1); - self.dropped_windows.remove(&window_id); - } - } - } - pub fn inc_model(&mut self, model_id: usize) { match self.entity_counts.entry(model_id) { Entry::Occupied(mut entry) => { @@ -98,15 +85,6 @@ impl RefCounts { } } - pub fn dec_window(&mut self, window_id: usize) { - let count = self.entity_counts.get_mut(&window_id).unwrap(); - *count -= 1; - if *count == 0 { - self.entity_counts.remove(&window_id); - self.dropped_windows.insert(window_id); - } - } - pub fn dec_model(&mut self, model_id: usize) { let count = self.entity_counts.get_mut(&model_id).unwrap(); *count -= 1; diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 0165c52e9f3fff9453c43484208c202a6a39138a..3b574eb03ee3f6cfcae23cffff8f1c5359828c66 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -157,9 +157,9 @@ impl TestAppContext { .cx .borrow_mut() .add_window(Default::default(), build_root_view); - self.simulate_window_activation(Some(window.id())); + self.simulate_window_activation(Some(window.window_id())); - WindowHandle::new(window.id(), self.cx.borrow_mut().ref_counts.clone()) + WindowHandle::new(window.window_id()) } pub fn add_view(&mut self, window_id: usize, build_view: F) -> ViewHandle diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 0149c310daaadd773e54dd58314261eb1864ecb6..789341d46fa4788e24c7b4d7b1e44d0558e1f3b7 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -1165,7 +1165,7 @@ impl<'a> WindowContext<'a> { let root_view = self.add_view(|cx| build_root_view(cx)); self.window.focused_view_id = Some(root_view.id()); self.window.root_view = Some(root_view.into_any()); - WindowHandle::new(self.window_id, self.ref_counts.clone()) + WindowHandle::new(self.window_id) } pub fn add_view(&mut self, build_view: F) -> ViewHandle diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 021ea2d3bc3a817342e9eac684496ffeee5026bb..80847f9f4b97b3dc2cf2c32d6d11f0ec7dcbcc3a 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1872,7 +1872,7 @@ mod tests { let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "root1", cx); @@ -2225,7 +2225,7 @@ mod tests { let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "root1", cx); @@ -2402,7 +2402,7 @@ mod tests { let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); toggle_expand_dir(&panel, "src/test", cx); @@ -2493,7 +2493,7 @@ mod tests { let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "src/", cx); diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index 8471f3a3a7014d2034438839f76ae9b4214ded52..4bd186fc98b3edb93bb4b2daa1b3e90633e3a0df 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -328,7 +328,7 @@ mod tests { let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); // Create the project symbols view. let symbols = cx.add_view(window_id, |cx| { diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 1e635432bd5c138f81410f3ac40ee461830ddb17..265e4f02061539a685322a446fef9f7d94b00ffb 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -851,11 +851,11 @@ mod tests { }); let window = cx.add_window(|_| EmptyView); - let editor = cx.add_view(window.id(), |cx| { + let editor = cx.add_view(window.window_id(), |cx| { Editor::for_buffer(buffer.clone(), None, cx) }); - let search_bar = cx.add_view(window.id(), |cx| { + let search_bar = cx.add_view(window.window_id(), |cx| { let mut search_bar = BufferSearchBar::new(cx); search_bar.set_active_pane_item(Some(&editor), cx); search_bar.show(cx); @@ -1232,7 +1232,7 @@ mod tests { ); let buffer = cx.add_model(|cx| Buffer::new(0, buffer_text, cx)); let window = cx.add_window(|_| EmptyView); - let window_id = window.id(); + let window_id = window.window_id(); let editor = cx.add_view(window_id, |cx| Editor::for_buffer(buffer.clone(), None, cx)); @@ -1421,11 +1421,11 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, buffer_text, cx)); let window = cx.add_window(|_| EmptyView); - let editor = cx.add_view(window.id(), |cx| { + let editor = cx.add_view(window.window_id(), |cx| { Editor::for_buffer(buffer.clone(), None, cx) }); - let search_bar = cx.add_view(window.id(), |cx| { + let search_bar = cx.add_view(window.window_id(), |cx| { let mut search_bar = BufferSearchBar::new(cx); search_bar.set_active_pane_item(Some(&editor), cx); search_bar.show(cx); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 0db66b4e378a56c97e2e2d1290742e52e1329bda..febd564050ddd0ea6355e83f69f505e80d924029 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1568,7 +1568,7 @@ pub mod tests { let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let active_item = cx.read(|cx| { workspace @@ -1874,7 +1874,7 @@ pub mod tests { let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); workspace.update(cx, |workspace, cx| { ProjectSearchView::deploy(workspace, &workspace::NewSearch, cx) }); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 2efa9f8daac69c872bda6cb3f7936d52d8d0222b..09e4c4c2193e8521cd8c7dc9841a361933497e73 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -4196,14 +4196,14 @@ mod tests { ); }); assert_eq!( - cx.current_window_title(window.id()).as_deref(), + cx.current_window_title(window.window_id()).as_deref(), Some("one.txt — root1") ); // Add a second item to a non-empty pane workspace.update(cx, |workspace, cx| workspace.add_item(Box::new(item2), cx)); assert_eq!( - cx.current_window_title(window.id()).as_deref(), + cx.current_window_title(window.window_id()).as_deref(), Some("two.txt — root1") ); project.read_with(cx, |project, cx| { @@ -4222,7 +4222,7 @@ mod tests { .await .unwrap(); assert_eq!( - cx.current_window_title(window.id()).as_deref(), + cx.current_window_title(window.window_id()).as_deref(), Some("one.txt — root1") ); project.read_with(cx, |project, cx| { @@ -4242,14 +4242,14 @@ mod tests { .await .unwrap(); assert_eq!( - cx.current_window_title(window.id()).as_deref(), + cx.current_window_title(window.window_id()).as_deref(), Some("one.txt — root1, root2") ); // Remove a project folder project.update(cx, |project, cx| project.remove_worktree(worktree_id, cx)); assert_eq!( - cx.current_window_title(window.id()).as_deref(), + cx.current_window_title(window.window_id()).as_deref(), Some("one.txt — root2") ); } @@ -4285,9 +4285,9 @@ mod tests { }); let task = workspace.update(cx, |w, cx| w.prepare_to_close(false, cx)); cx.foreground().run_until_parked(); - cx.simulate_prompt_answer(window.id(), 2 /* cancel */); + cx.simulate_prompt_answer(window.window_id(), 2 /* cancel */); cx.foreground().run_until_parked(); - assert!(!cx.has_pending_prompt(window.id())); + assert!(!cx.has_pending_prompt(window.window_id())); assert!(!task.await.unwrap()); } @@ -4346,10 +4346,10 @@ mod tests { assert_eq!(pane.items_len(), 4); assert_eq!(pane.active_item().unwrap().id(), item1.id()); }); - assert!(cx.has_pending_prompt(window.id())); + assert!(cx.has_pending_prompt(window.window_id())); // Confirm saving item 1. - cx.simulate_prompt_answer(window.id(), 0); + cx.simulate_prompt_answer(window.window_id(), 0); cx.foreground().run_until_parked(); // Item 1 is saved. There's a prompt to save item 3. @@ -4360,10 +4360,10 @@ mod tests { assert_eq!(pane.items_len(), 3); assert_eq!(pane.active_item().unwrap().id(), item3.id()); }); - assert!(cx.has_pending_prompt(window.id())); + assert!(cx.has_pending_prompt(window.window_id())); // Cancel saving item 3. - cx.simulate_prompt_answer(window.id(), 1); + cx.simulate_prompt_answer(window.window_id(), 1); cx.foreground().run_until_parked(); // Item 3 is reloaded. There's a prompt to save item 4. @@ -4374,10 +4374,10 @@ mod tests { assert_eq!(pane.items_len(), 2); assert_eq!(pane.active_item().unwrap().id(), item4.id()); }); - assert!(cx.has_pending_prompt(window.id())); + assert!(cx.has_pending_prompt(window.window_id())); // Confirm saving item 4. - cx.simulate_prompt_answer(window.id(), 0); + cx.simulate_prompt_answer(window.window_id(), 0); cx.foreground().run_until_parked(); // There's a prompt for a path for item 4. @@ -4480,7 +4480,7 @@ mod tests { &[ProjectEntryId::from_proto(0)] ); }); - cx.simulate_prompt_answer(window.id(), 0); + cx.simulate_prompt_answer(window.window_id(), 0); cx.foreground().run_until_parked(); left_pane.read_with(cx, |pane, cx| { @@ -4489,7 +4489,7 @@ mod tests { &[ProjectEntryId::from_proto(2)] ); }); - cx.simulate_prompt_answer(window.id(), 0); + cx.simulate_prompt_answer(window.window_id(), 0); cx.foreground().run_until_parked(); close.await.unwrap(); @@ -4549,7 +4549,7 @@ mod tests { item.read_with(cx, |item, _| assert_eq!(item.save_count, 2)); // Deactivating the window still saves the file. - cx.simulate_window_activation(Some(window.id())); + cx.simulate_window_activation(Some(window.window_id())); item.update(cx, |item, cx| { cx.focus_self(); item.is_dirty = true; @@ -4591,7 +4591,7 @@ mod tests { pane.update(cx, |pane, cx| pane.close_items(cx, move |id| id == item_id)) .await .unwrap(); - assert!(!cx.has_pending_prompt(window.id())); + assert!(!cx.has_pending_prompt(window.window_id())); item.read_with(cx, |item, _| assert_eq!(item.save_count, 5)); // Add the item again, ensuring autosave is prevented if the underlying file has been deleted. @@ -4612,7 +4612,7 @@ mod tests { let _close_items = pane.update(cx, |pane, cx| pane.close_items(cx, move |id| id == item_id)); deterministic.run_until_parked(); - assert!(cx.has_pending_prompt(window.id())); + assert!(cx.has_pending_prompt(window.window_id())); item.read_with(cx, |item, _| assert_eq!(item.save_count, 5)); } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index a459122cfc9a29b209f8d6cbcf7031f739781857..1c65317c413b67f6f3764c5dad2b71e2e9581d01 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1299,7 +1299,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); // Open a file within an existing worktree. workspace @@ -1342,7 +1342,7 @@ mod tests { project.update(cx, |project, _| project.languages().add(rust_lang())); let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let worktree = cx.read(|cx| workspace.read(cx).worktrees(cx).next().unwrap()); // Create a new untitled buffer @@ -1437,7 +1437,7 @@ mod tests { project.update(cx, |project, _| project.languages().add(rust_lang())); let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); // Create a new untitled buffer cx.dispatch_action(window_id, NewFile); @@ -1490,7 +1490,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); + let window_id = window.window_id(); let entries = cx.read(|cx| workspace.file_project_paths(cx)); let file1 = entries[0].clone(); @@ -2088,7 +2088,7 @@ mod tests { cx.foreground().run_until_parked(); let window = cx.add_window(|_| TestView); - let window_id = window.id(); + let window_id = window.window_id(); // Test loading the keymap base at all assert_key_bindings_for( @@ -2259,7 +2259,7 @@ mod tests { cx.foreground().run_until_parked(); let window = cx.add_window(|_| TestView); - let window_id = window.id(); + let window_id = window.window_id(); // Test loading the keymap base at all assert_key_bindings_for( From 2d96388be369259c5e8b6006bfe81cfe979889a3 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 3 Aug 2023 17:46:34 -0600 Subject: [PATCH 122/160] Use WindowHandles in a couple places --- crates/copilot/src/sign_in.rs | 44 ++++++++++++++++---------------- crates/gpui/src/app.rs | 47 ++++++++++++++++------------------- 2 files changed, 43 insertions(+), 48 deletions(-) diff --git a/crates/copilot/src/sign_in.rs b/crates/copilot/src/sign_in.rs index 0d5bb28ed688897e67ecccd816215f68ce573fd7..d03a2d393bfd345a478d66aa68998ae3759d7940 100644 --- a/crates/copilot/src/sign_in.rs +++ b/crates/copilot/src/sign_in.rs @@ -18,42 +18,42 @@ const COPILOT_SIGN_UP_URL: &'static str = "https://github.com/features/copilot"; pub fn init(cx: &mut AppContext) { if let Some(copilot) = Copilot::global(cx) { - let mut code_verification: Option> = None; + let mut verification_window: Option> = None; cx.observe(&copilot, move |copilot, cx| { let status = copilot.read(cx).status(); match &status { crate::Status::SigningIn { prompt } => { - if let Some(code_verification_handle) = code_verification.as_mut() { - let window_id = code_verification_handle.window_id(); - let updated = cx.update_window(window_id, |cx| { - code_verification_handle.update_root(cx, |code_verification, cx| { - code_verification.set_status(status.clone(), cx) - }); - cx.activate_window(); - }); - if updated.is_none() { - code_verification = Some(create_copilot_auth_window(cx, &status)); + if let Some(window) = verification_window.as_mut() { + let updated = window + .root(cx) + .map(|root| { + root.update(cx, |verification, cx| { + verification.set_status(status.clone(), cx); + cx.activate_window(); + }) + }) + .is_some(); + if !updated { + verification_window = Some(create_copilot_auth_window(cx, &status)); } } else if let Some(_prompt) = prompt { - code_verification = Some(create_copilot_auth_window(cx, &status)); + verification_window = Some(create_copilot_auth_window(cx, &status)); } } Status::Authorized | Status::Unauthorized => { - if let Some(code_verification) = code_verification.as_ref() { - let window_id = code_verification.window_id(); - cx.update_window(window_id, |cx| { - code_verification.update_root(cx, |code_verification, cx| { - code_verification.set_status(status, cx) + if let Some(window) = verification_window.as_ref() { + if let Some(verification) = window.root(cx) { + verification.update(cx, |verification, cx| { + verification.set_status(status, cx); + cx.platform().activate(true); + cx.activate_window(); }); - - cx.platform().activate(true); - cx.activate_window(); - }); + } } } _ => { - if let Some(code_verification) = code_verification.take() { + if let Some(code_verification) = verification_window.take() { code_verification.update(cx, |cx| cx.remove_window()); } } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 90f910d255ff595bd1e2c0e1173296180e10c8fc..d98033820bb60853403960adba3183f10782ce95 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -808,7 +808,7 @@ impl AppContext { result } - pub fn read_window T>( + fn read_window T>( &self, window_id: usize, callback: F, @@ -3892,31 +3892,26 @@ impl WindowHandle { cx.read_window_with(self.window_id(), |cx| read(cx)) } - pub fn update(&self, cx: &mut C, update: F) -> R + pub fn update(&self, cx: &mut C, update: F) -> C::Result where - C: BorrowAppContext, + C: BorrowWindowContext, F: FnOnce(&mut WindowContext) -> R, { - cx.update(|cx| cx.update_window(self.window_id(), update).unwrap()) - } - - pub fn update_root(&self, cx: &mut C, update: F) -> R - where - C: BorrowAppContext, - F: FnOnce(&mut V, &mut ViewContext) -> R, - { - let window_id = self.window_id(); - cx.update(|cx| { - cx.update_window(window_id, |cx| { - cx.root_view() - .clone() - .downcast::() - .unwrap() - .update(cx, update) - }) - .unwrap() - }) - } + cx.update_window(self.window_id(), update) + } + + // pub fn update_root(&self, cx: &mut C, update: F) -> C::Result> + // where + // C: BorrowWindowContext, + // F: FnOnce(&mut V, &mut ViewContext) -> R, + // { + // cx.update_window(self.window_id, |cx| { + // cx.root_view() + // .clone() + // .downcast::() + // .map(|v| v.update(cx, update)) + // }) + // } pub fn read_root<'a>(&self, cx: &'a AppContext) -> &'a V { let root_view = cx @@ -3940,9 +3935,9 @@ impl WindowHandle { }) } - pub fn add_view(&self, cx: &mut C, build_view: F) -> ViewHandle + pub fn add_view(&self, cx: &mut C, build_view: F) -> C::Result> where - C: BorrowAppContext, + C: BorrowWindowContext, U: View, F: FnOnce(&mut ViewContext) -> U, { @@ -4836,7 +4831,7 @@ mod tests { let called_defer = Rc::new(AtomicBool::new(false)); let called_after_window_update = Rc::new(AtomicBool::new(false)); - window.update_root(cx, |this, cx| { + window.root(cx).update(cx, |this, cx| { assert_eq!(this.render_count, 1); cx.defer({ let called_defer = called_defer.clone(); From 8c98b02e457ffb2fb0f457e9e2834ebbc9bebdd7 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Fri, 4 Aug 2023 15:09:08 -0400 Subject: [PATCH 123/160] Add `convert to {upper,lower} case` commands Co-Authored-By: Julia <30666851+ForLoveOfCats@users.noreply.github.com> --- crates/editor/src/editor.rs | 66 +++++++++++++++++++++++++++++++ crates/editor/src/editor_tests.rs | 59 +++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index a4d9259a6d7e7a63dc1606450ecef9d2aa4c53f4..ab952ba6e727fe7ced14fdcc37280bcb31ccfc9d 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -231,6 +231,8 @@ actions!( SortLinesCaseInsensitive, ReverseLines, ShuffleLines, + ConvertToUpperCase, + ConvertToLowerCase, Transpose, Cut, Copy, @@ -353,6 +355,8 @@ pub fn init(cx: &mut AppContext) { cx.add_action(Editor::sort_lines_case_insensitive); cx.add_action(Editor::reverse_lines); cx.add_action(Editor::shuffle_lines); + cx.add_action(Editor::convert_to_upper_case); + cx.add_action(Editor::convert_to_lower_case); cx.add_action(Editor::delete_to_previous_word_start); cx.add_action(Editor::delete_to_previous_subword_start); cx.add_action(Editor::delete_to_next_word_end); @@ -4306,6 +4310,68 @@ impl Editor { }); } + pub fn convert_to_upper_case(&mut self, _: &ConvertToUpperCase, cx: &mut ViewContext) { + self.manipulate_text(cx, |text| text.to_uppercase()) + } + + pub fn convert_to_lower_case(&mut self, _: &ConvertToLowerCase, cx: &mut ViewContext) { + self.manipulate_text(cx, |text| text.to_lowercase()) + } + + fn manipulate_text(&mut self, cx: &mut ViewContext, mut callback: Fn) + where + Fn: FnMut(&str) -> String, + { + let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); + let buffer = self.buffer.read(cx).snapshot(cx); + + let mut new_selections = Vec::new(); + let mut edits = Vec::new(); + for selection in self.selections.all::(cx) { + let selection_is_empty = selection.is_empty(); + + let (start, end) = if selection_is_empty { + let word_range = movement::surrounding_word( + &display_map, + selection.start.to_display_point(&display_map), + ); + let start = word_range.start.to_offset(&display_map, Bias::Left); + let end = word_range.end.to_offset(&display_map, Bias::Left); + (start, end) + } else { + (selection.start, selection.end) + }; + + let text = buffer.text_for_range(start..end).collect::(); + let text = callback(&text); + + if selection_is_empty { + new_selections.push(selection); + } else { + new_selections.push(Selection { + start, + end: start + text.len(), + goal: SelectionGoal::None, + ..selection + }); + } + + edits.push((start..end, text)); + } + + self.transact(cx, |this, cx| { + this.buffer.update(cx, |buffer, cx| { + buffer.edit(edits, None, cx); + }); + + this.change_selections(Some(Autoscroll::fit()), cx, |s| { + s.select(new_selections); + }); + + this.request_autoscroll(Autoscroll::fit(), cx); + }); + } + 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; diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index e8913505cab0d579afa7d1621fa54398a985844e..11d64f085cd35141aa98ff2bbafe20b5c51d96d4 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -2695,6 +2695,65 @@ async fn test_manipulate_lines_with_multi_selection(cx: &mut TestAppContext) { "}); } +#[gpui::test] +async fn test_manipulate_text(cx: &mut TestAppContext) { + init_test(cx, |_| {}); + + let mut cx = EditorTestContext::new(cx).await; + + // Test convert_to_upper_case() + cx.set_state(indoc! {" + «hello worldˇ» + "}); + cx.update_editor(|e, cx| e.convert_to_upper_case(&ConvertToUpperCase, cx)); + cx.assert_editor_state(indoc! {" + «HELLO WORLDˇ» + "}); + + // Test convert_to_lower_case() + cx.set_state(indoc! {" + «HELLO WORLDˇ» + "}); + cx.update_editor(|e, cx| e.convert_to_lower_case(&ConvertToLowerCase, cx)); + cx.assert_editor_state(indoc! {" + «hello worldˇ» + "}); + + // From here on out, test more complex cases of manipulate_text() with a single driver method: convert_to_upper_case() + + // Test no selection case - should affect words cursors are in + // Cursor at beginning, middle, and end of word + cx.set_state(indoc! {" + ˇhello big beauˇtiful worldˇ + "}); + cx.update_editor(|e, cx| e.convert_to_upper_case(&ConvertToUpperCase, cx)); + cx.assert_editor_state(indoc! {" + ˇHELLO big BEAUˇTIFUL WORLDˇ + "}); + + // Test multiple selections on a single line and across multiple lines + cx.set_state(indoc! {" + «Theˇ» quick «brown + foxˇ» jumps «overˇ» + the «lazyˇ» dog + "}); + cx.update_editor(|e, cx| e.convert_to_upper_case(&ConvertToUpperCase, cx)); + cx.assert_editor_state(indoc! {" + «THEˇ» quick «BROWN + FOXˇ» jumps «OVERˇ» + the «LAZYˇ» dog + "}); + + // Test case where text length grows + cx.set_state(indoc! {" + «tschüߡ» + "}); + cx.update_editor(|e, cx| e.convert_to_upper_case(&ConvertToUpperCase, cx)); + cx.assert_editor_state(indoc! {" + «TSCHÜSSˇ» + "}); +} + #[gpui::test] fn test_duplicate_line(cx: &mut TestAppContext) { init_test(cx, |_| {}); From 12e8f417e4ca3ff1d7aa019825b40c3b3d779483 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Fri, 4 Aug 2023 22:37:29 -0400 Subject: [PATCH 124/160] Add more convert to case commands ConvertToTitleCase ConvertToSnakeCase ConvertToKebabCase ConvertToUpperCamelCase ConvertToLowerCamelCase --- Cargo.lock | 10 ++++++++++ crates/editor/Cargo.toml | 3 ++- crates/editor/src/editor.rs | 39 +++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index fbf4e750c62c920a7158c712d48c4f6cd380bf6f..5afa1ebe6252ddabeb77067c2786d89301041a99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1649,6 +1649,15 @@ dependencies = [ "theme", ] +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "copilot" version = "0.1.0" @@ -2314,6 +2323,7 @@ dependencies = [ "clock", "collections", "context_menu", + "convert_case", "copilot", "ctor", "db", diff --git a/crates/editor/Cargo.toml b/crates/editor/Cargo.toml index bc1c904404972cb847947b8c60147bcf4a41186b..2fdeee56c18150aa1f38f97176f288fe54412a21 100644 --- a/crates/editor/Cargo.toml +++ b/crates/editor/Cargo.toml @@ -47,6 +47,7 @@ workspace = { path = "../workspace" } aho-corasick = "0.7" anyhow.workspace = true +convert_case = "0.6.0" futures.workspace = true indoc = "1.0.4" itertools = "0.10" @@ -56,12 +57,12 @@ ordered-float.workspace = true parking_lot.workspace = true postage.workspace = true pulldown-cmark = { version = "0.9.2", default-features = false } +rand.workspace = true schemars.workspace = true serde.workspace = true serde_derive.workspace = true smallvec.workspace = true smol.workspace = true -rand.workspace = true tree-sitter-rust = { workspace = true, optional = true } tree-sitter-html = { workspace = true, optional = true } diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index ab952ba6e727fe7ced14fdcc37280bcb31ccfc9d..c70a1a8e048a62c87b9576547da8f6d6c62fb013 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -28,6 +28,7 @@ use blink_manager::BlinkManager; use client::{ClickhouseEvent, TelemetrySettings}; use clock::{Global, ReplicaId}; use collections::{BTreeMap, Bound, HashMap, HashSet, VecDeque}; +use convert_case::{Case, Casing}; use copilot::Copilot; pub use display_map::DisplayPoint; use display_map::*; @@ -233,6 +234,11 @@ actions!( ShuffleLines, ConvertToUpperCase, ConvertToLowerCase, + ConvertToTitleCase, + ConvertToSnakeCase, + ConvertToKebabCase, + ConvertToUpperCamelCase, + ConvertToLowerCamelCase, Transpose, Cut, Copy, @@ -357,6 +363,11 @@ pub fn init(cx: &mut AppContext) { cx.add_action(Editor::shuffle_lines); cx.add_action(Editor::convert_to_upper_case); cx.add_action(Editor::convert_to_lower_case); + cx.add_action(Editor::convert_to_title_case); + cx.add_action(Editor::convert_to_snake_case); + cx.add_action(Editor::convert_to_kebab_case); + cx.add_action(Editor::convert_to_upper_camel_case); + cx.add_action(Editor::convert_to_lower_camel_case); cx.add_action(Editor::delete_to_previous_word_start); cx.add_action(Editor::delete_to_previous_subword_start); cx.add_action(Editor::delete_to_next_word_end); @@ -4318,6 +4329,34 @@ impl Editor { self.manipulate_text(cx, |text| text.to_lowercase()) } + pub fn convert_to_title_case(&mut self, _: &ConvertToTitleCase, cx: &mut ViewContext) { + self.manipulate_text(cx, |text| text.to_case(Case::Title)) + } + + pub fn convert_to_snake_case(&mut self, _: &ConvertToSnakeCase, cx: &mut ViewContext) { + self.manipulate_text(cx, |text| text.to_case(Case::Snake)) + } + + pub fn convert_to_kebab_case(&mut self, _: &ConvertToKebabCase, cx: &mut ViewContext) { + self.manipulate_text(cx, |text| text.to_case(Case::Kebab)) + } + + pub fn convert_to_upper_camel_case( + &mut self, + _: &ConvertToUpperCamelCase, + cx: &mut ViewContext, + ) { + self.manipulate_text(cx, |text| text.to_case(Case::UpperCamel)) + } + + pub fn convert_to_lower_camel_case( + &mut self, + _: &ConvertToLowerCamelCase, + cx: &mut ViewContext, + ) { + self.manipulate_text(cx, |text| text.to_case(Case::Camel)) + } + fn manipulate_text(&mut self, cx: &mut ViewContext, mut callback: Fn) where Fn: FnMut(&str) -> String, From 1abb6a0176feb0b1fe78553a08a2f6675654a8cf Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Sat, 5 Aug 2023 11:31:21 -0400 Subject: [PATCH 125/160] Expand empty selections to cover full word and fix bugs --- crates/editor/src/editor.rs | 21 +++++++++++---------- crates/editor/src/editor_tests.rs | 23 +++++++++++++++++++++-- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index c70a1a8e048a62c87b9576547da8f6d6c62fb013..cd5e86b91098b35cad385331d5e8f28a380d3139 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -4366,6 +4366,8 @@ impl Editor { let mut new_selections = Vec::new(); let mut edits = Vec::new(); + let mut selection_adjustment = 0i32; + for selection in self.selections.all::(cx) { let selection_is_empty = selection.is_empty(); @@ -4382,18 +4384,17 @@ impl Editor { }; let text = buffer.text_for_range(start..end).collect::(); + let old_length = text.len() as i32; let text = callback(&text); - if selection_is_empty { - new_selections.push(selection); - } else { - new_selections.push(Selection { - start, - end: start + text.len(), - goal: SelectionGoal::None, - ..selection - }); - } + new_selections.push(Selection { + start: (start as i32 - selection_adjustment) as usize, + end: ((start + text.len()) as i32 - selection_adjustment) as usize, + goal: SelectionGoal::None, + ..selection + }); + + selection_adjustment += old_length - text.len() as i32; edits.push((start..end, text)); } diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 11d64f085cd35141aa98ff2bbafe20b5c51d96d4..7e39647ac6370bcb3bba1ff0721764c6e3ee542d 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -2719,7 +2719,7 @@ async fn test_manipulate_text(cx: &mut TestAppContext) { «hello worldˇ» "}); - // From here on out, test more complex cases of manipulate_text() with a single driver method: convert_to_upper_case() + // From here on out, test more complex cases of manipulate_text() // Test no selection case - should affect words cursors are in // Cursor at beginning, middle, and end of word @@ -2728,7 +2728,7 @@ async fn test_manipulate_text(cx: &mut TestAppContext) { "}); cx.update_editor(|e, cx| e.convert_to_upper_case(&ConvertToUpperCase, cx)); cx.assert_editor_state(indoc! {" - ˇHELLO big BEAUˇTIFUL WORLDˇ + «HELLOˇ» big «BEAUTIFULˇ» «WORLDˇ» "}); // Test multiple selections on a single line and across multiple lines @@ -2752,6 +2752,25 @@ async fn test_manipulate_text(cx: &mut TestAppContext) { cx.assert_editor_state(indoc! {" «TSCHÜSSˇ» "}); + + // Test to make sure we don't crash when text shrinks + cx.set_state(indoc! {" + aaa_bbbˇ + "}); + cx.update_editor(|e, cx| e.convert_to_lower_camel_case(&ConvertToLowerCamelCase, cx)); + cx.assert_editor_state(indoc! {" + «aaaBbbˇ» + "}); + + // Test to make sure we all aware of the fact that each word can grow and shrink + // Final selections should be aware of this fact + cx.set_state(indoc! {" + aaa_bˇbb bbˇb_ccc ˇccc_ddd + "}); + cx.update_editor(|e, cx| e.convert_to_lower_camel_case(&ConvertToLowerCamelCase, cx)); + cx.assert_editor_state(indoc! {" + «aaaBbbˇ» «bbbCccˇ» «cccDddˇ» + "}); } #[gpui::test] From dcf8b00656eab32299338c2a63b69dc128fff19d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 5 Aug 2023 18:00:44 -0600 Subject: [PATCH 126/160] WIP --- crates/gpui/src/app.rs | 59 ++++++++++++++++++++--------------- crates/gpui/src/app/window.rs | 2 +- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index d98033820bb60853403960adba3183f10782ce95..62d7d1d48aef6413dbfa3aed4e05d93dc32cf413 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1442,7 +1442,7 @@ impl AppContext { window } - pub fn replace_root_view( + pub(crate) fn replace_root_view( &mut self, window_id: usize, build_root_view: F, @@ -3900,28 +3900,6 @@ impl WindowHandle { cx.update_window(self.window_id(), update) } - // pub fn update_root(&self, cx: &mut C, update: F) -> C::Result> - // where - // C: BorrowWindowContext, - // F: FnOnce(&mut V, &mut ViewContext) -> R, - // { - // cx.update_window(self.window_id, |cx| { - // cx.root_view() - // .clone() - // .downcast::() - // .map(|v| v.update(cx, update)) - // }) - // } - - pub fn read_root<'a>(&self, cx: &'a AppContext) -> &'a V { - let root_view = cx - .read_window(self.window_id(), |cx| { - cx.root_view().clone().downcast().unwrap() - }) - .unwrap(); - root_view.read(cx) - } - pub fn read_root_with(&self, cx: &C, read: F) -> C::Result where C: BorrowWindowContext, @@ -3935,6 +3913,20 @@ impl WindowHandle { }) } + pub fn update_root(&self, cx: &mut C, update: F) -> C::Result + where + C: BorrowWindowContext, + F: FnOnce(&mut V, &mut ViewContext) -> R, + { + cx.update_window(self.window_id, |cx| { + cx.root_view() + .clone() + .downcast::() + .unwrap() + .update(cx, update) + }) + } + pub fn add_view(&self, cx: &mut C, build_view: F) -> C::Result> where C: BorrowWindowContext, @@ -3943,6 +3935,23 @@ impl WindowHandle { { self.update(cx, |cx| cx.add_view(build_view)) } + + pub(crate) fn replace_root_view( + &self, + cx: &mut C, + build_root_view: F, + ) -> C::Result> + where + C: BorrowWindowContext, + F: FnOnce(&mut ViewContext) -> V, + { + cx.update_window(self.window_id, |cx| { + let root_view = self.add_view(cx, |cx| build_root_view(cx)); + cx.window.root_view = Some(root_view.clone().into_any()); + cx.window.focused_view_id = Some(root_view.id()); + root_view + }) + } } #[repr(transparent)] @@ -5329,7 +5338,7 @@ mod tests { TestView { events: Vec::new() } }); - assert_eq!(window.read_root(cx).events, ["before emit"]); + window.read_root_with(cx, |view, _| assert_eq!(view.events, ["before emit"])); } #[crate::test(self)] @@ -5381,7 +5390,7 @@ mod tests { TestView { events: Vec::new() } }); - assert_eq!(window.read_root(cx).events, ["before notify"]); + assert_eq!(window.read_root_with(cx, |view, _| assert_eq!(view.events, ["before notify"]))); } #[crate::test(self)] diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 789341d46fa4788e24c7b4d7b1e44d0558e1f3b7..20992bfbaad03e03888e9971c8f4f88f829cdf46 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -1157,7 +1157,7 @@ impl<'a> WindowContext<'a> { self.window.platform_window.prompt(level, msg, answers) } - pub fn replace_root_view(&mut self, build_root_view: F) -> WindowHandle + pub(crate) fn replace_root_view(&mut self, build_root_view: F) -> WindowHandle where V: View, F: FnOnce(&mut ViewContext) -> V, From ef5b982ea5901f9f5ef78854e1bcba93b77dd2b6 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Sun, 6 Aug 2023 02:20:31 -0400 Subject: [PATCH 127/160] Fix bash path_suffixes and add line_comment --- crates/zed/src/languages/bash/config.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/zed/src/languages/bash/config.toml b/crates/zed/src/languages/bash/config.toml index 80b8753d80105f91ea9c0b802a2fe11ea61557c4..d03897a071d78c55c48ac97c4e829c7d2e05db1f 100644 --- a/crates/zed/src/languages/bash/config.toml +++ b/crates/zed/src/languages/bash/config.toml @@ -1,5 +1,6 @@ name = "Shell Script" -path_suffixes = [".sh", ".bash", ".bashrc", ".bash_profile", ".bash_aliases", ".bash_logout", ".profile", ".zsh", ".zshrc", ".zshenv", ".zsh_profile", ".zsh_aliases", ".zsh_histfile", ".zlogin"] +path_suffixes = ["sh", "bash", "bashrc", "bash_profile", "bash_aliases", "bash_logout", "profile", "zsh", "zshrc", "zshenv", "zsh_profile", "zsh_aliases", "zsh_histfile", "zlogin"] +line_comment = "# " first_line_pattern = "^#!.*\\b(?:ba|z)?sh\\b" brackets = [ { start = "[", end = "]", close = true, newline = false }, From adc50469ff0c938415c4995ce8ed7fb761021a68 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sun, 6 Aug 2023 12:45:31 -0600 Subject: [PATCH 128/160] WIP --- Cargo.lock | 39 ++- Cargo.toml | 1 + crates/collab/src/tests/integration_tests.rs | 4 +- .../src/incoming_call_notification.rs | 2 +- .../src/project_shared_notification.rs | 2 +- crates/command_palette/src/command_palette.rs | 2 +- crates/diagnostics/src/diagnostics.rs | 4 +- crates/editor/src/editor_tests.rs | 2 +- .../src/test/editor_lsp_test_context.rs | 2 +- crates/editor/src/test/editor_test_context.rs | 2 +- crates/file_finder/src/file_finder.rs | 22 +- crates/gpui/Cargo.toml | 1 + crates/gpui/src/app.rs | 264 +++++++++--------- crates/gpui/src/app/test_app_context.rs | 33 ++- crates/gpui/src/app/window.rs | 21 +- crates/project_panel/src/project_panel.rs | 8 +- crates/project_symbols/src/project_symbols.rs | 2 +- crates/search/src/buffer_search.rs | 10 +- crates/search/src/project_search.rs | 4 +- crates/workspace/src/workspace.rs | 165 +++++------ crates/zed/src/zed.rs | 20 +- 21 files changed, 331 insertions(+), 279 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fbf4e750c62c920a7158c712d48c4f6cd380bf6f..6cd36252d1b8f09fd0a88027b09d4e4da0d7524b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1649,6 +1649,12 @@ dependencies = [ "theme", ] +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "copilot" version = "0.1.0" @@ -2133,6 +2139,19 @@ dependencies = [ "serde", ] +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn 1.0.109", +] + [[package]] name = "dhat" version = "0.3.2" @@ -3096,6 +3115,7 @@ dependencies = [ "core-graphics", "core-text", "ctor", + "derive_more", "dhat", "env_logger 0.9.3", "etagere", @@ -5106,7 +5126,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39fe46acc5503595e5949c17b818714d26fdf9b4920eacf3b2947f0199f4a6ff" dependencies = [ - "rustc_version", + "rustc_version 0.3.3", ] [[package]] @@ -6276,7 +6296,16 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" dependencies = [ - "semver", + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.18", ] [[package]] @@ -6716,6 +6745,12 @@ dependencies = [ "semver-parser", ] +[[package]] +name = "semver" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" + [[package]] name = "semver-parser" version = "0.10.2" diff --git a/Cargo.toml b/Cargo.toml index 6e79c6b6576c290a4a0e85e56a80cfe9b100ff2b..1938e832e9cdb74c26a96abfa150f09b23a97d75 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,6 +79,7 @@ resolver = "2" anyhow = { version = "1.0.57" } async-trait = { version = "0.1" } ctor = { version = "0.1" } +derive_more = { version = "0.99.17" } env_logger = { version = "0.9" } futures = { version = "0.3" } globset = { version = "0.4" } diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index 037f97f71abc8a5961b3693c461522af985fbb55..1a8e6d938d6d6caac2b8caee501e1088ddeea5b3 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -3446,7 +3446,7 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor( let editor_a = window_a.add_view(cx_a, |cx| Editor::for_buffer(buffer_a, Some(project_a), cx)); let mut editor_cx_a = EditorTestContext { cx: cx_a, - window_id: window_a.window_id(), + window_id: window_a.id(), editor: editor_a, }; @@ -3459,7 +3459,7 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor( let editor_b = window_b.add_view(cx_b, |cx| Editor::for_buffer(buffer_b, Some(project_b), cx)); let mut editor_cx_b = EditorTestContext { cx: cx_b, - window_id: window_b.window_id(), + window_id: window_b.id(), editor: editor_b, }; diff --git a/crates/collab_ui/src/incoming_call_notification.rs b/crates/collab_ui/src/incoming_call_notification.rs index 770f5d5795c980df75a4ce0f888f72745f63970e..a9c5e697a5f60d0cb6f9c0e6baf7cac50aba192a 100644 --- a/crates/collab_ui/src/incoming_call_notification.rs +++ b/crates/collab_ui/src/incoming_call_notification.rs @@ -49,7 +49,7 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { |_| IncomingCallNotification::new(incoming_call.clone(), app_state.clone()), ); - notification_windows.push(window.window_id()); + notification_windows.push(window.id()); } } } diff --git a/crates/collab_ui/src/project_shared_notification.rs b/crates/collab_ui/src/project_shared_notification.rs index 5be7e33bf3cea049569ce294dbb3d8b1942cf38f..03ab91623b43270bf2592ced0f460b474fd0c435 100644 --- a/crates/collab_ui/src/project_shared_notification.rs +++ b/crates/collab_ui/src/project_shared_notification.rs @@ -52,7 +52,7 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { notification_windows .entry(*project_id) .or_insert(Vec::new()) - .push(window.window_id()); + .push(window.id()); } } room::Event::RemoteProjectUnshared { project_id } => { diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 935358c2a126bfd59f90ffe89f7b7825063af8c9..7d4b4126b702774bf8c295d3b61f904ff7ebf80c 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -297,7 +297,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), [], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let editor = cx.add_view(window_id, |cx| { let mut editor = Editor::single_line(None, cx); editor.set_text("abc", cx); diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index f2db0a7763054d19ea85b591de6e8b8d63272740..2444465be666124adb706bcf1833c50c77cee081 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -857,7 +857,7 @@ mod tests { let project = Project::test(fs.clone(), ["/test".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); // Create some diagnostics project.update(cx, |project, cx| { @@ -1252,7 +1252,7 @@ mod tests { let project = Project::test(fs.clone(), ["/test".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let view = cx.add_view(window_id, |cx| { ProjectDiagnosticsEditor::new(project.clone(), workspace.downgrade(), cx) diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index e8913505cab0d579afa7d1621fa54398a985844e..a114cd437b16bbad580d6e732bb004ac352d822a 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -525,7 +525,7 @@ async fn test_navigation_history(cx: &mut TestAppContext) { let project = Project::test(fs, [], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); cx.add_view(window_id, |cx| { let buffer = MultiBuffer::build_simple(&sample_text(300, 5, 'a'), cx); diff --git a/crates/editor/src/test/editor_lsp_test_context.rs b/crates/editor/src/test/editor_lsp_test_context.rs index d25ca7bb88a86383166288fcb1ac6cd5cfd5997f..f53115f224a1cfe6cb4a3c634786c7e7e8c18305 100644 --- a/crates/editor/src/test/editor_lsp_test_context.rs +++ b/crates/editor/src/test/editor_lsp_test_context.rs @@ -99,7 +99,7 @@ impl<'a> EditorLspTestContext<'a> { Self { cx: EditorTestContext { cx, - window_id: window.window_id(), + window_id: window.id(), editor, }, lsp, diff --git a/crates/editor/src/test/editor_test_context.rs b/crates/editor/src/test/editor_test_context.rs index ac519764fdd8b671a92070118ec9b4937d135c64..c7ea1b4f3852301e300c5ff3f1db1dff65f342a2 100644 --- a/crates/editor/src/test/editor_test_context.rs +++ b/crates/editor/src/test/editor_test_context.rs @@ -39,7 +39,7 @@ impl<'a> EditorTestContext<'a> { let editor = window.root(cx); Self { cx, - window_id: window.window_id(), + window_id: window.id(), editor, } } diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 84a45b083e6fdef0a2b4145e756f495fdc255300..12bf3242627619d390409bba044c0fa9cdcce3d4 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -619,7 +619,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.window_id(), Toggle); + cx.dispatch_action(window.id(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); finder @@ -632,8 +632,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.window_id(), SelectNext); - cx.dispatch_action(window.window_id(), Confirm); + cx.dispatch_action(window.id(), SelectNext); + cx.dispatch_action(window.id(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -674,7 +674,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.window_id(), Toggle); + cx.dispatch_action(window.id(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); let file_query = &first_file_name[..3]; @@ -706,8 +706,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.window_id(), SelectNext); - cx.dispatch_action(window.window_id(), Confirm); + cx.dispatch_action(window.id(), SelectNext); + cx.dispatch_action(window.id(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -758,7 +758,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.window_id(), Toggle); + cx.dispatch_action(window.id(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); let file_query = &first_file_name[..3]; @@ -790,8 +790,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.window_id(), SelectNext); - cx.dispatch_action(window.window_id(), Confirm); + cx.dispatch_action(window.id(), SelectNext); + cx.dispatch_action(window.id(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -1168,7 +1168,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1); @@ -1376,7 +1376,7 @@ mod tests { let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1,); diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index 31b7db008d28d56849c7ce36eb3f23336fe82fad..5bd7d0318439d2cbd46667f585be37ae25efa33e 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -22,6 +22,7 @@ sqlez = { path = "../sqlez" } async-task = "4.0.3" backtrace = { version = "0.3", optional = true } ctor.workspace = true +derive_more.workspace = true dhat = { version = "0.3", optional = true } env_logger = { version = "0.9", optional = true } etagere = "0.2" diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 62d7d1d48aef6413dbfa3aed4e05d93dc32cf413..f967f134039081c1a89c71385e2fc25124a32bf3 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -23,6 +23,7 @@ use std::{ }; use anyhow::{anyhow, Context, Result}; +use derive_more::Deref; use parking_lot::Mutex; use postage::oneshot; use smallvec::SmallVec; @@ -132,11 +133,13 @@ pub trait BorrowAppContext { pub trait BorrowWindowContext { type Result; - fn read_window_with(&self, window_id: usize, f: F) -> Self::Result + fn read_window_with(&self, window_handle: H, f: F) -> Self::Result where + H: Into, F: FnOnce(&WindowContext) -> T; - fn update_window(&mut self, window_id: usize, f: F) -> Self::Result + fn update_window(&mut self, window_handle: H, f: F) -> Self::Result where + H: Into, F: FnOnce(&mut WindowContext) -> T; } @@ -300,13 +303,13 @@ impl App { result } - fn update_window T>( - &mut self, - window_id: usize, - callback: F, - ) -> Option { + fn update_window(&mut self, handle: H, callback: F) -> Option + where + H: Into, + F: FnOnce(&mut WindowContext) -> T, + { let mut state = self.0.borrow_mut(); - let result = state.update_window(window_id, callback); + let result = state.update_window(handle, callback); state.pending_notifications.clear(); result } @@ -333,6 +336,10 @@ impl AsyncAppContext { self.0.borrow_mut().update(callback) } + pub fn windows(&self) -> Vec { + self.0.borrow().windows().collect() + } + pub fn read_window T>( &self, window_id: usize, @@ -343,10 +350,10 @@ impl AsyncAppContext { pub fn update_window T>( &mut self, - window_id: usize, + handle: AnyWindowHandle, callback: F, ) -> Option { - self.0.borrow_mut().update_window(window_id, callback) + self.0.borrow_mut().update_window(handle, callback) } pub fn debug_elements(&self, window_id: usize) -> Option { @@ -359,14 +366,14 @@ impl AsyncAppContext { pub fn dispatch_action( &mut self, - window_id: usize, + window: impl Into, view_id: usize, action: &dyn Action, ) -> Result<()> { self.0 .borrow_mut() - .update_window(window_id, |window| { - window.dispatch_action(Some(view_id), action); + .update_window(window, |cx| { + cx.dispatch_action(Some(view_id), action); }) .ok_or_else(|| anyhow!("window not found")) } @@ -380,22 +387,6 @@ impl AsyncAppContext { .unwrap_or_default() } - pub fn has_window(&self, window_id: usize) -> bool { - self.read(|cx| cx.windows.contains_key(&window_id)) - } - - pub fn window_is_active(&self, window_id: usize) -> bool { - self.read(|cx| cx.windows.get(&window_id).map_or(false, |w| w.is_active)) - } - - pub fn root_view(&self, window_id: usize) -> Option { - self.read(|cx| cx.windows.get(&window_id).map(|w| w.root_view().clone())) - } - - pub fn window_ids(&self) -> Vec { - self.read(|cx| cx.windows.keys().copied().collect()) - } - pub fn add_model(&mut self, build_model: F) -> ModelHandle where T: Entity, @@ -501,7 +492,7 @@ pub struct AppContext { models: HashMap>, views: HashMap<(usize, usize), Box>, views_metadata: HashMap<(usize, usize), ViewMetadata>, - windows: HashMap, + windows: HashMap, globals: HashMap>, element_states: HashMap>, background: Arc, @@ -818,22 +809,6 @@ impl AppContext { Some(callback(&window_context)) } - pub fn update_window T>( - &mut self, - window_id: usize, - callback: F, - ) -> Option { - self.update(|app_context| { - let mut window = app_context.windows.remove(&window_id)?; - let mut window_context = WindowContext::mutable(app_context, &mut window, window_id); - let result = callback(&mut window_context); - if !window_context.removed { - app_context.windows.insert(window_id, window); - } - Some(result) - }) - } - pub fn update_active_window T>( &mut self, callback: F, @@ -1331,43 +1306,40 @@ impl AppContext { F: FnOnce(&mut ViewContext) -> V, { self.update(|this| { - let window_id = post_inc(&mut this.next_id); + let window = WindowHandle::::new(post_inc(&mut this.next_id)); let platform_window = this.platform - .open_window(window_id, window_options, this.foreground.clone()); - let window = this.build_window(window_id, platform_window, build_root_view); - this.windows.insert(window_id, window); - WindowHandle::new(window_id) + .open_window(window, window_options, this.foreground.clone()); + let window = this.build_window(window, platform_window, build_root_view); + this.windows.insert(window.into(), window); + window }) } - pub fn add_status_bar_item(&mut self, build_root_view: F) -> (usize, ViewHandle) + pub fn add_status_bar_item(&mut self, build_root_view: F) -> WindowHandle where V: View, F: FnOnce(&mut ViewContext) -> V, { self.update(|this| { - let window_id = post_inc(&mut this.next_id); - let platform_window = this.platform.add_status_item(window_id); - let window = this.build_window(window_id, platform_window, build_root_view); - let root_view = window.root_view().clone().downcast::().unwrap(); - - this.windows.insert(window_id, window); - this.update_window(window_id, |cx| { - root_view.update(cx, |view, cx| view.focus_in(cx.handle().into_any(), cx)) - }); + let handle = WindowHandle::::new(post_inc(&mut this.next_id)); + let platform_window = this.platform.add_status_item(handle.id()); + let window = this.build_window(handle, platform_window, build_root_view); - (window_id, root_view) + this.windows.insert(handle.into(), window); + handle.update_root(this, |view, cx| view.focus_in(cx.handle().into_any(), cx)); + handle }) } - pub fn build_window( + pub fn build_window( &mut self, - window_id: usize, + handle: H, mut platform_window: Box, build_root_view: F, ) -> Window where + H: Into, V: View, F: FnOnce(&mut ViewContext) -> V, { @@ -1375,7 +1347,7 @@ impl AppContext { let mut app = self.upgrade(); platform_window.on_event(Box::new(move |event| { - app.update_window(window_id, |cx| { + app.update_window(handle, |cx| { if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event { if cx.dispatch_keystroke(keystroke) { return true; @@ -1391,35 +1363,35 @@ impl AppContext { { let mut app = self.upgrade(); platform_window.on_active_status_change(Box::new(move |is_active| { - app.update(|cx| cx.window_changed_active_status(window_id, is_active)) + app.update(|cx| cx.window_changed_active_status(handle, is_active)) })); } { let mut app = self.upgrade(); platform_window.on_resize(Box::new(move || { - app.update(|cx| cx.window_was_resized(window_id)) + app.update(|cx| cx.window_was_resized(handle)) })); } { let mut app = self.upgrade(); platform_window.on_moved(Box::new(move || { - app.update(|cx| cx.window_was_moved(window_id)) + app.update(|cx| cx.window_was_moved(handle)) })); } { let mut app = self.upgrade(); platform_window.on_fullscreen(Box::new(move |is_fullscreen| { - app.update(|cx| cx.window_was_fullscreen_changed(window_id, is_fullscreen)) + app.update(|cx| cx.window_was_fullscreen_changed(handle, is_fullscreen)) })); } { let mut app = self.upgrade(); platform_window.on_close(Box::new(move || { - app.update(|cx| cx.update_window(window_id, |cx| cx.remove_window())); + app.update(|cx| cx.update_window(handle, |cx| cx.remove_window())); })); } @@ -1431,27 +1403,20 @@ impl AppContext { platform_window.set_input_handler(Box::new(WindowInputHandler { app: self.upgrade().0, - window_id, + window_id: handle, })); - let mut window = Window::new(window_id, platform_window, self, build_root_view); - let mut cx = WindowContext::mutable(self, &mut window, window_id); + let mut window = Window::new(handle, platform_window, self, build_root_view); + let mut cx = WindowContext::mutable(self, &mut window, handle); cx.layout(false).expect("initial layout should not error"); let scene = cx.paint().expect("initial paint should not error"); window.platform_window.present_scene(scene); window } - pub(crate) fn replace_root_view( - &mut self, - window_id: usize, - build_root_view: F, - ) -> Option> - where - V: View, - F: FnOnce(&mut ViewContext) -> V, - { - self.update_window(window_id, |cx| cx.replace_root_view(build_root_view)) + pub fn windows(&self) -> impl Iterator { + todo!(); + None.into_iter() } pub fn read_view(&self, handle: &ViewHandle) -> &T { @@ -2192,11 +2157,20 @@ impl BorrowWindowContext for AppContext { AppContext::read_window(self, window_id, f) } - fn update_window(&mut self, window_id: usize, f: F) -> Self::Result + fn update_window(&mut self, window: usize, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T, { - AppContext::update_window(self, window_id, f) + self.update(|app_context| { + let mut window = app_context.windows.remove(&window_handle)?; + let mut window_context = + WindowContext::mutable(app_context, &mut window, window_handle); + let result = callback(&mut window_context); + if !window_context.removed { + app_context.windows.insert(window_handle, window); + } + Some(result) + }) } } @@ -3862,44 +3836,28 @@ impl Clone for WeakModelHandle { impl Copy for WeakModelHandle {} +#[derive(Deref, Copy, Clone)] pub struct WindowHandle { - window_id: usize, + #[deref] + any_handle: AnyWindowHandle, root_view_type: PhantomData, } -#[allow(dead_code)] impl WindowHandle { fn new(window_id: usize) -> Self { WindowHandle { - window_id, + any_handle: AnyWindowHandle { + window_id, + root_view_type: TypeId::of::(), + }, root_view_type: PhantomData, } } - pub fn window_id(&self) -> usize { - self.window_id - } - pub fn root(&self, cx: &C) -> C::Result> { self.read_with(cx, |cx| cx.root_view().clone().downcast().unwrap()) } - pub fn read_with(&self, cx: &C, read: F) -> C::Result - where - C: BorrowWindowContext, - F: FnOnce(&WindowContext) -> R, - { - cx.read_window_with(self.window_id(), |cx| read(cx)) - } - - pub fn update(&self, cx: &mut C, update: F) -> C::Result - where - C: BorrowWindowContext, - F: FnOnce(&mut WindowContext) -> R, - { - cx.update_window(self.window_id(), update) - } - pub fn read_root_with(&self, cx: &C, read: F) -> C::Result where C: BorrowWindowContext, @@ -3918,7 +3876,7 @@ impl WindowHandle { C: BorrowWindowContext, F: FnOnce(&mut V, &mut ViewContext) -> R, { - cx.update_window(self.window_id, |cx| { + cx.update_window(*self, |cx| { cx.root_view() .clone() .downcast::() @@ -3927,6 +3885,53 @@ impl WindowHandle { }) } + pub fn replace_root(&self, cx: &mut C, build_root: F) -> C::Result> + where + C: BorrowWindowContext, + F: FnOnce(&mut ViewContext) -> V, + { + cx.update_window(self.into_any(), |cx| { + let root_view = self.add_view(cx, |cx| build_root(cx)); + cx.window.root_view = Some(root_view.clone().into_any()); + cx.window.focused_view_id = Some(root_view.id()); + root_view + }) + } +} + +impl Into for WindowHandle { + fn into(self) -> AnyWindowHandle { + self.any_handle + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct AnyWindowHandle { + window_id: usize, + root_view_type: TypeId, +} + +impl AnyWindowHandle { + pub fn id(&self) -> usize { + self.window_id + } + + pub fn read_with(&self, cx: &C, read: F) -> C::Result + where + C: BorrowWindowContext, + F: FnOnce(&WindowContext) -> R, + { + cx.read_window_with(self.window_id, |cx| read(cx)) + } + + pub fn update(&self, cx: &mut C, update: F) -> C::Result + where + C: BorrowWindowContext, + F: FnOnce(&mut WindowContext) -> R, + { + cx.update_window(self.window_id, update) + } + pub fn add_view(&self, cx: &mut C, build_view: F) -> C::Result> where C: BorrowWindowContext, @@ -3936,21 +3941,16 @@ impl WindowHandle { self.update(cx, |cx| cx.add_view(build_view)) } - pub(crate) fn replace_root_view( - &self, - cx: &mut C, - build_root_view: F, - ) -> C::Result> - where - C: BorrowWindowContext, - F: FnOnce(&mut ViewContext) -> V, - { - cx.update_window(self.window_id, |cx| { - let root_view = self.add_view(cx, |cx| build_root_view(cx)); - cx.window.root_view = Some(root_view.clone().into_any()); - cx.window.focused_view_id = Some(root_view.id()); - root_view - }) + pub fn root_is(&self) -> bool { + self.root_view_type == TypeId::of::() + } + + pub fn is_active(&self, cx: &C) -> C::Result { + self.read_with(cx, |cx| cx.window.is_active) + } + + pub fn remove(&self, cx: &mut C) -> C::Result<()> { + self.update(cx, |cx| cx.remove_window()) } } @@ -5390,7 +5390,7 @@ mod tests { TestView { events: Vec::new() } }); - assert_eq!(window.read_root_with(cx, |view, _| assert_eq!(view.events, ["before notify"]))); + window.read_root_with(cx, |view, _| assert_eq!(view.events, ["before notify"])); } #[crate::test(self)] @@ -6227,7 +6227,7 @@ mod tests { // Check that global actions do not have a binding, even if a binding does exist in another view assert_eq!( - &available_actions(window.window_id(), view_1.id(), cx), + &available_actions(window.id(), view_1.id(), cx), &[ ("test::Action1", vec![Keystroke::parse("a").unwrap()]), ("test::GlobalAction", vec![]) @@ -6236,7 +6236,7 @@ mod tests { // Check that view 1 actions and bindings are available even when called from view 2 assert_eq!( - &available_actions(window.window_id(), view_2.id(), cx), + &available_actions(window.id(), view_2.id(), cx), &[ ("test::Action1", vec![Keystroke::parse("a").unwrap()]), ("test::Action2", vec![Keystroke::parse("b").unwrap()]), @@ -6299,7 +6299,7 @@ mod tests { ]); }); - let actions = cx.available_actions(window.window_id(), view.id()); + let actions = cx.available_actions(window.id(), view.id()); assert_eq!( actions[0].1.as_any().downcast_ref::(), Some(&ActionWithArg { arg: false }) @@ -6585,25 +6585,25 @@ mod tests { [("window 2", false), ("window 3", true)] ); - cx.simulate_window_activation(Some(window_2.window_id())); + cx.simulate_window_activation(Some(window_2.id())); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 3", false), ("window 2", true)] ); - cx.simulate_window_activation(Some(window_1.window_id())); + cx.simulate_window_activation(Some(window_1.id())); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 2", false), ("window 1", true)] ); - cx.simulate_window_activation(Some(window_3.window_id())); + cx.simulate_window_activation(Some(window_3.id())); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 1", false), ("window 3", true)] ); - cx.simulate_window_activation(Some(window_3.window_id())); + cx.simulate_window_activation(Some(window_3.id())); assert_eq!(mem::take(&mut *events.borrow_mut()), []); } diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 3b574eb03ee3f6cfcae23cffff8f1c5359828c66..5b005d7d6f2cd527321c97b3690576433ed132e7 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -4,9 +4,9 @@ use crate::{ keymap_matcher::{Binding, Keystroke}, platform, platform::{Event, InputHandler, KeyDownEvent, Platform}, - Action, AppContext, BorrowAppContext, BorrowWindowContext, Entity, FontCache, Handle, - ModelContext, ModelHandle, Subscription, Task, View, ViewContext, ViewHandle, WeakHandle, - WindowContext, WindowHandle, + Action, AnyWindowHandle, AppContext, BorrowAppContext, BorrowWindowContext, Entity, FontCache, + Handle, ModelContext, ModelHandle, Subscription, Task, View, ViewContext, ViewHandle, + WeakHandle, WindowContext, WindowHandle, }; use collections::BTreeMap; use futures::Future; @@ -124,6 +124,13 @@ impl TestAppContext { } } + pub fn window(&self, window_id: usize) -> Option> { + self.cx + .borrow() + .read_window(window_id, |cx| cx.window()) + .flatten() + } + pub fn read_window T>( &self, window_id: usize, @@ -157,9 +164,9 @@ impl TestAppContext { .cx .borrow_mut() .add_window(Default::default(), build_root_view); - self.simulate_window_activation(Some(window.window_id())); + self.simulate_window_activation(Some(window.id())); - WindowHandle::new(window.window_id()) + WindowHandle::new(window.id()) } pub fn add_view(&mut self, window_id: usize, build_view: F) -> ViewHandle @@ -191,10 +198,14 @@ impl TestAppContext { self.cx.borrow_mut().subscribe_global(callback) } - pub fn window_ids(&self) -> Vec { - self.cx.borrow().windows.keys().copied().collect() + pub fn windows(&self) -> impl Iterator { + self.cx.borrow().windows() } + // pub fn window_ids(&self) -> Vec { + // self.cx.borrow().windows.keys().copied().collect() + // } + pub fn remove_all_windows(&mut self) { self.update(|cx| cx.windows.clear()); } @@ -311,15 +322,15 @@ impl TestAppContext { pub fn simulate_window_activation(&self, to_activate: Option) { self.cx.borrow_mut().update(|cx| { - let other_window_ids = cx + let other_windows = cx .windows .keys() - .filter(|window_id| Some(**window_id) != to_activate) + .filter(|window| Some(window.id()) != to_activate) .copied() .collect::>(); - for window_id in other_window_ids { - cx.window_changed_active_status(window_id, false) + for window in other_windows { + cx.window_changed_active_status(window.id(), false) } if let Some(to_activate) = to_activate { diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 20992bfbaad03e03888e9971c8f4f88f829cdf46..cc8468edbd7dbced86061e70a2b17d7ee4578691 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -196,6 +196,16 @@ impl<'a> WindowContext<'a> { self.window_id } + pub fn window(&self) -> Option> { + self.window.root_view.as_ref().and_then(|root_view| { + if root_view.is::() { + Some(WindowHandle::new(self.window_id)) + } else { + None + } + }) + } + pub fn app_context(&mut self) -> &mut AppContext { &mut self.app_context } @@ -1157,17 +1167,6 @@ impl<'a> WindowContext<'a> { self.window.platform_window.prompt(level, msg, answers) } - pub(crate) fn replace_root_view(&mut self, build_root_view: F) -> WindowHandle - where - V: View, - F: FnOnce(&mut ViewContext) -> V, - { - let root_view = self.add_view(|cx| build_root_view(cx)); - self.window.focused_view_id = Some(root_view.id()); - self.window.root_view = Some(root_view.into_any()); - WindowHandle::new(self.window_id) - } - pub fn add_view(&mut self, build_view: F) -> ViewHandle where T: View, diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 80847f9f4b97b3dc2cf2c32d6d11f0ec7dcbcc3a..021ea2d3bc3a817342e9eac684496ffeee5026bb 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1872,7 +1872,7 @@ mod tests { let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "root1", cx); @@ -2225,7 +2225,7 @@ mod tests { let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "root1", cx); @@ -2402,7 +2402,7 @@ mod tests { let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); toggle_expand_dir(&panel, "src/test", cx); @@ -2493,7 +2493,7 @@ mod tests { let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "src/", cx); diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index 4bd186fc98b3edb93bb4b2daa1b3e90633e3a0df..8471f3a3a7014d2034438839f76ae9b4214ded52 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -328,7 +328,7 @@ mod tests { let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); // Create the project symbols view. let symbols = cx.add_view(window_id, |cx| { diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 265e4f02061539a685322a446fef9f7d94b00ffb..1e635432bd5c138f81410f3ac40ee461830ddb17 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -851,11 +851,11 @@ mod tests { }); let window = cx.add_window(|_| EmptyView); - let editor = cx.add_view(window.window_id(), |cx| { + let editor = cx.add_view(window.id(), |cx| { Editor::for_buffer(buffer.clone(), None, cx) }); - let search_bar = cx.add_view(window.window_id(), |cx| { + let search_bar = cx.add_view(window.id(), |cx| { let mut search_bar = BufferSearchBar::new(cx); search_bar.set_active_pane_item(Some(&editor), cx); search_bar.show(cx); @@ -1232,7 +1232,7 @@ mod tests { ); let buffer = cx.add_model(|cx| Buffer::new(0, buffer_text, cx)); let window = cx.add_window(|_| EmptyView); - let window_id = window.window_id(); + let window_id = window.id(); let editor = cx.add_view(window_id, |cx| Editor::for_buffer(buffer.clone(), None, cx)); @@ -1421,11 +1421,11 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, buffer_text, cx)); let window = cx.add_window(|_| EmptyView); - let editor = cx.add_view(window.window_id(), |cx| { + let editor = cx.add_view(window.id(), |cx| { Editor::for_buffer(buffer.clone(), None, cx) }); - let search_bar = cx.add_view(window.window_id(), |cx| { + let search_bar = cx.add_view(window.id(), |cx| { let mut search_bar = BufferSearchBar::new(cx); search_bar.set_active_pane_item(Some(&editor), cx); search_bar.show(cx); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index febd564050ddd0ea6355e83f69f505e80d924029..0db66b4e378a56c97e2e2d1290742e52e1329bda 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1568,7 +1568,7 @@ pub mod tests { let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let active_item = cx.read(|cx| { workspace @@ -1874,7 +1874,7 @@ pub mod tests { let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); workspace.update(cx, |workspace, cx| { ProjectSearchView::deploy(workspace, &workspace::NewSearch, cx) }); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 09e4c4c2193e8521cd8c7dc9841a361933497e73..37fab1ee462d7a242c331ea5df169babbae3a6d8 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -37,7 +37,7 @@ use gpui::{ }, AnyModelHandle, AnyViewHandle, AnyWeakViewHandle, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, SizeConstraint, Subscription, Task, View, ViewContext, ViewHandle, - WeakViewHandle, WindowContext, + WeakViewHandle, WindowContext, WindowHandle, }; use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem}; use itertools::Itertools; @@ -749,7 +749,7 @@ impl Workspace { fn new_local( abs_paths: Vec, app_state: Arc, - requesting_window_id: Option, + requesting_window: Option>, cx: &mut AppContext, ) -> Task<( WeakViewHandle, @@ -793,55 +793,60 @@ impl Workspace { DB.next_id().await.unwrap_or(0) }; - let window = requesting_window_id.and_then(|window_id| { - cx.update(|cx| { - cx.replace_root_view(window_id, |cx| { - Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx) - }) - }) - }); - let window = window.unwrap_or_else(|| { - let window_bounds_override = window_bounds_env_override(&cx); - let (bounds, display) = if let Some(bounds) = window_bounds_override { - (Some(bounds), None) - } else { - serialized_workspace - .as_ref() - .and_then(|serialized_workspace| { - let display = serialized_workspace.display?; - let mut bounds = serialized_workspace.bounds?; - - // Stored bounds are relative to the containing display. - // So convert back to global coordinates if that screen still exists - if let WindowBounds::Fixed(mut window_bounds) = bounds { - if let Some(screen) = cx.platform().screen_by_id(display) { - let screen_bounds = screen.bounds(); - window_bounds.set_origin_x( - window_bounds.origin_x() + screen_bounds.origin_x(), - ); - window_bounds.set_origin_y( - window_bounds.origin_y() + screen_bounds.origin_y(), - ); - bounds = WindowBounds::Fixed(window_bounds); - } else { - // Screen no longer exists. Return none here. - return None; + let window = if let Some(window) = requesting_window { + window.replace_root(&mut cx, |cx| { + Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx) + }); + window + } else { + { + let window_bounds_override = window_bounds_env_override(&cx); + let (bounds, display) = if let Some(bounds) = window_bounds_override { + (Some(bounds), None) + } else { + serialized_workspace + .as_ref() + .and_then(|serialized_workspace| { + let display = serialized_workspace.display?; + let mut bounds = serialized_workspace.bounds?; + + // Stored bounds are relative to the containing display. + // So convert back to global coordinates if that screen still exists + if let WindowBounds::Fixed(mut window_bounds) = bounds { + if let Some(screen) = cx.platform().screen_by_id(display) { + let screen_bounds = screen.bounds(); + window_bounds.set_origin_x( + window_bounds.origin_x() + screen_bounds.origin_x(), + ); + window_bounds.set_origin_y( + window_bounds.origin_y() + screen_bounds.origin_y(), + ); + bounds = WindowBounds::Fixed(window_bounds); + } else { + // Screen no longer exists. Return none here. + return None; + } } - } - Some((bounds, display)) - }) - .unzip() - }; - - // Use the serialized workspace to construct the new window - cx.add_window( - (app_state.build_window_options)(bounds, display, cx.platform().as_ref()), - |cx| { - Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx) - }, - ) - }); + Some((bounds, display)) + }) + .unzip() + }; + + // Use the serialized workspace to construct the new window + cx.add_window( + (app_state.build_window_options)(bounds, display, cx.platform().as_ref()), + |cx| { + Workspace::new( + workspace_id, + project_handle.clone(), + app_state.clone(), + cx, + ) + }, + ) + } + }; // We haven't yielded the main thread since obtaining the window handle, // so the window exists. @@ -1227,14 +1232,14 @@ impl Workspace { pub fn close_global(_: &CloseWindow, cx: &mut AppContext) { cx.spawn(|mut cx| async move { - let id = cx - .window_ids() + let window = cx + .windows() .into_iter() - .find(|&id| cx.window_is_active(id)); - if let Some(id) = id { + .find(|window| window.is_active(&cx).unwrap_or(false)); + if let Some(window) = window { //This can only get called when the window's project connection has been lost //so we don't need to prompt the user for anything and instead just close the window - cx.remove_window(id); + window.remove(&mut cx); } }) .detach(); @@ -1265,9 +1270,9 @@ impl Workspace { cx.spawn(|this, mut cx| async move { let workspace_count = cx - .window_ids() + .windows() .into_iter() - .filter_map(|window_id| cx.root_view(window_id)?.clone().downcast::()) + .filter(|window| window.root_is::()) .count(); if let Some(active_call) = active_call { @@ -1385,7 +1390,7 @@ impl Workspace { paths: Vec, cx: &mut ViewContext, ) -> Task> { - let window_id = cx.window_id(); + let window = cx.window::(); let is_remote = self.project.read(cx).is_remote(); let has_worktree = self.project.read(cx).worktrees(cx).next().is_some(); let has_dirty_items = self.items(cx).any(|item| item.is_dirty(cx)); @@ -1397,15 +1402,15 @@ impl Workspace { let app_state = self.app_state.clone(); cx.spawn(|_, mut cx| async move { - let window_id_to_replace = if let Some(close_task) = close_task { + let window_to_replace = if let Some(close_task) = close_task { if !close_task.await? { return Ok(()); } - Some(window_id) + window } else { None }; - cx.update(|cx| open_paths(&paths, &app_state, window_id_to_replace, cx)) + cx.update(|cx| open_paths(&paths, &app_state, window_to_replace, cx)) .await?; Ok(()) }) @@ -3851,7 +3856,7 @@ pub async fn last_opened_workspace_paths() -> Option { pub fn open_paths( abs_paths: &[PathBuf], app_state: &Arc, - requesting_window_id: Option, + requesting_window: Option>, cx: &mut AppContext, ) -> Task< Result<( @@ -3879,7 +3884,7 @@ pub fn open_paths( } else { Ok(cx .update(|cx| { - Workspace::new_local(abs_paths, app_state.clone(), requesting_window_id, cx) + Workspace::new_local(abs_paths, app_state.clone(), requesting_window, cx) }) .await) } @@ -4196,14 +4201,14 @@ mod tests { ); }); assert_eq!( - cx.current_window_title(window.window_id()).as_deref(), + cx.current_window_title(window.id()).as_deref(), Some("one.txt — root1") ); // Add a second item to a non-empty pane workspace.update(cx, |workspace, cx| workspace.add_item(Box::new(item2), cx)); assert_eq!( - cx.current_window_title(window.window_id()).as_deref(), + cx.current_window_title(window.id()).as_deref(), Some("two.txt — root1") ); project.read_with(cx, |project, cx| { @@ -4222,7 +4227,7 @@ mod tests { .await .unwrap(); assert_eq!( - cx.current_window_title(window.window_id()).as_deref(), + cx.current_window_title(window.id()).as_deref(), Some("one.txt — root1") ); project.read_with(cx, |project, cx| { @@ -4242,14 +4247,14 @@ mod tests { .await .unwrap(); assert_eq!( - cx.current_window_title(window.window_id()).as_deref(), + cx.current_window_title(window.id()).as_deref(), Some("one.txt — root1, root2") ); // Remove a project folder project.update(cx, |project, cx| project.remove_worktree(worktree_id, cx)); assert_eq!( - cx.current_window_title(window.window_id()).as_deref(), + cx.current_window_title(window.id()).as_deref(), Some("one.txt — root2") ); } @@ -4285,9 +4290,9 @@ mod tests { }); let task = workspace.update(cx, |w, cx| w.prepare_to_close(false, cx)); cx.foreground().run_until_parked(); - cx.simulate_prompt_answer(window.window_id(), 2 /* cancel */); + cx.simulate_prompt_answer(window.id(), 2 /* cancel */); cx.foreground().run_until_parked(); - assert!(!cx.has_pending_prompt(window.window_id())); + assert!(!cx.has_pending_prompt(window.id())); assert!(!task.await.unwrap()); } @@ -4346,10 +4351,10 @@ mod tests { assert_eq!(pane.items_len(), 4); assert_eq!(pane.active_item().unwrap().id(), item1.id()); }); - assert!(cx.has_pending_prompt(window.window_id())); + assert!(cx.has_pending_prompt(window.id())); // Confirm saving item 1. - cx.simulate_prompt_answer(window.window_id(), 0); + cx.simulate_prompt_answer(window.id(), 0); cx.foreground().run_until_parked(); // Item 1 is saved. There's a prompt to save item 3. @@ -4360,10 +4365,10 @@ mod tests { assert_eq!(pane.items_len(), 3); assert_eq!(pane.active_item().unwrap().id(), item3.id()); }); - assert!(cx.has_pending_prompt(window.window_id())); + assert!(cx.has_pending_prompt(window.id())); // Cancel saving item 3. - cx.simulate_prompt_answer(window.window_id(), 1); + cx.simulate_prompt_answer(window.id(), 1); cx.foreground().run_until_parked(); // Item 3 is reloaded. There's a prompt to save item 4. @@ -4374,10 +4379,10 @@ mod tests { assert_eq!(pane.items_len(), 2); assert_eq!(pane.active_item().unwrap().id(), item4.id()); }); - assert!(cx.has_pending_prompt(window.window_id())); + assert!(cx.has_pending_prompt(window.id())); // Confirm saving item 4. - cx.simulate_prompt_answer(window.window_id(), 0); + cx.simulate_prompt_answer(window.id(), 0); cx.foreground().run_until_parked(); // There's a prompt for a path for item 4. @@ -4480,7 +4485,7 @@ mod tests { &[ProjectEntryId::from_proto(0)] ); }); - cx.simulate_prompt_answer(window.window_id(), 0); + cx.simulate_prompt_answer(window.id(), 0); cx.foreground().run_until_parked(); left_pane.read_with(cx, |pane, cx| { @@ -4489,7 +4494,7 @@ mod tests { &[ProjectEntryId::from_proto(2)] ); }); - cx.simulate_prompt_answer(window.window_id(), 0); + cx.simulate_prompt_answer(window.id(), 0); cx.foreground().run_until_parked(); close.await.unwrap(); @@ -4549,7 +4554,7 @@ mod tests { item.read_with(cx, |item, _| assert_eq!(item.save_count, 2)); // Deactivating the window still saves the file. - cx.simulate_window_activation(Some(window.window_id())); + cx.simulate_window_activation(Some(window.id())); item.update(cx, |item, cx| { cx.focus_self(); item.is_dirty = true; @@ -4591,7 +4596,7 @@ mod tests { pane.update(cx, |pane, cx| pane.close_items(cx, move |id| id == item_id)) .await .unwrap(); - assert!(!cx.has_pending_prompt(window.window_id())); + assert!(!cx.has_pending_prompt(window.id())); item.read_with(cx, |item, _| assert_eq!(item.save_count, 5)); // Add the item again, ensuring autosave is prevented if the underlying file has been deleted. @@ -4612,7 +4617,7 @@ mod tests { let _close_items = pane.update(cx, |pane, cx| pane.close_items(cx, move |id| id == item_id)); deterministic.run_until_parked(); - assert!(cx.has_pending_prompt(window.window_id())); + assert!(cx.has_pending_prompt(window.id())); item.read_with(cx, |item, _| assert_eq!(item.save_count, 5)); } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 46fcc014a138a727e2c3ceec01dbc0e3d6abee05..a8a287fb4e6fc964346378fad4eee09bc5eb057a 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -813,11 +813,12 @@ mod tests { // Replace existing windows let window_id = cx.window_ids()[0]; + let window = cx.read_window(window_id, |cx| cx.window()).flatten(); cx.update(|cx| { open_paths( &[PathBuf::from("/root/c"), PathBuf::from("/root/d")], &app_state, - Some(window_id), + window, cx, ) }) @@ -982,9 +983,8 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; - let workspace = cx - .add_window(|cx| Workspace::test_new(project, cx)) - .root(cx); + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); let entries = cx.read(|cx| workspace.file_project_paths(cx)); let file1 = entries[0].clone(); @@ -1298,7 +1298,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); // Open a file within an existing worktree. workspace @@ -1341,7 +1341,7 @@ mod tests { project.update(cx, |project, _| project.languages().add(rust_lang())); let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let worktree = cx.read(|cx| workspace.read(cx).worktrees(cx).next().unwrap()); // Create a new untitled buffer @@ -1436,7 +1436,7 @@ mod tests { project.update(cx, |project, _| project.languages().add(rust_lang())); let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); // Create a new untitled buffer cx.dispatch_action(window_id, NewFile); @@ -1489,7 +1489,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.window_id(); + let window_id = window.id(); let entries = cx.read(|cx| workspace.file_project_paths(cx)); let file1 = entries[0].clone(); @@ -2087,7 +2087,7 @@ mod tests { cx.foreground().run_until_parked(); let window = cx.add_window(|_| TestView); - let window_id = window.window_id(); + let window_id = window.id(); // Test loading the keymap base at all assert_key_bindings_for( @@ -2258,7 +2258,7 @@ mod tests { cx.foreground().run_until_parked(); let window = cx.add_window(|_| TestView); - let window_id = window.window_id(); + let window_id = window.id(); // Test loading the keymap base at all assert_key_bindings_for( From d4d32611fe3422e9dbb03d432fb8e746f7b8198c Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sun, 6 Aug 2023 18:57:02 -0600 Subject: [PATCH 129/160] WIP --- crates/gpui/src/app.rs | 58 +++++++++++++++---------- crates/gpui/src/app/menu.rs | 6 +-- crates/gpui/src/app/test_app_context.rs | 12 ++--- 3 files changed, 44 insertions(+), 32 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index f967f134039081c1a89c71385e2fc25124a32bf3..c2d2397d9c4f4e00ff73cb92358de2423f85a383 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -133,13 +133,11 @@ pub trait BorrowAppContext { pub trait BorrowWindowContext { type Result; - fn read_window_with(&self, window_handle: H, f: F) -> Self::Result + fn read_window_with(&self, window_id: usize, f: F) -> Self::Result where - H: Into, F: FnOnce(&WindowContext) -> T; - fn update_window(&mut self, window_handle: H, f: F) -> Self::Result + fn update_window(&mut self, window_id: usize, f: F) -> Self::Result where - H: Into, F: FnOnce(&mut WindowContext) -> T; } @@ -303,13 +301,12 @@ impl App { result } - fn update_window(&mut self, handle: H, callback: F) -> Option + fn update_window(&mut self, window_id: usize, callback: F) -> Option where - H: Into, F: FnOnce(&mut WindowContext) -> T, { let mut state = self.0.borrow_mut(); - let result = state.update_window(handle, callback); + let result = state.update_window(window_id, callback); state.pending_notifications.clear(); result } @@ -350,10 +347,10 @@ impl AsyncAppContext { pub fn update_window T>( &mut self, - handle: AnyWindowHandle, + window_id: usize, callback: F, ) -> Option { - self.0.borrow_mut().update_window(handle, callback) + self.0.borrow_mut().update_window(window_id, callback) } pub fn debug_elements(&self, window_id: usize) -> Option { @@ -366,13 +363,13 @@ impl AsyncAppContext { pub fn dispatch_action( &mut self, - window: impl Into, + window_id: usize, view_id: usize, action: &dyn Action, ) -> Result<()> { self.0 .borrow_mut() - .update_window(window, |cx| { + .update_window(window_id, |cx| { cx.dispatch_action(Some(view_id), action); }) .ok_or_else(|| anyhow!("window not found")) @@ -492,7 +489,7 @@ pub struct AppContext { models: HashMap>, views: HashMap<(usize, usize), Box>, views_metadata: HashMap<(usize, usize), ViewMetadata>, - windows: HashMap, + windows: HashMap, globals: HashMap>, element_states: HashMap>, background: Arc, @@ -1414,9 +1411,18 @@ impl AppContext { window } - pub fn windows(&self) -> impl Iterator { - todo!(); - None.into_iter() + pub fn main_window(&self) -> Option { + self.platform.main_window_id().and_then(|main_window_id| { + self.windows + .get(&main_window_id) + .map(|window| AnyWindowHandle::new(main_window_id, window.root_view().type_id())) + }) + } + + pub fn windows(&self) -> impl '_ + Iterator { + self.windows.iter().map(|(window_id, window)| { + AnyWindowHandle::new(*window_id, window.root_view().type_id()) + }) } pub fn read_view(&self, handle: &ViewHandle) -> &T { @@ -2157,17 +2163,16 @@ impl BorrowWindowContext for AppContext { AppContext::read_window(self, window_id, f) } - fn update_window(&mut self, window: usize, f: F) -> Self::Result + fn update_window(&mut self, window_id: usize, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T, { self.update(|app_context| { - let mut window = app_context.windows.remove(&window_handle)?; - let mut window_context = - WindowContext::mutable(app_context, &mut window, window_handle); - let result = callback(&mut window_context); + let mut window = app_context.windows.remove(&window_id)?; + let mut window_context = WindowContext::mutable(app_context, &mut window, window_id); + let result = f(&mut window_context); if !window_context.removed { - app_context.windows.insert(window_handle, window); + app_context.windows.insert(window_id, window); } Some(result) }) @@ -3876,7 +3881,7 @@ impl WindowHandle { C: BorrowWindowContext, F: FnOnce(&mut V, &mut ViewContext) -> R, { - cx.update_window(*self, |cx| { + cx.update_window(self.id(), |cx| { cx.root_view() .clone() .downcast::() @@ -3890,7 +3895,7 @@ impl WindowHandle { C: BorrowWindowContext, F: FnOnce(&mut ViewContext) -> V, { - cx.update_window(self.into_any(), |cx| { + cx.update_window(self.id(), |cx| { let root_view = self.add_view(cx, |cx| build_root(cx)); cx.window.root_view = Some(root_view.clone().into_any()); cx.window.focused_view_id = Some(root_view.id()); @@ -3912,6 +3917,13 @@ pub struct AnyWindowHandle { } impl AnyWindowHandle { + fn new(window_id: usize, root_view_type: TypeId) -> Self { + Self { + window_id, + root_view_type, + } + } + pub fn id(&self) -> usize { self.window_id } diff --git a/crates/gpui/src/app/menu.rs b/crates/gpui/src/app/menu.rs index a2ac13984bee5fcc7c248e5750080c84a5353aa0..1d8908b8fdda9627d2eb7df433a7c5b819f024ed 100644 --- a/crates/gpui/src/app/menu.rs +++ b/crates/gpui/src/app/menu.rs @@ -77,9 +77,9 @@ pub(crate) fn setup_menu_handlers(foreground_platform: &dyn ForegroundPlatform, let cx = app.0.clone(); move |action| { let mut cx = cx.borrow_mut(); - if let Some(main_window_id) = cx.platform.main_window_id() { - let dispatched = cx - .update_window(main_window_id, |cx| { + if let Some(main_window) = cx.main_window() { + let dispatched = main_window + .update(&mut *cx, |cx| { if let Some(view_id) = cx.focused_view_id() { cx.dispatch_action(Some(view_id), action); true diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 5b005d7d6f2cd527321c97b3690576433ed132e7..dcbe810804b6ac8331a3a3da20868040c10fcd8d 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -198,8 +198,8 @@ impl TestAppContext { self.cx.borrow_mut().subscribe_global(callback) } - pub fn windows(&self) -> impl Iterator { - self.cx.borrow().windows() + pub fn windows(&self) -> Vec { + self.cx.borrow().windows().collect() } // pub fn window_ids(&self) -> Vec { @@ -322,15 +322,15 @@ impl TestAppContext { pub fn simulate_window_activation(&self, to_activate: Option) { self.cx.borrow_mut().update(|cx| { - let other_windows = cx + let other_window_ids = cx .windows .keys() - .filter(|window| Some(window.id()) != to_activate) + .filter(|window_id| Some(**window_id) != to_activate) .copied() .collect::>(); - for window in other_windows { - cx.window_changed_active_status(window.id(), false) + for window_id in other_window_ids { + cx.window_changed_active_status(window_id, false) } if let Some(to_activate) = to_activate { From 3e0d0e5c010f3f5f0c8e964af5fcfce621705b14 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 7 Aug 2023 13:54:47 -0600 Subject: [PATCH 130/160] WIP --- crates/gpui/src/app.rs | 186 ++++++++++++++++---- crates/gpui/src/app/test_app_context.rs | 59 ++++--- crates/gpui/src/app/window.rs | 16 +- crates/gpui/src/app/window_input_handler.rs | 27 ++- crates/workspace/src/workspace.rs | 11 +- 5 files changed, 221 insertions(+), 78 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index c2d2397d9c4f4e00ff73cb92358de2423f85a383..730d0da5a054ea808dedd236892d4ca14aeefc30 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -133,12 +133,18 @@ pub trait BorrowAppContext { pub trait BorrowWindowContext { type Result; - fn read_window_with(&self, window_id: usize, f: F) -> Self::Result + fn read_window(&self, window_id: usize, f: F) -> Self::Result where F: FnOnce(&WindowContext) -> T; + fn read_window_optional(&self, window_id: usize, f: F) -> Option + where + F: FnOnce(&WindowContext) -> Option; fn update_window(&mut self, window_id: usize, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T; + fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + where + F: FnOnce(&mut WindowContext) -> Option; } #[derive(Clone)] @@ -449,13 +455,22 @@ impl BorrowAppContext for AsyncAppContext { impl BorrowWindowContext for AsyncAppContext { type Result = Option; - fn read_window_with(&self, window_id: usize, f: F) -> Self::Result + fn read_window(&self, window_id: usize, f: F) -> Self::Result where F: FnOnce(&WindowContext) -> T, { self.0.borrow().read_with(|cx| cx.read_window(window_id, f)) } + fn read_window_optional(&self, window_id: usize, f: F) -> Option + where + F: FnOnce(&WindowContext) -> Option, + { + self.0 + .borrow_mut() + .update(|cx| cx.read_window_optional(window_id, f)) + } + fn update_window(&mut self, window_id: usize, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T, @@ -464,6 +479,15 @@ impl BorrowWindowContext for AsyncAppContext { .borrow_mut() .update(|cx| cx.update_window(window_id, f)) } + + fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + where + F: FnOnce(&mut WindowContext) -> Option, + { + self.0 + .borrow_mut() + .update(|cx| cx.update_window_optional(window_id, f)) + } } type ActionCallback = dyn FnMut(&mut dyn AnyView, &dyn Action, &mut WindowContext, usize); @@ -1303,13 +1327,14 @@ impl AppContext { F: FnOnce(&mut ViewContext) -> V, { self.update(|this| { - let window = WindowHandle::::new(post_inc(&mut this.next_id)); + let window_id = post_inc(&mut this.next_id); let platform_window = this.platform - .open_window(window, window_options, this.foreground.clone()); - let window = this.build_window(window, platform_window, build_root_view); - this.windows.insert(window.into(), window); - window + .open_window(window_id, window_options, this.foreground.clone()); + let handle = WindowHandle::::new(window_id); + let window = this.build_window(handle, platform_window, build_root_view); + this.windows.insert(window_id, window); + handle }) } @@ -1319,11 +1344,11 @@ impl AppContext { F: FnOnce(&mut ViewContext) -> V, { self.update(|this| { - let handle = WindowHandle::::new(post_inc(&mut this.next_id)); - let platform_window = this.platform.add_status_item(handle.id()); + let window_id = post_inc(&mut this.next_id); + let platform_window = this.platform.add_status_item(window_id); + let handle = WindowHandle::::new(window_id); let window = this.build_window(handle, platform_window, build_root_view); - - this.windows.insert(handle.into(), window); + this.windows.insert(window_id, window); handle.update_root(this, |view, cx| view.focus_in(cx.handle().into_any(), cx)); handle }) @@ -1340,11 +1365,14 @@ impl AppContext { V: View, F: FnOnce(&mut ViewContext) -> V, { + let handle: AnyWindowHandle = handle.into(); + let window_id = handle.id(); + { let mut app = self.upgrade(); platform_window.on_event(Box::new(move |event| { - app.update_window(handle, |cx| { + app.update_window(window_id, |cx| { if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event { if cx.dispatch_keystroke(keystroke) { return true; @@ -1360,35 +1388,35 @@ impl AppContext { { let mut app = self.upgrade(); platform_window.on_active_status_change(Box::new(move |is_active| { - app.update(|cx| cx.window_changed_active_status(handle, is_active)) + app.update(|cx| cx.window_changed_active_status(window_id, is_active)) })); } { let mut app = self.upgrade(); platform_window.on_resize(Box::new(move || { - app.update(|cx| cx.window_was_resized(handle)) + app.update(|cx| cx.window_was_resized(window_id)) })); } { let mut app = self.upgrade(); platform_window.on_moved(Box::new(move || { - app.update(|cx| cx.window_was_moved(handle)) + app.update(|cx| cx.window_was_moved(window_id)) })); } { let mut app = self.upgrade(); platform_window.on_fullscreen(Box::new(move |is_fullscreen| { - app.update(|cx| cx.window_was_fullscreen_changed(handle, is_fullscreen)) + app.update(|cx| cx.window_was_fullscreen_changed(window_id, is_fullscreen)) })); } { let mut app = self.upgrade(); platform_window.on_close(Box::new(move || { - app.update(|cx| cx.update_window(handle, |cx| cx.remove_window())); + app.update(|cx| cx.update_window(window_id, |cx| cx.remove_window())); })); } @@ -1400,11 +1428,11 @@ impl AppContext { platform_window.set_input_handler(Box::new(WindowInputHandler { app: self.upgrade().0, - window_id: handle, + window: handle, })); - let mut window = Window::new(handle, platform_window, self, build_root_view); - let mut cx = WindowContext::mutable(self, &mut window, handle); + let mut window = Window::new(window_id, platform_window, self, build_root_view); + let mut cx = WindowContext::mutable(self, &mut window, window_id); cx.layout(false).expect("initial layout should not error"); let scene = cx.paint().expect("initial paint should not error"); window.platform_window.present_scene(scene); @@ -2156,13 +2184,20 @@ impl BorrowAppContext for AppContext { impl BorrowWindowContext for AppContext { type Result = Option; - fn read_window_with(&self, window_id: usize, f: F) -> Self::Result + fn read_window(&self, window_id: usize, f: F) -> Self::Result where F: FnOnce(&WindowContext) -> T, { AppContext::read_window(self, window_id, f) } + fn read_window_optional(&self, window_id: usize, f: F) -> Option + where + F: FnOnce(&WindowContext) -> Option, + { + AppContext::read_window(self, window_id, f).flatten() + } + fn update_window(&mut self, window_id: usize, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T, @@ -2177,6 +2212,13 @@ impl BorrowWindowContext for AppContext { Some(result) }) } + + fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + where + F: FnOnce(&mut WindowContext) -> Option, + { + AppContext::update_window(self, window_id, f).flatten() + } } #[derive(Debug)] @@ -3379,8 +3421,15 @@ impl BorrowAppContext for ViewContext<'_, '_, V> { impl BorrowWindowContext for ViewContext<'_, '_, V> { type Result = T; - fn read_window_with T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_window_with(&*self.window_context, window_id, f) + fn read_window T>(&self, window_id: usize, f: F) -> T { + BorrowWindowContext::read_window(&*self.window_context, window_id, f) + } + + fn read_window_optional(&self, window_id: usize, f: F) -> Option + where + F: FnOnce(&WindowContext) -> Option, + { + BorrowWindowContext::read_window_optional(&*self.window_context, window_id, f) } fn update_window T>( @@ -3390,6 +3439,13 @@ impl BorrowWindowContext for ViewContext<'_, '_, V> { ) -> T { BorrowWindowContext::update_window(&mut *self.window_context, window_id, f) } + + fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + where + F: FnOnce(&mut WindowContext) -> Option, + { + BorrowWindowContext::update_window_optional(&mut *self.window_context, window_id, f) + } } pub struct LayoutContext<'a, 'b, 'c, V: View> { @@ -3490,8 +3546,15 @@ impl BorrowAppContext for LayoutContext<'_, '_, '_, V> { impl BorrowWindowContext for LayoutContext<'_, '_, '_, V> { type Result = T; - fn read_window_with T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_window_with(&*self.view_context, window_id, f) + fn read_window T>(&self, window_id: usize, f: F) -> T { + BorrowWindowContext::read_window(&*self.view_context, window_id, f) + } + + fn read_window_optional(&self, window_id: usize, f: F) -> Option + where + F: FnOnce(&WindowContext) -> Option, + { + BorrowWindowContext::read_window_optional(&*self.view_context, window_id, f) } fn update_window T>( @@ -3501,6 +3564,13 @@ impl BorrowWindowContext for LayoutContext<'_, '_, '_, V> { ) -> T { BorrowWindowContext::update_window(&mut *self.view_context, window_id, f) } + + fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + where + F: FnOnce(&mut WindowContext) -> Option, + { + BorrowWindowContext::update_window_optional(&mut *self.view_context, window_id, f) + } } pub struct EventContext<'a, 'b, 'c, V: View> { @@ -3548,8 +3618,15 @@ impl BorrowAppContext for EventContext<'_, '_, '_, V> { impl BorrowWindowContext for EventContext<'_, '_, '_, V> { type Result = T; - fn read_window_with T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_window_with(&*self.view_context, window_id, f) + fn read_window T>(&self, window_id: usize, f: F) -> T { + BorrowWindowContext::read_window(&*self.view_context, window_id, f) + } + + fn read_window_optional(&self, window_id: usize, f: F) -> Option + where + F: FnOnce(&WindowContext) -> Option, + { + BorrowWindowContext::read_window_optional(&*self.view_context, window_id, f) } fn update_window T>( @@ -3559,6 +3636,13 @@ impl BorrowWindowContext for EventContext<'_, '_, '_, V> { ) -> T { BorrowWindowContext::update_window(&mut *self.view_context, window_id, f) } + + fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + where + F: FnOnce(&mut WindowContext) -> Option, + { + BorrowWindowContext::update_window_optional(&mut *self.view_context, window_id, f) + } } pub(crate) enum Reference<'a, T> { @@ -3841,13 +3925,24 @@ impl Clone for WeakModelHandle { impl Copy for WeakModelHandle {} -#[derive(Deref, Copy, Clone)] -pub struct WindowHandle { +#[derive(Deref)] +pub struct WindowHandle { #[deref] any_handle: AnyWindowHandle, - root_view_type: PhantomData, + root_view_type: PhantomData, +} + +impl Clone for WindowHandle { + fn clone(&self) -> Self { + Self { + any_handle: self.any_handle.clone(), + root_view_type: PhantomData, + } + } } +impl Copy for WindowHandle {} + impl WindowHandle { fn new(window_id: usize) -> Self { WindowHandle { @@ -3933,7 +4028,15 @@ impl AnyWindowHandle { C: BorrowWindowContext, F: FnOnce(&WindowContext) -> R, { - cx.read_window_with(self.window_id, |cx| read(cx)) + cx.read_window(self.window_id, |cx| read(cx)) + } + + pub fn read_optional_with(&self, cx: &C, read: F) -> Option + where + C: BorrowWindowContext, + F: FnOnce(&WindowContext) -> Option, + { + cx.read_window_optional(self.window_id, |cx| read(cx)) } pub fn update(&self, cx: &mut C, update: F) -> C::Result @@ -3944,6 +4047,14 @@ impl AnyWindowHandle { cx.update_window(self.window_id, update) } + pub fn update_optional(&self, cx: &mut C, update: F) -> Option + where + C: BorrowWindowContext, + F: FnOnce(&mut WindowContext) -> Option, + { + cx.update_window_optional(self.window_id, update) + } + pub fn add_view(&self, cx: &mut C, build_view: F) -> C::Result> where C: BorrowWindowContext, @@ -3953,6 +4064,17 @@ impl AnyWindowHandle { self.update(cx, |cx| cx.add_view(build_view)) } + pub fn downcast(self) -> Option> { + if self.root_view_type == TypeId::of::() { + Some(WindowHandle { + any_handle: self, + root_view_type: PhantomData, + }) + } else { + None + } + } + pub fn root_is(&self) -> bool { self.root_view_type == TypeId::of::() } @@ -4018,7 +4140,7 @@ impl ViewHandle { C: BorrowWindowContext, F: FnOnce(&T, &ViewContext) -> S, { - cx.read_window_with(self.window_id, |cx| { + cx.read_window(self.window_id, |cx| { let cx = ViewContext::immutable(cx, self.view_id); read(cx.read_view(self), &cx) }) diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index dcbe810804b6ac8331a3a3da20868040c10fcd8d..0331c7922e680fe1c45460bc2569c85ab77a3f19 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -92,33 +92,34 @@ impl TestAppContext { self.update(|cx| cx.dispatch_global_action_any(&action)); } - pub fn dispatch_keystroke(&mut self, window_id: usize, keystroke: Keystroke, is_held: bool) { - let handled = self - .cx - .borrow_mut() - .update_window(window_id, |cx| { - if cx.dispatch_keystroke(&keystroke) { - return true; - } + pub fn dispatch_keystroke( + &mut self, + window: AnyWindowHandle, + keystroke: Keystroke, + is_held: bool, + ) { + let handled = window.update(self, |cx| { + if cx.dispatch_keystroke(&keystroke) { + return true; + } - if cx.dispatch_event( - Event::KeyDown(KeyDownEvent { - keystroke: keystroke.clone(), - is_held, - }), - false, - ) { - return true; - } + if cx.dispatch_event( + Event::KeyDown(KeyDownEvent { + keystroke: keystroke.clone(), + is_held, + }), + false, + ) { + return true; + } - false - }) - .unwrap_or(false); + false + }); if !handled && !keystroke.cmd && !keystroke.ctrl { WindowInputHandler { app: self.cx.clone(), - window_id, + window, } .replace_text_in_range(None, &keystroke.key) } @@ -419,13 +420,20 @@ impl BorrowAppContext for TestAppContext { impl BorrowWindowContext for TestAppContext { type Result = T; - fn read_window_with T>(&self, window_id: usize, f: F) -> T { + fn read_window T>(&self, window_id: usize, f: F) -> T { self.cx .borrow() .read_window(window_id, f) .expect("window was closed") } + fn read_window_optional(&self, window_id: usize, f: F) -> Option + where + F: FnOnce(&WindowContext) -> Option, + { + BorrowWindowContext::read_window(self, window_id, f) + } + fn update_window T>( &mut self, window_id: usize, @@ -436,6 +444,13 @@ impl BorrowWindowContext for TestAppContext { .update_window(window_id, f) .expect("window was closed") } + + fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + where + F: FnOnce(&mut WindowContext) -> Option, + { + BorrowWindowContext::update_window(self, window_id, f) + } } impl ModelHandle { diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index cc8468edbd7dbced86061e70a2b17d7ee4578691..d960b9da16a7c84d46fda2b17cd2650204aa1c08 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -144,7 +144,7 @@ impl BorrowAppContext for WindowContext<'_> { impl BorrowWindowContext for WindowContext<'_> { type Result = T; - fn read_window_with T>(&self, window_id: usize, f: F) -> T { + fn read_window T>(&self, window_id: usize, f: F) -> T { if self.window_id == window_id { f(self) } else { @@ -152,6 +152,13 @@ impl BorrowWindowContext for WindowContext<'_> { } } + fn read_window_optional(&self, window_id: usize, f: F) -> Option + where + F: FnOnce(&WindowContext) -> Option, + { + BorrowWindowContext::read_window(self, window_id, f) + } + fn update_window T>( &mut self, window_id: usize, @@ -163,6 +170,13 @@ impl BorrowWindowContext for WindowContext<'_> { panic!("update called with id of window that does not belong to this context") } } + + fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + where + F: FnOnce(&mut WindowContext) -> Option, + { + BorrowWindowContext::update_window_optional(self, window_id, f) + } } impl<'a> WindowContext<'a> { diff --git a/crates/gpui/src/app/window_input_handler.rs b/crates/gpui/src/app/window_input_handler.rs index 8ee9f7eeff5c2a3e4f4d63ca55c9338f02e3ed69..d7c65b11fae6f6c66de0c4c0a1c4302400d651ba 100644 --- a/crates/gpui/src/app/window_input_handler.rs +++ b/crates/gpui/src/app/window_input_handler.rs @@ -2,11 +2,11 @@ use std::{cell::RefCell, ops::Range, rc::Rc}; use pathfinder_geometry::rect::RectF; -use crate::{platform::InputHandler, window::WindowContext, AnyView, AppContext}; +use crate::{platform::InputHandler, window::WindowContext, AnyView, AnyWindowHandle, AppContext}; pub struct WindowInputHandler { pub app: Rc>, - pub window_id: usize, + pub window: AnyWindowHandle, } impl WindowInputHandler { @@ -21,13 +21,12 @@ impl WindowInputHandler { // // See https://github.com/zed-industries/community/issues/444 let mut app = self.app.try_borrow_mut().ok()?; - app.update_window(self.window_id, |cx| { + self.window.update_optional(&mut *app, |cx| { let view_id = cx.window.focused_view_id?; - let view = cx.views.get(&(self.window_id, view_id))?; + let view = cx.views.get(&(self.window.id(), view_id))?; let result = f(view.as_ref(), &cx); Some(result) }) - .flatten() } fn update_focused_view(&mut self, f: F) -> Option @@ -35,11 +34,12 @@ impl WindowInputHandler { F: FnOnce(&mut dyn AnyView, &mut WindowContext, usize) -> T, { let mut app = self.app.try_borrow_mut().ok()?; - app.update_window(self.window_id, |cx| { - let view_id = cx.window.focused_view_id?; - cx.update_any_view(view_id, |view, cx| f(view, cx, view_id)) - }) - .flatten() + self.window + .update(&mut *app, |cx| { + let view_id = cx.window.focused_view_id?; + cx.update_any_view(view_id, |view, cx| f(view, cx, view_id)) + }) + .flatten() } } @@ -83,9 +83,8 @@ impl InputHandler for WindowInputHandler { } fn rect_for_range(&self, range_utf16: Range) -> Option { - self.app - .borrow() - .read_window(self.window_id, |cx| cx.rect_for_text_range(range_utf16)) - .flatten() + self.window.read_optional_with(&*self.app.borrow(), |cx| { + cx.rect_for_text_range(range_utf16) + }) } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 37fab1ee462d7a242c331ea5df169babbae3a6d8..c5e0e7e1ad6e2cb83b6c9cdb3dbd01f8f1687d3c 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -4035,16 +4035,9 @@ pub fn restart(_: &Restart, cx: &mut AppContext) { let should_confirm = settings::get::(cx).confirm_quit; cx.spawn(|mut cx| async move { let mut workspaces = cx - .window_ids() + .windows() .into_iter() - .filter_map(|window_id| { - Some( - cx.root_view(window_id)? - .clone() - .downcast::()? - .downgrade(), - ) - }) + .filter_map(|window| Some(window.downcast::()?.root(&cx)?.downgrade())) .collect::>(); // If multiple windows have unsaved changes, and need a save prompt, From 4e33654abaafd22de5140cc6e40f342351047a2a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 7 Aug 2023 13:53:41 -0700 Subject: [PATCH 131/160] Make LspAdapter::process_diagnostics synchronous Co-authored-by: Nathan --- crates/language/src/language.rs | 14 ++++---------- crates/project/src/project.rs | 29 +++++++++++++---------------- crates/zed/src/languages/rust.rs | 4 ++-- 3 files changed, 19 insertions(+), 28 deletions(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 125e14d445f3872e9718cb2759016a09b0c28439..100ab275717066251973c3f6d547e32f72ff0b4c 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -182,8 +182,8 @@ impl CachedLspAdapter { self.adapter.workspace_configuration(cx) } - pub async fn process_diagnostics(&self, params: &mut lsp::PublishDiagnosticsParams) { - self.adapter.process_diagnostics(params).await + pub fn process_diagnostics(&self, params: &mut lsp::PublishDiagnosticsParams) { + self.adapter.process_diagnostics(params) } pub async fn process_completion(&self, completion_item: &mut lsp::CompletionItem) { @@ -262,7 +262,7 @@ pub trait LspAdapter: 'static + Send + Sync { container_dir: PathBuf, ) -> Option; - async fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} + fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} async fn process_completion(&self, _: &mut lsp::CompletionItem) {} @@ -1487,12 +1487,6 @@ impl Language { None } - pub async fn process_diagnostics(&self, diagnostics: &mut lsp::PublishDiagnosticsParams) { - for adapter in &self.adapters { - adapter.process_diagnostics(diagnostics).await; - } - } - pub async fn process_completion(self: &Arc, completion: &mut lsp::CompletionItem) { for adapter in &self.adapters { adapter.process_completion(completion).await; @@ -1756,7 +1750,7 @@ impl LspAdapter for Arc { unreachable!(); } - async fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} + fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} async fn disk_based_diagnostic_sources(&self) -> Vec { self.disk_based_diagnostics_sources.clone() diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 6b905a1faa876bafd793b5e6fc02be4aacc437c2..1aa2a2dd40c2d01b98860d39420c6ec4ab894728 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2769,24 +2769,21 @@ impl Project { language_server .on_notification::({ let adapter = adapter.clone(); - move |mut params, cx| { + move |mut params, mut cx| { let this = this; let adapter = adapter.clone(); - cx.spawn(|mut cx| async move { - adapter.process_diagnostics(&mut params).await; - if let Some(this) = this.upgrade(&cx) { - this.update(&mut cx, |this, cx| { - this.update_diagnostics( - server_id, - params, - &adapter.disk_based_diagnostic_sources, - cx, - ) - .log_err(); - }); - } - }) - .detach(); + adapter.process_diagnostics(&mut params); + if let Some(this) = this.upgrade(&cx) { + this.update(&mut cx, |this, cx| { + this.update_diagnostics( + server_id, + params, + &adapter.disk_based_diagnostic_sources, + cx, + ) + .log_err(); + }); + } } }) .detach(); diff --git a/crates/zed/src/languages/rust.rs b/crates/zed/src/languages/rust.rs index 97549b00583d45f3b03a730d2a10f43dc9b2f978..3c7f84fec7dced7f8241ff7009160b0d748191f4 100644 --- a/crates/zed/src/languages/rust.rs +++ b/crates/zed/src/languages/rust.rs @@ -102,7 +102,7 @@ impl LspAdapter for RustLspAdapter { Some("rust-analyzer/flycheck".into()) } - async fn process_diagnostics(&self, params: &mut lsp::PublishDiagnosticsParams) { + fn process_diagnostics(&self, params: &mut lsp::PublishDiagnosticsParams) { lazy_static! { static ref REGEX: Regex = Regex::new("(?m)`([^`]+)\n`$").unwrap(); } @@ -310,7 +310,7 @@ mod tests { }, ], }; - RustLspAdapter.process_diagnostics(&mut params).await; + RustLspAdapter.process_diagnostics(&mut params); assert_eq!(params.diagnostics[0].message, "use of moved value `a`"); From 580c2ea8eb7ec308ba0dc1d003b8addb212bc371 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Mon, 7 Aug 2023 17:07:01 -0400 Subject: [PATCH 132/160] Fix test name --- crates/util/src/paths.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/util/src/paths.rs b/crates/util/src/paths.rs index 7e0b240570f249b7dc97b17ea0fc85581fd44410..f231669197fcfdd560011132e406772da64e3050 100644 --- a/crates/util/src/paths.rs +++ b/crates/util/src/paths.rs @@ -294,7 +294,7 @@ mod tests { } #[test] - fn test_path_suffix() { + fn test_icon_suffix() { // No dots in name let path = Path::new("/a/b/c/file_name.rs"); assert_eq!(path.icon_suffix(), Some("rs")); From dbf25ea2ffbb77c8ad2276860c4e24a1da4fd70d Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Mon, 7 Aug 2023 17:24:22 -0400 Subject: [PATCH 133/160] Add syntax highlighting for Cargo.toml files --- crates/zed/src/languages/toml/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/zed/src/languages/toml/config.toml b/crates/zed/src/languages/toml/config.toml index 4e89f5cabd99fb2faf120b32943be31d20d2a514..188239a8e0d2b518c99b9b6f69a14632bae37926 100644 --- a/crates/zed/src/languages/toml/config.toml +++ b/crates/zed/src/languages/toml/config.toml @@ -1,5 +1,5 @@ name = "TOML" -path_suffixes = ["toml"] +path_suffixes = ["Cargo.lock", "toml"] line_comment = "# " autoclose_before = ",]}" brackets = [ From ca21626064d078867c7241d7eb39b09f763fa894 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 7 Aug 2023 23:32:27 +0200 Subject: [PATCH 134/160] Baseline: Improve selection rendering for large quantities from 270ms to 90ms --- crates/editor/src/editor.rs | 64 +++++++++++++++++++++++++++++++++- crates/editor/src/element.rs | 67 +++++++++++++----------------------- 2 files changed, 86 insertions(+), 45 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index cd5e86b91098b35cad385331d5e8f28a380d3139..8f8511deb697913c1e8e1fcebd6702177d504c34 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -90,7 +90,7 @@ use std::{ cmp::{self, Ordering, Reverse}, mem, num::NonZeroU32, - ops::{ControlFlow, Deref, DerefMut, Range}, + ops::{ControlFlow, Deref, DerefMut, Range, RangeInclusive}, path::Path, sync::Arc, time::{Duration, Instant}, @@ -7549,6 +7549,68 @@ impl Editor { results } + pub fn selected_rows( + &self, + search_range: Range, + display_snapshot: &DisplaySnapshot, + theme: &Theme, + ) -> Vec> { + let mut results = Vec::new(); + let buffer = &display_snapshot.buffer_snapshot; + let Some((color_fetcher, ranges)) = self.background_highlights + .get(&TypeId::of::()) else { + return vec![]; + }; + + let color = color_fetcher(theme); + let start_ix = match ranges.binary_search_by(|probe| { + let cmp = probe.end.cmp(&search_range.start, buffer); + if cmp.is_gt() { + Ordering::Greater + } else { + Ordering::Less + } + }) { + Ok(i) | Err(i) => i, + }; + let mut push_region = |start, end| { + if let (Some(start_display), Some(end_display)) = (start, end) { + results.push(start_display..=end_display); + } + }; + let mut start_row = None; + let mut end_row = None; + for range in &ranges[start_ix..] { + if range.start.cmp(&search_range.end, buffer).is_ge() { + break; + } + let start = range.start.to_point(buffer).row; + let end = range.end.to_point(buffer).row; + if start_row.is_none() { + assert_eq!(end_row, None); + start_row = Some(start); + end_row = Some(end); + continue; + } + if let Some(current_end) = end_row.as_mut() { + if start > *current_end + 1 { + push_region(start_row, end_row); + start_row = Some(start); + end_row = Some(end); + } else { + // Merge two hunks. + *current_end = end; + } + } else { + unreachable!(); + } + } + // We might still have a hunk that was not rendered (if there was a search hit on the last line) + push_region(start_row, end_row); + + results + } + pub fn highlight_text( &mut self, ranges: Vec>, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 2d4b273f5ef0523f8ef8d9d9cd107c7e30bd659d..9ef95ec929a9ebb1425eed4c049f159e95c00466 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -1107,8 +1107,6 @@ impl EditorElement { if layout.is_singleton && scrollbar_settings.selections { let start_anchor = Anchor::min(); let end_anchor = Anchor::max(); - let mut start_row = None; - let mut end_row = None; let color = scrollbar_theme.selections; let border = Border { width: 1., @@ -1119,54 +1117,35 @@ impl EditorElement { bottom: false, left: true, }; - let mut push_region = |start, end| { - if let (Some(start_display), Some(end_display)) = (start, end) { - let start_y = y_for_row(start_display as f32); - let mut end_y = y_for_row(end_display as f32); - if end_y - start_y < 1. { - end_y = start_y + 1.; - } - let bounds = RectF::from_points(vec2f(left, start_y), vec2f(right, end_y)); - - scene.push_quad(Quad { - bounds, - background: Some(color), - border, - corner_radius: style.thumb.corner_radius, - }) + let mut push_region = |start: u32, end: u32| { + let start_y = y_for_row(start as f32); + let mut end_y = y_for_row(end as f32); + if end_y - start_y < 1. { + end_y = start_y + 1.; } + let bounds = RectF::from_points(vec2f(left, start_y), vec2f(right, end_y)); + + scene.push_quad(Quad { + bounds, + background: Some(color), + border, + corner_radius: style.thumb.corner_radius, + }) }; - for (row, _) in &editor - .background_highlights_in_range_for::( + let start = std::time::Instant::now(); + + let background_ranges = editor + .selected_rows::( start_anchor..end_anchor, &layout.position_map.snapshot, &theme, - ) - { - let start_display = row.start; - let end_display = row.end; - - if start_row.is_none() { - assert_eq!(end_row, None); - start_row = Some(start_display.row()); - end_row = Some(end_display.row()); - continue; - } - if let Some(current_end) = end_row.as_mut() { - if start_display.row() > *current_end + 1 { - push_region(start_row, end_row); - start_row = Some(start_display.row()); - end_row = Some(end_display.row()); - } else { - // Merge two hunks. - *current_end = end_display.row(); - } - } else { - unreachable!(); - } + ); + dbg!(start.elapsed().as_millis()); + for row in background_ranges { + let start = row.start(); + let end = row.end(); + push_region(*start, *end); } - // We might still have a hunk that was not rendered (if there was a search hit on the last line) - push_region(start_row, end_row); } if layout.is_singleton && scrollbar_settings.git_diff { From fa168959764defa98ed2c7ce5173f38afb6135aa Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 8 Aug 2023 00:27:38 +0200 Subject: [PATCH 135/160] Do not query start of range if it's end is the same as the previous hunk's --- crates/editor/src/editor.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 8f8511deb697913c1e8e1fcebd6702177d504c34..c12bdc9c55c9b97a96da6452c6ca8ea9a8512098 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -7557,12 +7557,11 @@ impl Editor { ) -> Vec> { let mut results = Vec::new(); let buffer = &display_snapshot.buffer_snapshot; - let Some((color_fetcher, ranges)) = self.background_highlights + let Some((_, ranges)) = self.background_highlights .get(&TypeId::of::()) else { return vec![]; }; - let color = color_fetcher(theme); let start_ix = match ranges.binary_search_by(|probe| { let cmp = probe.end.cmp(&search_range.start, buffer); if cmp.is_gt() { @@ -7584,8 +7583,14 @@ impl Editor { if range.start.cmp(&search_range.end, buffer).is_ge() { break; } - let start = range.start.to_point(buffer).row; let end = range.end.to_point(buffer).row; + if let Some(current_row) = &end_row { + if end == *current_row { + continue; + } + } + let start = range.start.to_point(buffer).row; + if start_row.is_none() { assert_eq!(end_row, None); start_row = Some(start); From 42e12213571d475b5019113b49c1a88b3f0f0a30 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 8 Aug 2023 02:17:11 +0200 Subject: [PATCH 136/160] Add upper bound limit. Remove dbg! statements --- crates/editor/src/editor.rs | 4 +++- crates/editor/src/element.rs | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index c12bdc9c55c9b97a96da6452c6ca8ea9a8512098..682974d61fb3b2993048db2105c740617cfba04e 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -7553,6 +7553,7 @@ impl Editor { &self, search_range: Range, display_snapshot: &DisplaySnapshot, + count: usize, theme: &Theme, ) -> Vec> { let mut results = Vec::new(); @@ -7572,6 +7573,7 @@ impl Editor { }) { Ok(i) | Err(i) => i, }; + let end_ix = count.min(ranges.len()); let mut push_region = |start, end| { if let (Some(start_display), Some(end_display)) = (start, end) { results.push(start_display..=end_display); @@ -7579,7 +7581,7 @@ impl Editor { }; let mut start_row = None; let mut end_row = None; - for range in &ranges[start_ix..] { + for range in &ranges[start_ix..end_ix] { if range.start.cmp(&search_range.end, buffer).is_ge() { break; } diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 9ef95ec929a9ebb1425eed4c049f159e95c00466..735abbbd13f0dd834c461f3792bd4adedd1b3f9b 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -1132,15 +1132,13 @@ impl EditorElement { corner_radius: style.thumb.corner_radius, }) }; - let start = std::time::Instant::now(); - let background_ranges = editor .selected_rows::( start_anchor..end_anchor, &layout.position_map.snapshot, + 50000, &theme, ); - dbg!(start.elapsed().as_millis()); for row in background_ranges { let start = row.start(); let end = row.end(); From 241d3951b8193d2ee1ba8fd177815531334da33b Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 8 Aug 2023 02:25:30 +0200 Subject: [PATCH 137/160] Remove redundant argument --- crates/editor/src/editor.rs | 1 - crates/editor/src/element.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 682974d61fb3b2993048db2105c740617cfba04e..0711e5eb024b6cfa9ea0b3f5bc6ee313d4c2cd52 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -7554,7 +7554,6 @@ impl Editor { search_range: Range, display_snapshot: &DisplaySnapshot, count: usize, - theme: &Theme, ) -> Vec> { let mut results = Vec::new(); let buffer = &display_snapshot.buffer_snapshot; diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 735abbbd13f0dd834c461f3792bd4adedd1b3f9b..c3c8681bcf0d572419c144ce410bdc32b52426b5 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -1137,7 +1137,6 @@ impl EditorElement { start_anchor..end_anchor, &layout.position_map.snapshot, 50000, - &theme, ); for row in background_ranges { let start = row.start(); From b0fc6da55b495dc5f43a934ee8b2d67eb1fbe62e Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 8 Aug 2023 02:37:27 +0200 Subject: [PATCH 138/160] Use display maps --- crates/editor/src/editor.rs | 21 ++++++++++++--------- crates/editor/src/element.rs | 6 +++--- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 0711e5eb024b6cfa9ea0b3f5bc6ee313d4c2cd52..8f4f97ad604dc15c47dbc2373495919059497dab 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -7554,7 +7554,7 @@ impl Editor { search_range: Range, display_snapshot: &DisplaySnapshot, count: usize, - ) -> Vec> { + ) -> Vec> { let mut results = Vec::new(); let buffer = &display_snapshot.buffer_snapshot; let Some((_, ranges)) = self.background_highlights @@ -7573,24 +7573,27 @@ impl Editor { Ok(i) | Err(i) => i, }; let end_ix = count.min(ranges.len()); - let mut push_region = |start, end| { + let mut push_region = |start: Option, end: Option| { if let (Some(start_display), Some(end_display)) = (start, end) { - results.push(start_display..=end_display); + results.push( + start_display.to_display_point(display_snapshot) + ..=end_display.to_display_point(display_snapshot), + ); } }; - let mut start_row = None; - let mut end_row = None; + let mut start_row: Option = None; + let mut end_row: Option = None; for range in &ranges[start_ix..end_ix] { if range.start.cmp(&search_range.end, buffer).is_ge() { break; } - let end = range.end.to_point(buffer).row; + let end = range.end.to_point(buffer); if let Some(current_row) = &end_row { - if end == *current_row { + if end.row == current_row.row { continue; } } - let start = range.start.to_point(buffer).row; + let start = range.start.to_point(buffer); if start_row.is_none() { assert_eq!(end_row, None); @@ -7599,7 +7602,7 @@ impl Editor { continue; } if let Some(current_end) = end_row.as_mut() { - if start > *current_end + 1 { + if start.row > current_end.row + 1 { push_region(start_row, end_row); start_row = Some(start); end_row = Some(end); diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index c3c8681bcf0d572419c144ce410bdc32b52426b5..30a9cba85c3e0bd92bc2fa0c2e121dc6e9949835 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -1117,9 +1117,9 @@ impl EditorElement { bottom: false, left: true, }; - let mut push_region = |start: u32, end: u32| { - let start_y = y_for_row(start as f32); - let mut end_y = y_for_row(end as f32); + let mut push_region = |start: DisplayPoint, end: DisplayPoint| { + let start_y = y_for_row(start.row() as f32); + let mut end_y = y_for_row(end.row() as f32); if end_y - start_y < 1. { end_y = start_y + 1.; } From 371c669e003f8082896706261779231b3c2dce11 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 8 Aug 2023 02:45:15 +0200 Subject: [PATCH 139/160] Address review feedback. Rename selected_rows to background_highlight_row_ranges. Do not return any ranges if there are more than 50k results --- crates/editor/src/editor.rs | 6 ++++-- crates/editor/src/element.rs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 8f4f97ad604dc15c47dbc2373495919059497dab..17195cb22b5de1bc60c21c8169f929e020cc78f7 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -7549,7 +7549,7 @@ impl Editor { results } - pub fn selected_rows( + pub fn background_highlight_row_ranges( &self, search_range: Range, display_snapshot: &DisplaySnapshot, @@ -7616,7 +7616,9 @@ impl Editor { } // We might still have a hunk that was not rendered (if there was a search hit on the last line) push_region(start_row, end_row); - + if results.len() > count { + return vec![]; + } results } diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 30a9cba85c3e0bd92bc2fa0c2e121dc6e9949835..33ebd4c7bd632d5137b6f8f565e6e7010899abe1 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -1133,7 +1133,7 @@ impl EditorElement { }) }; let background_ranges = editor - .selected_rows::( + .background_highlight_row_ranges::( start_anchor..end_anchor, &layout.position_map.snapshot, 50000, From 486f5bc6ca186b07c415aea5794631c5f6cbcf80 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 7 Aug 2023 19:08:58 -0600 Subject: [PATCH 140/160] Get compiling --- crates/collab/src/tests/integration_tests.rs | 4 +- .../src/project_shared_notification.rs | 2 +- .../collab_ui/src/sharing_status_indicator.rs | 8 +- crates/editor/src/editor_tests.rs | 6 +- .../src/test/editor_lsp_test_context.rs | 2 +- crates/editor/src/test/editor_test_context.rs | 10 ++- crates/go_to_line/src/go_to_line.rs | 18 ++-- crates/gpui/src/app.rs | 7 ++ crates/gpui/src/app/window.rs | 2 +- crates/vim/src/editor_events.rs | 2 +- crates/vim/src/mode_indicator.rs | 2 +- crates/vim/src/test/vim_test_context.rs | 2 +- crates/workspace/src/workspace.rs | 52 ++++++----- crates/zed/src/zed.rs | 87 +++++++------------ 14 files changed, 97 insertions(+), 107 deletions(-) diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index 1a8e6d938d6d6caac2b8caee501e1088ddeea5b3..92ccee91c0ecb5cd6d8a0ca2af5928f9b6c3a72f 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -3446,7 +3446,7 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor( let editor_a = window_a.add_view(cx_a, |cx| Editor::for_buffer(buffer_a, Some(project_a), cx)); let mut editor_cx_a = EditorTestContext { cx: cx_a, - window_id: window_a.id(), + window: window_a.into(), editor: editor_a, }; @@ -3459,7 +3459,7 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor( let editor_b = window_b.add_view(cx_b, |cx| Editor::for_buffer(buffer_b, Some(project_b), cx)); let mut editor_cx_b = EditorTestContext { cx: cx_b, - window_id: window_b.id(), + window: window_b.into(), editor: editor_b, }; diff --git a/crates/collab_ui/src/project_shared_notification.rs b/crates/collab_ui/src/project_shared_notification.rs index 03ab91623b43270bf2592ced0f460b474fd0c435..d5e7c877f7067480688faedeb9b36be964878a72 100644 --- a/crates/collab_ui/src/project_shared_notification.rs +++ b/crates/collab_ui/src/project_shared_notification.rs @@ -5,7 +5,7 @@ use gpui::{ elements::*, geometry::{rect::RectF, vector::vec2f}, platform::{CursorStyle, MouseButton, WindowBounds, WindowKind, WindowOptions}, - AppContext, Entity, View, ViewContext, + AppContext, BorrowWindowContext, Entity, View, ViewContext, }; use std::sync::{Arc, Weak}; use workspace::AppState; diff --git a/crates/collab_ui/src/sharing_status_indicator.rs b/crates/collab_ui/src/sharing_status_indicator.rs index 3a1dde072f867b0791ae8fab90d6c6328857bb2a..a39ffc457a04cacacf351fcc2d85cac8c0a391cd 100644 --- a/crates/collab_ui/src/sharing_status_indicator.rs +++ b/crates/collab_ui/src/sharing_status_indicator.rs @@ -20,11 +20,11 @@ pub fn init(cx: &mut AppContext) { { status_indicator = Some(cx.add_status_bar_item(|_| SharingStatusIndicator)); } - } else if let Some((window_id, _)) = status_indicator.take() { - cx.update_window(window_id, |cx| cx.remove_window()); + } else if let Some(window) = status_indicator.take() { + window.update(cx, |cx| cx.remove_window()); } - } else if let Some((window_id, _)) = status_indicator.take() { - cx.update_window(window_id, |cx| cx.remove_window()); + } else if let Some(window) = status_indicator.take() { + window.update(cx, |cx| cx.remove_window()); } }) .detach(); diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index a114cd437b16bbad580d6e732bb004ac352d822a..9a65e2e9532c4c74c855b58ae714bd8c7d0970bf 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -1290,7 +1290,7 @@ async fn test_move_start_of_paragraph_end_of_paragraph(cx: &mut gpui::TestAppCon let mut cx = EditorTestContext::new(cx).await; let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache())); - cx.simulate_window_resize(cx.window_id, vec2f(100., 4. * line_height)); + cx.simulate_window_resize(cx.window.id(), vec2f(100., 4. * line_height)); cx.set_state( &r#"ˇone @@ -1401,7 +1401,7 @@ async fn test_scroll_page_up_page_down(cx: &mut gpui::TestAppContext) { init_test(cx, |_| {}); let mut cx = EditorTestContext::new(cx).await; let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache())); - cx.simulate_window_resize(cx.window_id, vec2f(1000., 4. * line_height + 0.5)); + cx.simulate_window_resize(cx.window.id(), vec2f(1000., 4. * line_height + 0.5)); cx.set_state( &r#"ˇone @@ -1439,7 +1439,7 @@ async fn test_move_page_up_page_down(cx: &mut gpui::TestAppContext) { let mut cx = EditorTestContext::new(cx).await; let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache())); - cx.simulate_window_resize(cx.window_id, vec2f(100., 4. * line_height)); + cx.simulate_window_resize(cx.window.id(), vec2f(100., 4. * line_height)); cx.set_state( &r#" diff --git a/crates/editor/src/test/editor_lsp_test_context.rs b/crates/editor/src/test/editor_lsp_test_context.rs index f53115f224a1cfe6cb4a3c634786c7e7e8c18305..83aaa3b703491b5f5334d173ca8d90e731aeb5e8 100644 --- a/crates/editor/src/test/editor_lsp_test_context.rs +++ b/crates/editor/src/test/editor_lsp_test_context.rs @@ -99,7 +99,7 @@ impl<'a> EditorLspTestContext<'a> { Self { cx: EditorTestContext { cx, - window_id: window.id(), + window: window.into(), editor, }, lsp, diff --git a/crates/editor/src/test/editor_test_context.rs b/crates/editor/src/test/editor_test_context.rs index c7ea1b4f3852301e300c5ff3f1db1dff65f342a2..118cddaa9226a543ca479f577428237d77539d5d 100644 --- a/crates/editor/src/test/editor_test_context.rs +++ b/crates/editor/src/test/editor_test_context.rs @@ -3,7 +3,8 @@ use crate::{ }; use futures::Future; use gpui::{ - keymap_matcher::Keystroke, AppContext, ContextHandle, ModelContext, ViewContext, ViewHandle, + keymap_matcher::Keystroke, AnyWindowHandle, AppContext, ContextHandle, ModelContext, + ViewContext, ViewHandle, }; use indoc::indoc; use language::{Buffer, BufferSnapshot}; @@ -21,7 +22,7 @@ use super::build_editor; pub struct EditorTestContext<'a> { pub cx: &'a mut gpui::TestAppContext, - pub window_id: usize, + pub window: AnyWindowHandle, pub editor: ViewHandle, } @@ -39,7 +40,7 @@ impl<'a> EditorTestContext<'a> { let editor = window.root(cx); Self { cx, - window_id: window.id(), + window: window.into(), editor, } } @@ -111,7 +112,8 @@ impl<'a> EditorTestContext<'a> { let keystroke_under_test_handle = self.add_assertion_context(format!("Simulated Keystroke: {:?}", keystroke_text)); let keystroke = Keystroke::parse(keystroke_text).unwrap(); - self.cx.dispatch_keystroke(self.window_id, keystroke, false); + + self.cx.dispatch_keystroke(self.window, keystroke, false); keystroke_under_test_handle } diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index 769f2eda55b4a165e138ee094adc4a581963a641..fa42a523741679c191c5fab053417243f4d5d4df 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -135,14 +135,16 @@ impl Entity for GoToLine { fn release(&mut self, cx: &mut AppContext) { let scroll_position = self.prev_scroll_position.take(); - cx.update_window(self.active_editor.window_id(), |cx| { - self.active_editor.update(cx, |editor, cx| { - editor.highlight_rows(None); - if let Some(scroll_position) = scroll_position { - editor.set_scroll_position(scroll_position, cx); - } - }) - }); + if let Some(window) = self.active_editor.window(cx) { + window.update(cx, |cx| { + self.active_editor.update(cx, |editor, cx| { + editor.highlight_rows(None); + if let Some(scroll_position) = scroll_position { + editor.set_scroll_position(scroll_position, cx); + } + }) + }); + } } } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 730d0da5a054ea808dedd236892d4ca14aeefc30..b95cb0179a84131afcccf2f07bd9929d166684d8 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -23,6 +23,7 @@ use std::{ }; use anyhow::{anyhow, Context, Result}; + use derive_more::Deref; use parking_lot::Mutex; use postage::oneshot; @@ -4127,6 +4128,12 @@ impl ViewHandle { self.window_id } + pub fn window(&self, cx: &C) -> C::Result { + cx.read_window(self.window_id, |cx| { + AnyWindowHandle::new(self.window_id, cx.window.root_view.type_id()) + }) + } + pub fn id(&self) -> usize { self.view_id } diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index d960b9da16a7c84d46fda2b17cd2650204aa1c08..70d02c1fa1265b5449b127a6736c8a81573be1e1 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -175,7 +175,7 @@ impl BorrowWindowContext for WindowContext<'_> { where F: FnOnce(&mut WindowContext) -> Option, { - BorrowWindowContext::update_window_optional(self, window_id, f) + BorrowWindowContext::update_window(self, window_id, f) } } diff --git a/crates/vim/src/editor_events.rs b/crates/vim/src/editor_events.rs index 60e63f982347b9fee2a10087d530527a1db69ad4..4fef6bd715eedbe49b1347b679a2ebe6d3a89f33 100644 --- a/crates/vim/src/editor_events.rs +++ b/crates/vim/src/editor_events.rs @@ -1,6 +1,6 @@ use crate::Vim; use editor::{EditorBlurred, EditorFocused, EditorReleased}; -use gpui::AppContext; +use gpui::{AppContext, BorrowWindowContext}; pub fn init(cx: &mut AppContext) { cx.subscribe_global(focused).detach(); diff --git a/crates/vim/src/mode_indicator.rs b/crates/vim/src/mode_indicator.rs index 639a7594f113c61bc8c232325ac8d769b2ac89e5..afd60af848be052060988ba961bb75e811f33d3b 100644 --- a/crates/vim/src/mode_indicator.rs +++ b/crates/vim/src/mode_indicator.rs @@ -1,6 +1,6 @@ use gpui::{ elements::{Empty, Label}, - AnyElement, Element, Entity, Subscription, View, ViewContext, + AnyElement, Element, Entity, Subscription, View, ViewContext, BorrowWindowContext }; use settings::SettingsStore; use workspace::{item::ItemHandle, StatusItemView}; diff --git a/crates/vim/src/test/vim_test_context.rs b/crates/vim/src/test/vim_test_context.rs index ea09e550916c4355b10d12b6d3a5a2207112dd16..839ab3aafc87e535a8b09096be6b58a5837063da 100644 --- a/crates/vim/src/test/vim_test_context.rs +++ b/crates/vim/src/test/vim_test_context.rs @@ -85,7 +85,7 @@ impl<'a> VimTestContext<'a> { } pub fn set_state(&mut self, text: &str, mode: Mode) -> ContextHandle { - let window_id = self.window_id; + let window_id = self.window.id(); self.update_window(window_id, |cx| { Vim::update(cx, |vim, cx| { vim.switch_mode(mode, false, cx); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index c5e0e7e1ad6e2cb83b6c9cdb3dbd01f8f1687d3c..679c34611b37a4c7dd88e86c39338b75d9bfe9df 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -3827,9 +3827,9 @@ pub fn activate_workspace_for_project( cx: &mut AsyncAppContext, predicate: impl Fn(&mut Project, &mut ModelContext) -> bool, ) -> Option> { - for window_id in cx.window_ids() { - let handle = cx - .update_window(window_id, |cx| { + for window in cx.windows() { + let handle = window + .update(cx, |cx| { if let Some(workspace_handle) = cx.root_view().clone().downcast::() { let project = workspace_handle.read(cx).project.clone(); if project.update(cx, &predicate) { @@ -3945,18 +3945,23 @@ pub fn join_remote_project( ) -> Task> { cx.spawn(|mut cx| async move { let existing_workspace = cx - .window_ids() + .windows() .into_iter() - .filter_map(|window_id| cx.root_view(window_id)?.clone().downcast::()) - .find(|workspace| { - cx.read_window(workspace.window_id(), |cx| { - workspace.read(cx).project().read(cx).remote_id() == Some(project_id) + .find_map(|window| { + window.downcast::().and_then(|window| { + window.read_root_with(&cx, |workspace, cx| { + if workspace.project().read(cx).remote_id() == Some(project_id) { + Some(cx.handle().downgrade()) + } else { + None + } + }) }) - .unwrap_or(false) - }); + }) + .flatten(); let workspace = if let Some(existing_workspace) = existing_workspace { - existing_workspace.downgrade() + existing_workspace } else { let active_call = cx.read(ActiveCall::global); let room = active_call @@ -4034,19 +4039,19 @@ pub fn join_remote_project( pub fn restart(_: &Restart, cx: &mut AppContext) { let should_confirm = settings::get::(cx).confirm_quit; cx.spawn(|mut cx| async move { - let mut workspaces = cx + let mut workspace_windows = cx .windows() .into_iter() - .filter_map(|window| Some(window.downcast::()?.root(&cx)?.downgrade())) + .filter_map(|window| window.downcast::()) .collect::>(); // If multiple windows have unsaved changes, and need a save prompt, // prompt in the active window before switching to a different window. - workspaces.sort_by_key(|workspace| !cx.window_is_active(workspace.window_id())); + workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); - if let (true, Some(workspace)) = (should_confirm, workspaces.first()) { + if let (true, Some(window)) = (should_confirm, workspace_windows.first()) { let answer = cx.prompt( - workspace.window_id(), + window.id(), PromptLevel::Info, "Are you sure you want to restart?", &["Restart", "Cancel"], @@ -4061,14 +4066,13 @@ pub fn restart(_: &Restart, cx: &mut AppContext) { } // If the user cancels any save prompt, then keep the app open. - for workspace in workspaces { - if !workspace - .update(&mut cx, |workspace, cx| { - workspace.prepare_to_close(true, cx) - })? - .await? - { - return Ok(()); + for window in workspace_windows { + if let Some(close) = window.update_root(&mut cx, |workspace, cx| { + workspace.prepare_to_close(true, cx) + }) { + if !close.await? { + return Ok(()); + } } } cx.platform().restart(); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index a8a287fb4e6fc964346378fad4eee09bc5eb057a..2b9321b303e8610bed75b9da53b770dbc6267c3a 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -406,26 +406,19 @@ pub fn build_window_options( fn quit(_: &Quit, cx: &mut gpui::AppContext) { let should_confirm = settings::get::(cx).confirm_quit; cx.spawn(|mut cx| async move { - let mut workspaces = cx - .window_ids() + let mut workspace_windows = cx + .windows() .into_iter() - .filter_map(|window_id| { - Some( - cx.root_view(window_id)? - .clone() - .downcast::()? - .downgrade(), - ) - }) + .filter_map(|window| window.downcast::()) .collect::>(); // If multiple windows have unsaved changes, and need a save prompt, // prompt in the active window before switching to a different window. - workspaces.sort_by_key(|workspace| !cx.window_is_active(workspace.window_id())); + workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); - if let (true, Some(workspace)) = (should_confirm, workspaces.first()) { + if let (true, Some(window)) = (should_confirm, workspace_windows.first()) { let answer = cx.prompt( - workspace.window_id(), + window.id(), PromptLevel::Info, "Are you sure you want to quit?", &["Quit", "Cancel"], @@ -440,14 +433,13 @@ fn quit(_: &Quit, cx: &mut gpui::AppContext) { } // If the user cancels any save prompt, then keep the app open. - for workspace in workspaces { - if !workspace - .update(&mut cx, |workspace, cx| { - workspace.prepare_to_close(true, cx) - })? - .await? - { - return Ok(()); + for window in workspace_windows { + if let Some(close) = window.update_root(&mut cx, |workspace, cx| { + workspace.prepare_to_close(false, cx) + }) { + if close.await? { + return Ok(()); + } } } cx.platform().quit(); @@ -782,17 +774,13 @@ mod tests { }) .await .unwrap(); - assert_eq!(cx.window_ids().len(), 1); + assert_eq!(cx.windows().len(), 1); cx.update(|cx| open_paths(&[PathBuf::from("/root/a")], &app_state, None, cx)) .await .unwrap(); - assert_eq!(cx.window_ids().len(), 1); - let workspace_1 = cx - .read_window(cx.window_ids()[0], |cx| cx.root_view().clone()) - .unwrap() - .downcast::() - .unwrap(); + assert_eq!(cx.windows().len(), 1); + let workspace_1 = cx.windows()[0].downcast::().unwrap().root(cx); workspace_1.update(cx, |workspace, cx| { assert_eq!(workspace.worktrees(cx).count(), 2); assert!(workspace.left_dock().read(cx).is_open()); @@ -809,28 +797,22 @@ mod tests { }) .await .unwrap(); - assert_eq!(cx.window_ids().len(), 2); + assert_eq!(cx.windows().len(), 2); // Replace existing windows - let window_id = cx.window_ids()[0]; - let window = cx.read_window(window_id, |cx| cx.window()).flatten(); + let window = cx.windows()[0].downcast::().unwrap(); cx.update(|cx| { open_paths( &[PathBuf::from("/root/c"), PathBuf::from("/root/d")], &app_state, - window, + Some(window), cx, ) }) .await .unwrap(); - assert_eq!(cx.window_ids().len(), 2); - let workspace_1 = cx - .read_window(cx.window_ids()[0], |cx| cx.root_view().clone()) - .unwrap() - .clone() - .downcast::() - .unwrap(); + assert_eq!(cx.windows().len(), 2); + let workspace_1 = cx.windows()[0].downcast::().unwrap().root(cx); workspace_1.update(cx, |workspace, cx| { assert_eq!( workspace @@ -856,14 +838,10 @@ mod tests { cx.update(|cx| open_paths(&[PathBuf::from("/root/a")], &app_state, None, cx)) .await .unwrap(); - assert_eq!(cx.window_ids().len(), 1); + assert_eq!(cx.windows().len(), 1); // When opening the workspace, the window is not in a edited state. - let workspace = cx - .read_window(cx.window_ids()[0], |cx| cx.root_view().clone()) - .unwrap() - .downcast::() - .unwrap(); + let workspace = cx.windows()[0].downcast::().unwrap().root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); let editor = workspace.read_with(cx, |workspace, cx| { workspace @@ -917,12 +895,12 @@ mod tests { // buffer having unsaved changes. assert!(!cx.simulate_window_close(workspace.window_id())); executor.run_until_parked(); - assert_eq!(cx.window_ids().len(), 1); + assert_eq!(cx.windows().len(), 1); // The window is successfully closed after the user dismisses the prompt. cx.simulate_prompt_answer(workspace.window_id(), 1); executor.run_until_parked(); - assert_eq!(cx.window_ids().len(), 0); + assert_eq!(cx.windows().len(), 0); } #[gpui::test] @@ -935,12 +913,13 @@ mod tests { }) .await; - let window_id = *cx.window_ids().first().unwrap(); - let workspace = cx - .read_window(window_id, |cx| cx.root_view().clone()) + let window = cx + .windows() + .first() .unwrap() .downcast::() .unwrap(); + let workspace = window.root(cx); let editor = workspace.update(cx, |workspace, cx| { workspace @@ -1105,12 +1084,8 @@ mod tests { cx.update(|cx| open_paths(&[PathBuf::from("/dir1/")], &app_state, None, cx)) .await .unwrap(); - assert_eq!(cx.window_ids().len(), 1); - let workspace = cx - .read_window(cx.window_ids()[0], |cx| cx.root_view().clone()) - .unwrap() - .downcast::() - .unwrap(); + assert_eq!(cx.windows().len(), 1); + let workspace = cx.windows()[0].downcast::().unwrap().root(cx); #[track_caller] fn assert_project_panel_selection( From 0197d49230832118cf78f4b5c94d47d390b27d44 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 7 Aug 2023 19:45:43 -0600 Subject: [PATCH 141/160] Move activation simulation to AnyWindowHandle --- crates/gpui/src/app.rs | 31 +++++++++++++++++++++---- crates/gpui/src/app/test_app_context.rs | 28 ++++------------------ crates/workspace/src/workspace.rs | 6 ++--- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index b95cb0179a84131afcccf2f07bd9929d166684d8..bd3fbb8149fb6ecfd00bb461f8c4a21a22289047 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -4087,6 +4087,29 @@ impl AnyWindowHandle { pub fn remove(&self, cx: &mut C) -> C::Result<()> { self.update(cx, |cx| cx.remove_window()) } + + pub fn simulate_activation(&self, cx: &mut TestAppContext) { + self.update(cx, |cx| { + let other_window_ids = cx + .windows + .keys() + .filter(|window_id| **window_id != self.window_id) + .copied() + .collect::>(); + + for window_id in other_window_ids { + cx.window_changed_active_status(window_id, false) + } + + cx.window_changed_active_status(self.window_id, true) + }); + } + + pub fn simulate_deactivation(&self, cx: &mut TestAppContext) { + self.update(cx, |cx| { + cx.window_changed_active_status(self.window_id, false); + }) + } } #[repr(transparent)] @@ -6726,25 +6749,25 @@ mod tests { [("window 2", false), ("window 3", true)] ); - cx.simulate_window_activation(Some(window_2.id())); + window_2.simulate_activation(cx); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 3", false), ("window 2", true)] ); - cx.simulate_window_activation(Some(window_1.id())); + window_1.simulate_activation(cx); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 2", false), ("window 1", true)] ); - cx.simulate_window_activation(Some(window_3.id())); + window_3.simulate_activation(cx); assert_eq!( mem::take(&mut *events.borrow_mut()), [("window 1", false), ("window 3", true)] ); - cx.simulate_window_activation(Some(window_3.id())); + window_3.simulate_activation(cx); assert_eq!(mem::take(&mut *events.borrow_mut()), []); } diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 0331c7922e680fe1c45460bc2569c85ab77a3f19..675d8b8528dc0b2c95b2c140207be6a4e3067563 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -156,17 +156,16 @@ impl TestAppContext { self.cx.borrow_mut().add_model(build_model) } - pub fn add_window(&mut self, build_root_view: F) -> WindowHandle + pub fn add_window(&mut self, build_root_view: F) -> WindowHandle where - T: View, - F: FnOnce(&mut ViewContext) -> T, + V: View, + F: FnOnce(&mut ViewContext) -> V, { let window = self .cx .borrow_mut() .add_window(Default::default(), build_root_view); - self.simulate_window_activation(Some(window.id())); - + window.simulate_activation(self); WindowHandle::new(window.id()) } @@ -321,25 +320,6 @@ impl TestAppContext { self.platform_window_mut(window_id).resize_handlers = handlers; } - pub fn simulate_window_activation(&self, to_activate: Option) { - self.cx.borrow_mut().update(|cx| { - let other_window_ids = cx - .windows - .keys() - .filter(|window_id| Some(**window_id) != to_activate) - .copied() - .collect::>(); - - for window_id in other_window_ids { - cx.window_changed_active_status(window_id, false) - } - - if let Some(to_activate) = to_activate { - cx.window_changed_active_status(to_activate, true) - } - }); - } - pub fn is_window_edited(&self, window_id: usize) -> bool { self.platform_window_mut(window_id).edited } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 679c34611b37a4c7dd88e86c39338b75d9bfe9df..dc52614ecf497542306a7705e3be2f938d825315 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -4530,7 +4530,7 @@ mod tests { }); // Deactivating the window saves the file. - cx.simulate_window_activation(None); + window.simulate_deactivation(cx); deterministic.run_until_parked(); item.read_with(cx, |item, _| assert_eq!(item.save_count, 1)); @@ -4551,12 +4551,12 @@ mod tests { item.read_with(cx, |item, _| assert_eq!(item.save_count, 2)); // Deactivating the window still saves the file. - cx.simulate_window_activation(Some(window.id())); + window.simulate_activation(cx); item.update(cx, |item, cx| { cx.focus_self(); item.is_dirty = true; }); - cx.simulate_window_activation(None); + window.simulate_deactivation(cx); deterministic.run_until_parked(); item.read_with(cx, |item, _| assert_eq!(item.save_count, 3)); From f2be3181a98aab8c711d6c4f92b43dc891dc6ce0 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 7 Aug 2023 20:23:04 -0600 Subject: [PATCH 142/160] Move window-related methods from TestAppContext to AnyWindowHandle --- crates/collab/src/tests/integration_tests.rs | 4 +- crates/editor/src/editor_tests.rs | 9 +- crates/gpui/src/app/test_app_context.rs | 132 +++++++++---------- crates/project_panel/src/project_panel.rs | 26 ++-- crates/workspace/src/workspace.rs | 46 +++---- crates/zed/src/zed.rs | 29 ++-- 6 files changed, 118 insertions(+), 128 deletions(-) diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index 92ccee91c0ecb5cd6d8a0ca2af5928f9b6c3a72f..29dcd95eae076cd38ae36fb950a41eabe98905a0 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -1510,7 +1510,7 @@ async fn test_host_disconnect( .unwrap(); assert!(window_b.read_with(cx_b, |cx| editor_b.is_focused(cx))); editor_b.update(cx_b, |editor, cx| editor.insert("X", cx)); - assert!(cx_b.is_window_edited(workspace_b.window_id())); + assert!(window_b.is_edited(cx_b)); // Drop client A's connection. Collaborators should disappear and the project should not be shown as shared. server.forbid_connections(); @@ -1525,7 +1525,7 @@ async fn test_host_disconnect( window_b.read_with(cx_b, |cx| { assert_eq!(cx.focused_view_id(), None); }); - assert!(!cx_b.is_window_edited(workspace_b.window_id())); + assert!(!window_b.is_edited(cx_b)); // Ensure client B is not prompted to save edits when closing window after disconnecting. let can_close = workspace_b diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 9a65e2e9532c4c74c855b58ae714bd8c7d0970bf..61fa952f944d1059c210629aa93eba0736d62459 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -1290,7 +1290,8 @@ async fn test_move_start_of_paragraph_end_of_paragraph(cx: &mut gpui::TestAppCon let mut cx = EditorTestContext::new(cx).await; let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache())); - cx.simulate_window_resize(cx.window.id(), vec2f(100., 4. * line_height)); + let window = cx.window; + window.simulate_resize(vec2f(100., 4. * line_height), &mut cx); cx.set_state( &r#"ˇone @@ -1401,7 +1402,8 @@ async fn test_scroll_page_up_page_down(cx: &mut gpui::TestAppContext) { init_test(cx, |_| {}); let mut cx = EditorTestContext::new(cx).await; let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache())); - cx.simulate_window_resize(cx.window.id(), vec2f(1000., 4. * line_height + 0.5)); + let window = cx.window; + window.simulate_resize(vec2f(1000., 4. * line_height + 0.5), &mut cx); cx.set_state( &r#"ˇone @@ -1439,7 +1441,8 @@ async fn test_move_page_up_page_down(cx: &mut gpui::TestAppContext) { let mut cx = EditorTestContext::new(cx).await; let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache())); - cx.simulate_window_resize(cx.window.id(), vec2f(100., 4. * line_height)); + let window = cx.window; + window.simulate_resize(vec2f(100., 4. * line_height), &mut cx); cx.set_state( &r#" diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index 675d8b8528dc0b2c95b2c140207be6a4e3067563..e298224caa2d0fc4829443a836cc9bbb91ef6087 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -202,10 +202,6 @@ impl TestAppContext { self.cx.borrow().windows().collect() } - // pub fn window_ids(&self) -> Vec { - // self.cx.borrow().windows.keys().copied().collect() - // } - pub fn remove_all_windows(&mut self) { self.update(|cx| cx.windows.clear()); } @@ -273,57 +269,6 @@ impl TestAppContext { self.foreground_platform.as_ref().did_prompt_for_new_path() } - pub fn simulate_prompt_answer(&self, window_id: usize, answer: usize) { - use postage::prelude::Sink as _; - - let mut done_tx = self - .platform_window_mut(window_id) - .pending_prompts - .borrow_mut() - .pop_front() - .expect("prompt was not called"); - done_tx.try_send(answer).ok(); - } - - pub fn has_pending_prompt(&self, window_id: usize) -> bool { - let window = self.platform_window_mut(window_id); - let prompts = window.pending_prompts.borrow_mut(); - !prompts.is_empty() - } - - pub fn current_window_title(&self, window_id: usize) -> Option { - self.platform_window_mut(window_id).title.clone() - } - - pub fn simulate_window_close(&self, window_id: usize) -> bool { - let handler = self - .platform_window_mut(window_id) - .should_close_handler - .take(); - if let Some(mut handler) = handler { - let should_close = handler(); - self.platform_window_mut(window_id).should_close_handler = Some(handler); - should_close - } else { - false - } - } - - pub fn simulate_window_resize(&self, window_id: usize, size: Vector2F) { - let mut window = self.platform_window_mut(window_id); - window.size = size; - let mut handlers = mem::take(&mut window.resize_handlers); - drop(window); - for handler in &mut handlers { - handler(); - } - self.platform_window_mut(window_id).resize_handlers = handlers; - } - - pub fn is_window_edited(&self, window_id: usize) -> bool { - self.platform_window_mut(window_id).edited - } - pub fn leak_detector(&self) -> Arc> { self.cx.borrow().leak_detector() } @@ -344,18 +289,6 @@ impl TestAppContext { self.assert_dropped(weak); } - fn platform_window_mut(&self, window_id: usize) -> std::cell::RefMut { - std::cell::RefMut::map(self.cx.borrow_mut(), |state| { - let window = state.windows.get_mut(&window_id).unwrap(); - let test_window = window - .platform_window - .as_any_mut() - .downcast_mut::() - .unwrap(); - test_window - }) - } - pub fn set_condition_duration(&mut self, duration: Option) { self.condition_duration = duration; } @@ -545,6 +478,71 @@ impl ModelHandle { } } +impl AnyWindowHandle { + pub fn has_pending_prompt(&self, cx: &mut TestAppContext) -> bool { + let window = self.platform_window_mut(cx); + let prompts = window.pending_prompts.borrow_mut(); + !prompts.is_empty() + } + + pub fn current_title(&self, cx: &mut TestAppContext) -> Option { + self.platform_window_mut(cx).title.clone() + } + + pub fn simulate_close(&self, cx: &mut TestAppContext) -> bool { + let handler = self.platform_window_mut(cx).should_close_handler.take(); + if let Some(mut handler) = handler { + let should_close = handler(); + self.platform_window_mut(cx).should_close_handler = Some(handler); + should_close + } else { + false + } + } + + pub fn simulate_resize(&self, size: Vector2F, cx: &mut TestAppContext) { + let mut window = self.platform_window_mut(cx); + window.size = size; + let mut handlers = mem::take(&mut window.resize_handlers); + drop(window); + for handler in &mut handlers { + handler(); + } + self.platform_window_mut(cx).resize_handlers = handlers; + } + + pub fn is_edited(&self, cx: &mut TestAppContext) -> bool { + self.platform_window_mut(cx).edited + } + + pub fn simulate_prompt_answer(&self, answer: usize, cx: &mut TestAppContext) { + use postage::prelude::Sink as _; + + let mut done_tx = self + .platform_window_mut(cx) + .pending_prompts + .borrow_mut() + .pop_front() + .expect("prompt was not called"); + done_tx.try_send(answer).ok(); + } + + fn platform_window_mut<'a>( + &self, + cx: &'a mut TestAppContext, + ) -> std::cell::RefMut<'a, platform::test::Window> { + std::cell::RefMut::map(cx.cx.borrow_mut(), |state| { + let window = state.windows.get_mut(&self.window_id).unwrap(); + let test_window = window + .platform_window + .as_any_mut() + .downcast_mut::() + .unwrap(); + test_window + }) + } +} + impl ViewHandle { pub fn next_notification(&self, cx: &TestAppContext) -> impl Future { use postage::prelude::{Sink as _, Stream as _}; diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 021ea2d3bc3a817342e9eac684496ffeee5026bb..07aaea812a98d5758bb15b801c5cd8bdf1688e8f 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1726,7 +1726,7 @@ impl ClipboardEntry { #[cfg(test)] mod tests { use super::*; - use gpui::{TestAppContext, ViewHandle}; + use gpui::{AnyWindowHandle, TestAppContext, ViewHandle}; use pretty_assertions::assert_eq; use project::FakeFs; use serde_json::json; @@ -2421,7 +2421,7 @@ mod tests { ); ensure_single_file_is_opened(window_id, &workspace, "test/first.rs", cx); - submit_deletion(window_id, &panel, cx); + submit_deletion(window.into(), &panel, cx); assert_eq!( visible_entries_as_strings(&panel, 0..10, cx), &[ @@ -2432,7 +2432,7 @@ mod tests { ], "Project panel should have no deleted file, no other file is selected in it" ); - ensure_no_open_items_and_panes(window_id, &workspace, cx); + ensure_no_open_items_and_panes(window.into(), &workspace, cx); select_path(&panel, "src/test/second.rs", cx); panel.update(cx, |panel, cx| panel.open_file(&Open, cx)); @@ -2464,13 +2464,13 @@ mod tests { .expect("Open item should be an editor"); open_editor.update(cx, |editor, cx| editor.set_text("Another text!", cx)); }); - submit_deletion(window_id, &panel, cx); + submit_deletion(window.into(), &panel, cx); assert_eq!( visible_entries_as_strings(&panel, 0..10, cx), &["v src", " v test", " third.rs"], "Project panel should have no deleted file, with one last file remaining" ); - ensure_no_open_items_and_panes(window_id, &workspace, cx); + ensure_no_open_items_and_panes(window.into(), &workspace, cx); } #[gpui::test] @@ -2910,12 +2910,12 @@ mod tests { } fn submit_deletion( - window_id: usize, + window: AnyWindowHandle, panel: &ViewHandle, cx: &mut TestAppContext, ) { assert!( - !cx.has_pending_prompt(window_id), + !window.has_pending_prompt(cx), "Should have no prompts before the deletion" ); panel.update(cx, |panel, cx| { @@ -2925,27 +2925,27 @@ mod tests { .detach_and_log_err(cx); }); assert!( - cx.has_pending_prompt(window_id), + window.has_pending_prompt(cx), "Should have a prompt after the deletion" ); - cx.simulate_prompt_answer(window_id, 0); + window.simulate_prompt_answer(0, cx); assert!( - !cx.has_pending_prompt(window_id), + !window.has_pending_prompt(cx), "Should have no prompts after prompt was replied to" ); cx.foreground().run_until_parked(); } fn ensure_no_open_items_and_panes( - window_id: usize, + window: AnyWindowHandle, workspace: &ViewHandle, cx: &mut TestAppContext, ) { assert!( - !cx.has_pending_prompt(window_id), + !window.has_pending_prompt(cx), "Should have no prompts after deletion operation closes the file" ); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { let open_project_paths = workspace .read(cx) .panes() diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index dc52614ecf497542306a7705e3be2f938d825315..da708c6ea727de82b1c288a9549e6d627fad07b3 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -4197,17 +4197,11 @@ mod tests { .map(|e| e.id) ); }); - assert_eq!( - cx.current_window_title(window.id()).as_deref(), - Some("one.txt — root1") - ); + assert_eq!(window.current_title(cx).as_deref(), Some("one.txt — root1")); // Add a second item to a non-empty pane workspace.update(cx, |workspace, cx| workspace.add_item(Box::new(item2), cx)); - assert_eq!( - cx.current_window_title(window.id()).as_deref(), - Some("two.txt — root1") - ); + assert_eq!(window.current_title(cx).as_deref(), Some("two.txt — root1")); project.read_with(cx, |project, cx| { assert_eq!( project.active_entry(), @@ -4223,10 +4217,7 @@ mod tests { }) .await .unwrap(); - assert_eq!( - cx.current_window_title(window.id()).as_deref(), - Some("one.txt — root1") - ); + assert_eq!(window.current_title(cx).as_deref(), Some("one.txt — root1")); project.read_with(cx, |project, cx| { assert_eq!( project.active_entry(), @@ -4244,16 +4235,13 @@ mod tests { .await .unwrap(); assert_eq!( - cx.current_window_title(window.id()).as_deref(), + window.current_title(cx).as_deref(), Some("one.txt — root1, root2") ); // Remove a project folder project.update(cx, |project, cx| project.remove_worktree(worktree_id, cx)); - assert_eq!( - cx.current_window_title(window.id()).as_deref(), - Some("one.txt — root2") - ); + assert_eq!(window.current_title(cx).as_deref(), Some("one.txt — root2")); } #[gpui::test] @@ -4287,9 +4275,9 @@ mod tests { }); let task = workspace.update(cx, |w, cx| w.prepare_to_close(false, cx)); cx.foreground().run_until_parked(); - cx.simulate_prompt_answer(window.id(), 2 /* cancel */); + window.simulate_prompt_answer(2, cx); // cancel cx.foreground().run_until_parked(); - assert!(!cx.has_pending_prompt(window.id())); + assert!(!window.has_pending_prompt(cx)); assert!(!task.await.unwrap()); } @@ -4348,10 +4336,10 @@ mod tests { assert_eq!(pane.items_len(), 4); assert_eq!(pane.active_item().unwrap().id(), item1.id()); }); - assert!(cx.has_pending_prompt(window.id())); + assert!(window.has_pending_prompt(cx)); // Confirm saving item 1. - cx.simulate_prompt_answer(window.id(), 0); + window.simulate_prompt_answer(0, cx); cx.foreground().run_until_parked(); // Item 1 is saved. There's a prompt to save item 3. @@ -4362,10 +4350,10 @@ mod tests { assert_eq!(pane.items_len(), 3); assert_eq!(pane.active_item().unwrap().id(), item3.id()); }); - assert!(cx.has_pending_prompt(window.id())); + assert!(window.has_pending_prompt(cx)); // Cancel saving item 3. - cx.simulate_prompt_answer(window.id(), 1); + window.simulate_prompt_answer(1, cx); cx.foreground().run_until_parked(); // Item 3 is reloaded. There's a prompt to save item 4. @@ -4376,10 +4364,10 @@ mod tests { assert_eq!(pane.items_len(), 2); assert_eq!(pane.active_item().unwrap().id(), item4.id()); }); - assert!(cx.has_pending_prompt(window.id())); + assert!(window.has_pending_prompt(cx)); // Confirm saving item 4. - cx.simulate_prompt_answer(window.id(), 0); + window.simulate_prompt_answer(0, cx); cx.foreground().run_until_parked(); // There's a prompt for a path for item 4. @@ -4482,7 +4470,7 @@ mod tests { &[ProjectEntryId::from_proto(0)] ); }); - cx.simulate_prompt_answer(window.id(), 0); + window.simulate_prompt_answer(0, cx); cx.foreground().run_until_parked(); left_pane.read_with(cx, |pane, cx| { @@ -4491,7 +4479,7 @@ mod tests { &[ProjectEntryId::from_proto(2)] ); }); - cx.simulate_prompt_answer(window.id(), 0); + window.simulate_prompt_answer(0, cx); cx.foreground().run_until_parked(); close.await.unwrap(); @@ -4593,7 +4581,7 @@ mod tests { pane.update(cx, |pane, cx| pane.close_items(cx, move |id| id == item_id)) .await .unwrap(); - assert!(!cx.has_pending_prompt(window.id())); + assert!(!window.has_pending_prompt(cx)); item.read_with(cx, |item, _| assert_eq!(item.save_count, 5)); // Add the item again, ensuring autosave is prevented if the underlying file has been deleted. @@ -4614,7 +4602,7 @@ mod tests { let _close_items = pane.update(cx, |pane, cx| pane.close_items(cx, move |id| id == item_id)); deterministic.run_until_parked(); - assert!(cx.has_pending_prompt(window.id())); + assert!(window.has_pending_prompt(cx)); item.read_with(cx, |item, _| assert_eq!(item.save_count, 5)); } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 2b9321b303e8610bed75b9da53b770dbc6267c3a..3435727b1e0345ab1eef4cb63870b6b71f03c7f9 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -841,7 +841,8 @@ mod tests { assert_eq!(cx.windows().len(), 1); // When opening the workspace, the window is not in a edited state. - let workspace = cx.windows()[0].downcast::().unwrap().root(cx); + let window = cx.windows()[0].downcast::().unwrap(); + let workspace = window.root(cx); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); let editor = workspace.read_with(cx, |workspace, cx| { workspace @@ -850,19 +851,19 @@ mod tests { .downcast::() .unwrap() }); - assert!(!cx.is_window_edited(workspace.window_id())); + assert!(!window.is_edited(cx)); // Editing a buffer marks the window as edited. editor.update(cx, |editor, cx| editor.insert("EDIT", cx)); - assert!(cx.is_window_edited(workspace.window_id())); + assert!(window.is_edited(cx)); // Undoing the edit restores the window's edited state. editor.update(cx, |editor, cx| editor.undo(&Default::default(), cx)); - assert!(!cx.is_window_edited(workspace.window_id())); + assert!(!window.is_edited(cx)); // Redoing the edit marks the window as edited again. editor.update(cx, |editor, cx| editor.redo(&Default::default(), cx)); - assert!(cx.is_window_edited(workspace.window_id())); + assert!(window.is_edited(cx)); // Closing the item restores the window's edited state. let close = pane.update(cx, |pane, cx| { @@ -870,9 +871,10 @@ mod tests { pane.close_active_item(&Default::default(), cx).unwrap() }); executor.run_until_parked(); - cx.simulate_prompt_answer(workspace.window_id(), 1); + + window.simulate_prompt_answer(1, cx); close.await.unwrap(); - assert!(!cx.is_window_edited(workspace.window_id())); + assert!(!window.is_edited(cx)); // Opening the buffer again doesn't impact the window's edited state. cx.update(|cx| open_paths(&[PathBuf::from("/root/a")], &app_state, None, cx)) @@ -885,20 +887,20 @@ mod tests { .downcast::() .unwrap() }); - assert!(!cx.is_window_edited(workspace.window_id())); + assert!(!window.is_edited(cx)); // Editing the buffer marks the window as edited. editor.update(cx, |editor, cx| editor.insert("EDIT", cx)); - assert!(cx.is_window_edited(workspace.window_id())); + assert!(window.is_edited(cx)); // Ensure closing the window via the mouse gets preempted due to the // buffer having unsaved changes. - assert!(!cx.simulate_window_close(workspace.window_id())); + assert!(!window.simulate_close(cx)); executor.run_until_parked(); assert_eq!(cx.windows().len(), 1); // The window is successfully closed after the user dismisses the prompt. - cx.simulate_prompt_answer(workspace.window_id(), 1); + window.simulate_prompt_answer(1, cx); executor.run_until_parked(); assert_eq!(cx.windows().len(), 0); } @@ -1273,7 +1275,6 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); // Open a file within an existing worktree. workspace @@ -1299,7 +1300,7 @@ mod tests { cx.read(|cx| assert!(editor.is_dirty(cx))); let save_task = workspace.update(cx, |workspace, cx| workspace.save_active_item(false, cx)); - cx.simulate_prompt_answer(window_id, 0); + window.simulate_prompt_answer(0, cx); save_task.await.unwrap(); editor.read_with(cx, |editor, cx| { assert!(!editor.is_dirty(cx)); @@ -1506,7 +1507,7 @@ mod tests { cx.dispatch_action(window_id, workspace::CloseActiveItem); cx.foreground().run_until_parked(); - cx.simulate_prompt_answer(window_id, 1); + window.simulate_prompt_answer(1, cx); cx.foreground().run_until_parked(); workspace.read_with(cx, |workspace, cx| { From 0f332238b3076d17fbaf2ff920cf9eaeda6ac2ac Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 7 Aug 2023 22:08:44 -0600 Subject: [PATCH 143/160] Remove unused method --- crates/gpui/src/app/test_app_context.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index e298224caa2d0fc4829443a836cc9bbb91ef6087..e0fd0cb8e9f15407f25a22aaa0e768ff786caecc 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -125,13 +125,6 @@ impl TestAppContext { } } - pub fn window(&self, window_id: usize) -> Option> { - self.cx - .borrow() - .read_window(window_id, |cx| cx.window()) - .flatten() - } - pub fn read_window T>( &self, window_id: usize, From f0da6b05fdfec04e4583be1231c7d755dad24646 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 7 Aug 2023 22:15:53 -0600 Subject: [PATCH 144/160] Remove TestAppContext::add_view Instead, we now call this on window handles. --- crates/collab/src/tests.rs | 44 ++----------------- crates/collab/src/tests/integration_tests.rs | 40 ++++++++--------- crates/command_palette/src/command_palette.rs | 3 +- crates/diagnostics/src/diagnostics.rs | 6 +-- crates/editor/src/editor_tests.rs | 3 +- crates/gpui/src/app/test_app_context.rs | 9 ---- crates/project_symbols/src/project_symbols.rs | 3 +- crates/search/src/buffer_search.rs | 17 +++---- crates/search/src/project_search.rs | 3 +- 9 files changed, 35 insertions(+), 93 deletions(-) diff --git a/crates/collab/src/tests.rs b/crates/collab/src/tests.rs index 4804f5b0f1f24033fc79c12a6af5d87096a49a84..febe43ce5e1c78357c9ba4fa42c5a0f328b4ba9f 100644 --- a/crates/collab/src/tests.rs +++ b/crates/collab/src/tests.rs @@ -12,10 +12,7 @@ use client::{ use collections::{HashMap, HashSet}; use fs::FakeFs; use futures::{channel::oneshot, StreamExt as _}; -use gpui::{ - elements::*, executor::Deterministic, AnyElement, Entity, ModelHandle, TestAppContext, View, - ViewContext, ViewHandle, WeakViewHandle, -}; +use gpui::{executor::Deterministic, ModelHandle, TestAppContext, WindowHandle}; use language::LanguageRegistry; use parking_lot::Mutex; use project::{Project, WorktreeId}; @@ -466,43 +463,8 @@ impl TestClient { &self, project: &ModelHandle, cx: &mut TestAppContext, - ) -> ViewHandle { - struct WorkspaceContainer { - workspace: Option>, - } - - impl Entity for WorkspaceContainer { - type Event = (); - } - - impl View for WorkspaceContainer { - fn ui_name() -> &'static str { - "WorkspaceContainer" - } - - fn render(&mut self, cx: &mut ViewContext) -> AnyElement { - if let Some(workspace) = self - .workspace - .as_ref() - .and_then(|workspace| workspace.upgrade(cx)) - { - ChildView::new(&workspace, cx).into_any() - } else { - Empty::new().into_any() - } - } - } - - // We use a workspace container so that we don't need to remove the window in order to - // drop the workspace and we can use a ViewHandle instead. - let window = cx.add_window(|_| WorkspaceContainer { workspace: None }); - let container = window.root(cx); - let workspace = window.add_view(cx, |cx| Workspace::test_new(project.clone(), cx)); - container.update(cx, |container, cx| { - container.workspace = Some(workspace.downgrade()); - cx.notify(); - }); - workspace + ) -> WindowHandle { + cx.add_window(|cx| Workspace::test_new(project.clone(), cx)) } } diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index 29dcd95eae076cd38ae36fb950a41eabe98905a0..8ad7864adfc774888c395d9f14508a4e066edf63 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -6441,8 +6441,10 @@ async fn test_basic_following( .await .unwrap(); - let workspace_a = client_a.build_workspace(&project_a, cx_a); - let workspace_b = client_b.build_workspace(&project_b, cx_b); + let window_a = client_a.build_workspace(&project_a, cx_a); + let workspace_a = window_a.root(cx_a); + let window_b = client_b.build_workspace(&project_b, cx_b); + let workspace_b = window_b.root(cx_b); // Client A opens some editors. let pane_a = workspace_a.read_with(cx_a, |workspace, _| workspace.active_pane().clone()); @@ -6525,7 +6527,7 @@ async fn test_basic_following( cx_c.foreground().run_until_parked(); let active_call_c = cx_c.read(ActiveCall::global); let project_c = client_c.build_remote_project(project_id, cx_c).await; - let workspace_c = client_c.build_workspace(&project_c, cx_c); + let workspace_c = client_c.build_workspace(&project_c, cx_c).root(cx_c); active_call_c .update(cx_c, |call, cx| call.set_location(Some(&project_c), cx)) .await @@ -6543,7 +6545,7 @@ async fn test_basic_following( cx_d.foreground().run_until_parked(); let active_call_d = cx_d.read(ActiveCall::global); let project_d = client_d.build_remote_project(project_id, cx_d).await; - let workspace_d = client_d.build_workspace(&project_d, cx_d); + let workspace_d = client_d.build_workspace(&project_d, cx_d).root(cx_d); active_call_d .update(cx_d, |call, cx| call.set_location(Some(&project_d), cx)) .await @@ -6870,9 +6872,7 @@ async fn test_basic_following( }); // Client B activates a panel, and the previously-opened screen-sharing item gets activated. - let panel = cx_b.add_view(workspace_b.window_id(), |_| { - TestPanel::new(DockPosition::Left) - }); + let panel = window_b.add_view(cx_b, |_| TestPanel::new(DockPosition::Left)); workspace_b.update(cx_b, |workspace, cx| { workspace.add_panel(panel, cx); workspace.toggle_panel_focus::(cx); @@ -6900,7 +6900,7 @@ async fn test_basic_following( // Client B activates an item that doesn't implement following, // so the previously-opened screen-sharing item gets activated. - let unfollowable_item = cx_b.add_view(workspace_b.window_id(), |_| TestItem::new()); + let unfollowable_item = window_b.add_view(cx_b, |_| TestItem::new()); workspace_b.update(cx_b, |workspace, cx| { workspace.active_pane().update(cx, |pane, cx| { pane.add_item(Box::new(unfollowable_item), true, true, None, cx) @@ -7062,10 +7062,10 @@ async fn test_following_tab_order( .await .unwrap(); - let workspace_a = client_a.build_workspace(&project_a, cx_a); + let workspace_a = client_a.build_workspace(&project_a, cx_a).root(cx_a); let pane_a = workspace_a.read_with(cx_a, |workspace, _| workspace.active_pane().clone()); - let workspace_b = client_b.build_workspace(&project_b, cx_b); + let workspace_b = client_b.build_workspace(&project_b, cx_b).root(cx_b); let pane_b = workspace_b.read_with(cx_b, |workspace, _| workspace.active_pane().clone()); let client_b_id = project_a.read_with(cx_a, |project, _| { @@ -7188,7 +7188,7 @@ async fn test_peers_following_each_other( .unwrap(); // Client A opens some editors. - let workspace_a = client_a.build_workspace(&project_a, cx_a); + let workspace_a = client_a.build_workspace(&project_a, cx_a).root(cx_a); let pane_a1 = workspace_a.read_with(cx_a, |workspace, _| workspace.active_pane().clone()); let _editor_a1 = workspace_a .update(cx_a, |workspace, cx| { @@ -7200,7 +7200,7 @@ async fn test_peers_following_each_other( .unwrap(); // Client B opens an editor. - let workspace_b = client_b.build_workspace(&project_b, cx_b); + let workspace_b = client_b.build_workspace(&project_b, cx_b).root(cx_b); let pane_b1 = workspace_b.read_with(cx_b, |workspace, _| workspace.active_pane().clone()); let _editor_b1 = workspace_b .update(cx_b, |workspace, cx| { @@ -7359,7 +7359,7 @@ async fn test_auto_unfollowing( .unwrap(); // Client A opens some editors. - let workspace_a = client_a.build_workspace(&project_a, cx_a); + let workspace_a = client_a.build_workspace(&project_a, cx_a).root(cx_a); let _editor_a1 = workspace_a .update(cx_a, |workspace, cx| { workspace.open_path((worktree_id, "1.txt"), None, true, cx) @@ -7370,7 +7370,7 @@ async fn test_auto_unfollowing( .unwrap(); // Client B starts following client A. - let workspace_b = client_b.build_workspace(&project_b, cx_b); + let workspace_b = client_b.build_workspace(&project_b, cx_b).root(cx_b); let pane_b = workspace_b.read_with(cx_b, |workspace, _| workspace.active_pane().clone()); let leader_id = project_b.read_with(cx_b, |project, _| { project.collaborators().values().next().unwrap().peer_id @@ -7498,14 +7498,14 @@ async fn test_peers_simultaneously_following_each_other( client_a.fs.insert_tree("/a", json!({})).await; let (project_a, _) = client_a.build_local_project("/a", cx_a).await; - let workspace_a = client_a.build_workspace(&project_a, cx_a); + let workspace_a = client_a.build_workspace(&project_a, cx_a).root(cx_a); let project_id = active_call_a .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .await .unwrap(); let project_b = client_b.build_remote_project(project_id, cx_b).await; - let workspace_b = client_b.build_workspace(&project_b, cx_b); + let workspace_b = client_b.build_workspace(&project_b, cx_b).root(cx_b); deterministic.run_until_parked(); let client_a_id = project_b.read_with(cx_b, |project, _| { @@ -7887,7 +7887,7 @@ async fn test_mutual_editor_inlay_hint_cache_update( .await .unwrap(); - let workspace_a = client_a.build_workspace(&project_a, cx_a); + let workspace_a = client_a.build_workspace(&project_a, cx_a).root(cx_a); cx_a.foreground().start_waiting(); let _buffer_a = project_a @@ -7955,7 +7955,7 @@ async fn test_mutual_editor_inlay_hint_cache_update( "Host editor update the cache version after every cache/view change", ); }); - let workspace_b = client_b.build_workspace(&project_b, cx_b); + let workspace_b = client_b.build_workspace(&project_b, cx_b).root(cx_b); let editor_b = workspace_b .update(cx_b, |workspace, cx| { workspace.open_path((worktree_id, "main.rs"), None, true, cx) @@ -8194,8 +8194,8 @@ async fn test_inlay_hint_refresh_is_forwarded( .await .unwrap(); - let workspace_a = client_a.build_workspace(&project_a, cx_a); - let workspace_b = client_b.build_workspace(&project_b, cx_b); + let workspace_a = client_a.build_workspace(&project_a, cx_a).root(cx_a); + let workspace_b = client_b.build_workspace(&project_b, cx_b).root(cx_b); cx_a.foreground().start_waiting(); cx_b.foreground().start_waiting(); diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 7d4b4126b702774bf8c295d3b61f904ff7ebf80c..f51a6c923802c93b197f059aed2af24f7cfde0e9 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -297,8 +297,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), [], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); - let editor = cx.add_view(window_id, |cx| { + let editor = window.add_view(cx, |cx| { let mut editor = Editor::single_line(None, cx); editor.set_text("abc", cx); editor diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 2444465be666124adb706bcf1833c50c77cee081..16a7340fae485b1c1b329315700437e4470c3af9 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -857,7 +857,6 @@ mod tests { let project = Project::test(fs.clone(), ["/test".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); // Create some diagnostics project.update(cx, |project, cx| { @@ -944,7 +943,7 @@ mod tests { }); // Open the project diagnostics view while there are already diagnostics. - let view = cx.add_view(window_id, |cx| { + let view = window.add_view(cx, |cx| { ProjectDiagnosticsEditor::new(project.clone(), workspace.downgrade(), cx) }); @@ -1252,9 +1251,8 @@ mod tests { let project = Project::test(fs.clone(), ["/test".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); - let view = cx.add_view(window_id, |cx| { + let view = window.add_view(cx, |cx| { ProjectDiagnosticsEditor::new(project.clone(), workspace.downgrade(), cx) }); diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index c9688011a443fe0cb75fadbd9124b1feace579d6..ec1cc1249895881485489b56474c61aafd78d31d 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -525,9 +525,8 @@ async fn test_navigation_history(cx: &mut TestAppContext) { let project = Project::test(fs, [], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - cx.add_view(window_id, |cx| { + window.add_view(cx, |cx| { let buffer = MultiBuffer::build_simple(&sample_text(300, 5, 'a'), cx); let mut editor = build_editor(buffer.clone(), cx); let handle = cx.handle(); diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index e0fd0cb8e9f15407f25a22aaa0e768ff786caecc..ff988607b094f8d3253b8baaad2e6332bee4ad84 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -162,15 +162,6 @@ impl TestAppContext { WindowHandle::new(window.id()) } - pub fn add_view(&mut self, window_id: usize, build_view: F) -> ViewHandle - where - T: View, - F: FnOnce(&mut ViewContext) -> T, - { - self.update_window(window_id, |cx| cx.add_view(build_view)) - .expect("window not found") - } - pub fn observe_global(&mut self, callback: F) -> Subscription where E: Any, diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index 8471f3a3a7014d2034438839f76ae9b4214ded52..e88aee5dcfb6b9b5862ba92e6e8fc32fbc0da8cb 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -328,10 +328,9 @@ mod tests { let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); // Create the project symbols view. - let symbols = cx.add_view(window_id, |cx| { + let symbols = window.add_view(cx, |cx| { ProjectSymbols::new( ProjectSymbolsDelegate::new(workspace.downgrade(), project.clone()), cx, diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 1e635432bd5c138f81410f3ac40ee461830ddb17..b20ffed6d7e1ad94e9c311503c332e066e5c9b91 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -850,12 +850,9 @@ mod tests { ) }); let window = cx.add_window(|_| EmptyView); + let editor = window.add_view(cx, |cx| Editor::for_buffer(buffer.clone(), None, cx)); - let editor = cx.add_view(window.id(), |cx| { - Editor::for_buffer(buffer.clone(), None, cx) - }); - - let search_bar = cx.add_view(window.id(), |cx| { + let search_bar = window.add_view(cx, |cx| { let mut search_bar = BufferSearchBar::new(cx); search_bar.set_active_pane_item(Some(&editor), cx); search_bar.show(cx); @@ -1234,9 +1231,9 @@ mod tests { let window = cx.add_window(|_| EmptyView); let window_id = window.id(); - let editor = cx.add_view(window_id, |cx| Editor::for_buffer(buffer.clone(), None, cx)); + let editor = window.add_view(cx, |cx| Editor::for_buffer(buffer.clone(), None, cx)); - let search_bar = cx.add_view(window_id, |cx| { + let search_bar = window.add_view(cx, |cx| { let mut search_bar = BufferSearchBar::new(cx); search_bar.set_active_pane_item(Some(&editor), cx); search_bar.show(cx); @@ -1421,11 +1418,9 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, buffer_text, cx)); let window = cx.add_window(|_| EmptyView); - let editor = cx.add_view(window.id(), |cx| { - Editor::for_buffer(buffer.clone(), None, cx) - }); + let editor = window.add_view(cx, |cx| Editor::for_buffer(buffer.clone(), None, cx)); - let search_bar = cx.add_view(window.id(), |cx| { + let search_bar = window.add_view(cx, |cx| { let mut search_bar = BufferSearchBar::new(cx); search_bar.set_active_pane_item(Some(&editor), cx); search_bar.show(cx); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 0db66b4e378a56c97e2e2d1290742e52e1329bda..dffd88db14229871a805a282ccbc49670697206e 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1874,7 +1874,6 @@ pub mod tests { let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); workspace.update(cx, |workspace, cx| { ProjectSearchView::deploy(workspace, &workspace::NewSearch, cx) }); @@ -1889,7 +1888,7 @@ pub mod tests { .expect("Search view expected to appear after new search event trigger") }); - let search_bar = cx.add_view(window_id, |cx| { + let search_bar = window.add_view(cx, |cx| { let mut search_bar = ProjectSearchBar::new(); search_bar.set_active_pane_item(Some(&search_view), cx); // search_bar.show(cx); From dba2facd23d94ebb79aab8a32b4318ab28320c83 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 7 Aug 2023 22:58:01 -0600 Subject: [PATCH 145/160] Remove window via handles --- crates/collab_ui/src/incoming_call_notification.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/collab_ui/src/incoming_call_notification.rs b/crates/collab_ui/src/incoming_call_notification.rs index a9c5e697a5f60d0cb6f9c0e6baf7cac50aba192a..6f86a74300acc36e6fc7240dd023cb0d034e4f03 100644 --- a/crates/collab_ui/src/incoming_call_notification.rs +++ b/crates/collab_ui/src/incoming_call_notification.rs @@ -7,7 +7,7 @@ use gpui::{ elements::*, geometry::{rect::RectF, vector::vec2f}, platform::{CursorStyle, MouseButton, WindowBounds, WindowKind, WindowOptions}, - AnyElement, AppContext, Entity, View, ViewContext, + AnyElement, AppContext, Entity, View, ViewContext, WindowHandle, }; use util::ResultExt; use workspace::AppState; @@ -16,10 +16,10 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { let app_state = Arc::downgrade(app_state); let mut incoming_call = ActiveCall::global(cx).read(cx).incoming(); cx.spawn(|mut cx| async move { - let mut notification_windows = Vec::new(); + let mut notification_windows: Vec> = Vec::new(); while let Some(incoming_call) = incoming_call.next().await { - for window_id in notification_windows.drain(..) { - cx.remove_window(window_id); + for window in notification_windows.drain(..) { + window.remove(&mut cx); } if let Some(incoming_call) = incoming_call { @@ -49,7 +49,7 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { |_| IncomingCallNotification::new(incoming_call.clone(), app_state.clone()), ); - notification_windows.push(window.id()); + notification_windows.push(window); } } } From 1aff642981fd8b6fd9f4a0b58d7ca43758485edb Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 8 Aug 2023 13:09:27 +0200 Subject: [PATCH 146/160] Do not highlgiht selections at all over the threshold --- crates/editor/src/editor.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 17195cb22b5de1bc60c21c8169f929e020cc78f7..02cd58524bb5e6b5b97a17b751d9a2304abbaf11 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -7572,7 +7572,6 @@ impl Editor { }) { Ok(i) | Err(i) => i, }; - let end_ix = count.min(ranges.len()); let mut push_region = |start: Option, end: Option| { if let (Some(start_display), Some(end_display)) = (start, end) { results.push( @@ -7583,7 +7582,10 @@ impl Editor { }; let mut start_row: Option = None; let mut end_row: Option = None; - for range in &ranges[start_ix..end_ix] { + if ranges.len() > count { + return vec![]; + } + for range in &ranges[start_ix..] { if range.start.cmp(&search_range.end, buffer).is_ge() { break; } @@ -7616,9 +7618,6 @@ impl Editor { } // We might still have a hunk that was not rendered (if there was a search hit on the last line) push_region(start_row, end_row); - if results.len() > count { - return vec![]; - } results } From 49f1f1c6c263e1346f0534660c8ce2c8c70859be Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 09:13:17 -0600 Subject: [PATCH 147/160] Remove window when closing workspace in test --- crates/collab/src/tests/integration_tests.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index 8ad7864adfc774888c395d9f14508a4e066edf63..ce7fd8a094abb4006c97701c612ed65cae49a105 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -6527,7 +6527,8 @@ async fn test_basic_following( cx_c.foreground().run_until_parked(); let active_call_c = cx_c.read(ActiveCall::global); let project_c = client_c.build_remote_project(project_id, cx_c).await; - let workspace_c = client_c.build_workspace(&project_c, cx_c).root(cx_c); + let window_c = client_c.build_workspace(&project_c, cx_c); + let workspace_c = window_c.root(cx_c); active_call_c .update(cx_c, |call, cx| call.set_location(Some(&project_c), cx)) .await @@ -6643,6 +6644,7 @@ async fn test_basic_following( } // Client C closes the project. + window_c.remove(cx_c); cx_c.drop_last(workspace_c); // Clients A and B see that client B is following A, and client C is not present in the followers. From d896d89842ed11021482aaa477177d1203f56347 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 11:08:37 -0600 Subject: [PATCH 148/160] Store an AnyWindowHandle in WindowContext --- crates/collab_ui/src/contact_list.rs | 4 +- .../src/project_shared_notification.rs | 16 +- crates/command_palette/src/command_palette.rs | 8 +- crates/context_menu/src/context_menu.rs | 12 +- crates/file_finder/src/file_finder.rs | 42 +- crates/go_to_line/src/go_to_line.rs | 18 +- crates/gpui/src/app.rs | 621 +++++++++--------- crates/gpui/src/app/test_app_context.rs | 32 +- crates/gpui/src/app/window.rs | 149 ++--- crates/project_panel/src/project_panel.rs | 28 +- crates/search/src/buffer_search.rs | 15 +- crates/search/src/project_search.rs | 25 +- crates/vim/src/editor_events.rs | 10 +- crates/vim/src/mode_indicator.rs | 4 +- crates/vim/src/test/vim_test_context.rs | 4 +- crates/workspace/src/dock.rs | 12 +- crates/workspace/src/pane.rs | 4 +- crates/workspace/src/workspace.rs | 22 +- crates/zed/src/zed.rs | 59 +- 19 files changed, 526 insertions(+), 559 deletions(-) diff --git a/crates/collab_ui/src/contact_list.rs b/crates/collab_ui/src/contact_list.rs index 428f2156d116133d063710fed99c890e8ad30869..a2b281856d923754e715e0e112eca2f5c682e605 100644 --- a/crates/collab_ui/src/contact_list.rs +++ b/crates/collab_ui/src/contact_list.rs @@ -305,7 +305,7 @@ impl ContactList { github_login ); let mut answer = cx.prompt(PromptLevel::Warning, &prompt_message, &["Remove", "Cancel"]); - let window_id = cx.window_id(); + let window = cx.window(); cx.spawn(|_, mut cx| async move { if answer.next().await == Some(0) { if let Err(e) = user_store @@ -313,7 +313,7 @@ impl ContactList { .await { cx.prompt( - window_id, + window, PromptLevel::Info, &format!("Failed to remove contact: {}", e), &["Ok"], diff --git a/crates/collab_ui/src/project_shared_notification.rs b/crates/collab_ui/src/project_shared_notification.rs index d5e7c877f7067480688faedeb9b36be964878a72..63922f2b65c91df1053533584ac8f1bf3473c899 100644 --- a/crates/collab_ui/src/project_shared_notification.rs +++ b/crates/collab_ui/src/project_shared_notification.rs @@ -5,7 +5,7 @@ use gpui::{ elements::*, geometry::{rect::RectF, vector::vec2f}, platform::{CursorStyle, MouseButton, WindowBounds, WindowKind, WindowOptions}, - AppContext, BorrowWindowContext, Entity, View, ViewContext, + AppContext, Entity, View, ViewContext, }; use std::sync::{Arc, Weak}; use workspace::AppState; @@ -52,20 +52,20 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { notification_windows .entry(*project_id) .or_insert(Vec::new()) - .push(window.id()); + .push(window); } } room::Event::RemoteProjectUnshared { project_id } => { - if let Some(window_ids) = notification_windows.remove(&project_id) { - for window_id in window_ids { - cx.update_window(window_id, |cx| cx.remove_window()); + if let Some(windows) = notification_windows.remove(&project_id) { + for window in windows { + window.remove(cx); } } } room::Event::Left => { - for (_, window_ids) in notification_windows.drain() { - for window_id in window_ids { - cx.update_window(window_id, |cx| cx.remove_window()); + for (_, windows) in notification_windows.drain() { + for window in windows { + window.remove(cx); } } } diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index f51a6c923802c93b197f059aed2af24f7cfde0e9..b3703aa64a4549596caf47b57fc91971c985b8f0 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -80,11 +80,11 @@ impl PickerDelegate for CommandPaletteDelegate { query: String, cx: &mut ViewContext>, ) -> gpui::Task<()> { - let window_id = cx.window_id(); let view_id = self.focused_view_id; + let window = cx.window(); cx.spawn(move |picker, mut cx| async move { let actions = cx - .available_actions(window_id, view_id) + .available_actions(window, view_id) .into_iter() .filter_map(|(name, action, bindings)| { let filtered = cx.read(|cx| { @@ -162,13 +162,13 @@ impl PickerDelegate for CommandPaletteDelegate { fn confirm(&mut self, _: bool, cx: &mut ViewContext>) { if !self.matches.is_empty() { - let window_id = cx.window_id(); + let window = cx.window(); let focused_view_id = self.focused_view_id; let action_ix = self.matches[self.selected_ix].candidate_id; let action = self.actions.remove(action_ix).action; cx.app_context() .spawn(move |mut cx| async move { - cx.dispatch_action(window_id, focused_view_id, action.as_ref()) + cx.dispatch_action(window, focused_view_id, action.as_ref()) }) .detach_and_log_err(cx); } diff --git a/crates/context_menu/src/context_menu.rs b/crates/context_menu/src/context_menu.rs index f58afab361f4db153824ad9488fb295588dac425..75cfd872b29aba9b03b1235faeaba24d8ac95ae7 100644 --- a/crates/context_menu/src/context_menu.rs +++ b/crates/context_menu/src/context_menu.rs @@ -218,12 +218,12 @@ impl ContextMenu { if let Some(ContextMenuItem::Item { action, .. }) = self.items.get(ix) { match action { ContextMenuItemAction::Action(action) => { - let window_id = cx.window_id(); + let window = cx.window(); let view_id = self.parent_view_id; let action = action.boxed_clone(); cx.app_context() .spawn(|mut cx| async move { - cx.dispatch_action(window_id, view_id, action.as_ref()) + cx.dispatch_action(window, view_id, action.as_ref()) }) .detach_and_log_err(cx); } @@ -480,17 +480,13 @@ impl ContextMenu { .on_down(MouseButton::Left, |_, _, _| {}) // Capture these events .on_click(MouseButton::Left, move |_, menu, cx| { menu.cancel(&Default::default(), cx); - let window_id = cx.window_id(); + let window = cx.window(); match &action { ContextMenuItemAction::Action(action) => { let action = action.boxed_clone(); cx.app_context() .spawn(|mut cx| async move { - cx.dispatch_action( - window_id, - view_id, - action.as_ref(), - ) + cx.dispatch_action(window, view_id, action.as_ref()) }) .detach_and_log_err(cx); } diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 12bf3242627619d390409bba044c0fa9cdcce3d4..523d6e8a5caeb9edea4c990237263c66e7d384e4 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -619,7 +619,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.id(), Toggle); + cx.dispatch_action(window.into(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); finder @@ -632,8 +632,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.id(), SelectNext); - cx.dispatch_action(window.id(), Confirm); + cx.dispatch_action(window.into(), SelectNext); + cx.dispatch_action(window.into(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -674,7 +674,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.id(), Toggle); + cx.dispatch_action(window.into(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); let file_query = &first_file_name[..3]; @@ -706,8 +706,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.id(), SelectNext); - cx.dispatch_action(window.id(), Confirm); + cx.dispatch_action(window.into(), SelectNext); + cx.dispatch_action(window.into(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -758,7 +758,7 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - cx.dispatch_action(window.id(), Toggle); + cx.dispatch_action(window.into(), Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); let file_query = &first_file_name[..3]; @@ -790,8 +790,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window.id(), SelectNext); - cx.dispatch_action(window.id(), Confirm); + cx.dispatch_action(window.into(), SelectNext); + cx.dispatch_action(window.into(), Confirm); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) .await; @@ -1168,7 +1168,6 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1); @@ -1186,7 +1185,7 @@ mod tests { "fir", 1, "first.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1201,7 +1200,7 @@ mod tests { "sec", 1, "second.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1223,7 +1222,7 @@ mod tests { "thi", 1, "third.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1255,7 +1254,7 @@ mod tests { "sec", 1, "second.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1294,7 +1293,7 @@ mod tests { "thi", 1, "third.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1376,7 +1375,6 @@ mod tests { let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); let worktree_id = cx.read(|cx| { let worktrees = workspace.read(cx).worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1,); @@ -1411,7 +1409,7 @@ mod tests { "sec", 1, "second.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1433,7 +1431,7 @@ mod tests { "fir", 1, "first.rs", - window_id, + window.into(), &workspace, &deterministic, cx, @@ -1465,12 +1463,12 @@ mod tests { input: &str, expected_matches: usize, expected_editor_title: &str, - window_id: usize, + window: gpui::AnyWindowHandle, workspace: &ViewHandle, deterministic: &gpui::executor::Deterministic, cx: &mut gpui::TestAppContext, ) -> Vec { - cx.dispatch_action(window_id, Toggle); + cx.dispatch_action(window, Toggle); let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); finder .update(cx, |finder, cx| { @@ -1487,8 +1485,8 @@ mod tests { }); let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone()); - cx.dispatch_action(window_id, SelectNext); - cx.dispatch_action(window_id, Confirm); + cx.dispatch_action(window, SelectNext); + cx.dispatch_action(window, Confirm); deterministic.run_until_parked(); active_pane .condition(cx, |pane, _| pane.active_item().is_some()) diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index fa42a523741679c191c5fab053417243f4d5d4df..1d3b44fa4359ec31fbb3c6aab5ba9b161d23f693 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -135,16 +135,14 @@ impl Entity for GoToLine { fn release(&mut self, cx: &mut AppContext) { let scroll_position = self.prev_scroll_position.take(); - if let Some(window) = self.active_editor.window(cx) { - window.update(cx, |cx| { - self.active_editor.update(cx, |editor, cx| { - editor.highlight_rows(None); - if let Some(scroll_position) = scroll_position { - editor.set_scroll_position(scroll_position, cx); - } - }) - }); - } + self.active_editor.window().update(cx, |cx| { + self.active_editor.update(cx, |editor, cx| { + editor.highlight_rows(None); + if let Some(scroll_position) = scroll_position { + editor.set_scroll_position(scroll_position, cx); + } + }) + }); } } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index ff8e343c2caaf361c2b178f16d1c94b492973cb8..e0f46b036a07322844daf0fd7ca30c4d546e185f 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -134,16 +134,16 @@ pub trait BorrowAppContext { pub trait BorrowWindowContext { type Result; - fn read_window(&self, window_id: usize, f: F) -> Self::Result + fn read_window(&self, window: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&WindowContext) -> T; - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option; - fn update_window(&mut self, window_id: usize, f: F) -> Self::Result + fn update_window(&mut self, window: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T; - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option; } @@ -308,12 +308,12 @@ impl App { result } - fn update_window(&mut self, window_id: usize, callback: F) -> Option + fn update_window(&mut self, window: AnyWindowHandle, callback: F) -> Option where F: FnOnce(&mut WindowContext) -> T, { let mut state = self.0.borrow_mut(); - let result = state.update_window(window_id, callback); + let result = state.update_window(window, callback); state.pending_notifications.clear(); result } @@ -346,22 +346,22 @@ impl AsyncAppContext { pub fn read_window T>( &self, - window_id: usize, + window: AnyWindowHandle, callback: F, ) -> Option { - self.0.borrow_mut().read_window(window_id, callback) + self.0.borrow_mut().read_window(window, callback) } pub fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, callback: F, ) -> Option { - self.0.borrow_mut().update_window(window_id, callback) + self.0.borrow_mut().update_window(window, callback) } - pub fn debug_elements(&self, window_id: usize) -> Option { - self.0.borrow().read_window(window_id, |cx| { + pub fn debug_elements(&self, window: AnyWindowHandle) -> Option { + self.0.borrow().read_window(window, |cx| { let root_view = cx.window.root_view(); let root_element = cx.window.rendered_views.get(&root_view.id())?; root_element.debug(cx).log_err() @@ -370,13 +370,13 @@ impl AsyncAppContext { pub fn dispatch_action( &mut self, - window_id: usize, + window: AnyWindowHandle, view_id: usize, action: &dyn Action, ) -> Result<()> { self.0 .borrow_mut() - .update_window(window_id, |cx| { + .update_window(window, |cx| { cx.dispatch_action(Some(view_id), action); }) .ok_or_else(|| anyhow!("window not found")) @@ -384,10 +384,10 @@ impl AsyncAppContext { pub fn available_actions( &self, - window_id: usize, + window: AnyWindowHandle, view_id: usize, ) -> Vec<(&'static str, Box, SmallVec<[Binding; 1]>)> { - self.read_window(window_id, |cx| cx.available_actions(view_id)) + self.read_window(window, |cx| cx.available_actions(view_id)) .unwrap_or_default() } @@ -411,23 +411,23 @@ impl AsyncAppContext { self.update(|cx| cx.add_window(window_options, build_root_view)) } - pub fn remove_window(&mut self, window_id: usize) { - self.update_window(window_id, |cx| cx.remove_window()); + pub fn remove_window(&mut self, window: AnyWindowHandle) { + self.update_window(window, |cx| cx.remove_window()); } - pub fn activate_window(&mut self, window_id: usize) { - self.update_window(window_id, |cx| cx.activate_window()); + pub fn activate_window(&mut self, window: AnyWindowHandle) { + self.update_window(window, |cx| cx.activate_window()); } // TODO: Can we eliminate this method and move it to WindowContext then call it with update_window?s pub fn prompt( &mut self, - window_id: usize, + window: AnyWindowHandle, level: PromptLevel, msg: &str, answers: &[&str], ) -> Option> { - self.update_window(window_id, |cx| cx.prompt(level, msg, answers)) + self.update_window(window, |cx| cx.prompt(level, msg, answers)) } pub fn platform(&self) -> Arc { @@ -456,38 +456,36 @@ impl BorrowAppContext for AsyncAppContext { impl BorrowWindowContext for AsyncAppContext { type Result = Option; - fn read_window(&self, window_id: usize, f: F) -> Self::Result + fn read_window(&self, window: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&WindowContext) -> T, { - self.0.borrow().read_with(|cx| cx.read_window(window_id, f)) + self.0.borrow().read_with(|cx| cx.read_window(window, f)) } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { self.0 .borrow_mut() - .update(|cx| cx.read_window_optional(window_id, f)) + .update(|cx| cx.read_window_optional(window, f)) } - fn update_window(&mut self, window_id: usize, f: F) -> Self::Result + fn update_window(&mut self, window: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T, { - self.0 - .borrow_mut() - .update(|cx| cx.update_window(window_id, f)) + self.0.borrow_mut().update(|cx| cx.update_window(window, f)) } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { self.0 .borrow_mut() - .update(|cx| cx.update_window_optional(window_id, f)) + .update(|cx| cx.update_window_optional(window, f)) } } @@ -534,7 +532,7 @@ pub struct AppContext { global_actions: HashMap>, keystroke_matcher: KeymapMatcher, next_id: usize, - // next_window_id: usize, + // next_window: AnyWindowHandle, next_subscription_id: usize, frame_count: usize, @@ -794,13 +792,13 @@ impl AppContext { } } - pub fn view_ui_name(&self, window_id: usize, view_id: usize) -> Option<&'static str> { - Some(self.views.get(&(window_id, view_id))?.ui_name()) + pub fn view_ui_name(&self, window: AnyWindowHandle, view_id: usize) -> Option<&'static str> { + Some(self.views.get(&(window.id(), view_id))?.ui_name()) } - pub fn view_type_id(&self, window_id: usize, view_id: usize) -> Option { + pub fn view_type_id(&self, window: AnyWindowHandle, view_id: usize) -> Option { self.views_metadata - .get(&(window_id, view_id)) + .get(&(window.id(), view_id)) .map(|metadata| metadata.type_id) } @@ -823,11 +821,11 @@ impl AppContext { fn read_window T>( &self, - window_id: usize, + handle: AnyWindowHandle, callback: F, ) -> Option { - let window = self.windows.get(&window_id)?; - let window_context = WindowContext::immutable(self, &window, window_id); + let window = self.windows.get(&handle.id())?; + let window_context = WindowContext::immutable(self, &window, handle); Some(callback(&window_context)) } @@ -835,9 +833,8 @@ impl AppContext { &mut self, callback: F, ) -> Option { - self.platform - .main_window_id() - .and_then(|id| self.update_window(id, callback)) + self.main_window() + .and_then(|window| window.update(self, callback)) } pub fn prompt_for_paths( @@ -1075,10 +1072,10 @@ impl AppContext { } } - fn notify_view(&mut self, window_id: usize, view_id: usize) { + fn notify_view(&mut self, window: AnyWindowHandle, view_id: usize) { if self.pending_notifications.insert(view_id) { self.pending_effects - .push_back(Effect::ViewNotification { window_id, view_id }); + .push_back(Effect::ViewNotification { window, view_id }); } } @@ -1096,13 +1093,13 @@ impl AppContext { pub fn is_action_available(&self, action: &dyn Action) -> bool { let mut available_in_window = false; let action_id = action.id(); - if let Some(window_id) = self.platform.main_window_id() { + if let Some(window) = self.main_window() { available_in_window = self - .read_window(window_id, |cx| { + .read_window(window, |cx| { if let Some(focused_view_id) = cx.focused_view_id() { for view_id in cx.ancestors(focused_view_id) { if let Some(view_metadata) = - cx.views_metadata.get(&(window_id, view_id)) + cx.views_metadata.get(&(cx.window_handle.id(), view_id)) { if let Some(actions) = cx.actions.get(&view_metadata.type_id) { if actions.contains_key(&action_id) { @@ -1367,13 +1364,12 @@ impl AppContext { F: FnOnce(&mut ViewContext) -> V, { let handle: AnyWindowHandle = handle.into(); - let window_id = handle.id(); { let mut app = self.upgrade(); platform_window.on_event(Box::new(move |event| { - app.update_window(window_id, |cx| { + app.update_window(handle, |cx| { if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event { if cx.dispatch_keystroke(keystroke) { return true; @@ -1389,35 +1385,35 @@ impl AppContext { { let mut app = self.upgrade(); platform_window.on_active_status_change(Box::new(move |is_active| { - app.update(|cx| cx.window_changed_active_status(window_id, is_active)) + app.update(|cx| cx.window_changed_active_status(handle, is_active)) })); } { let mut app = self.upgrade(); platform_window.on_resize(Box::new(move || { - app.update(|cx| cx.window_was_resized(window_id)) + app.update(|cx| cx.window_was_resized(handle)) })); } { let mut app = self.upgrade(); platform_window.on_moved(Box::new(move || { - app.update(|cx| cx.window_was_moved(window_id)) + app.update(|cx| cx.window_was_moved(handle)) })); } { let mut app = self.upgrade(); platform_window.on_fullscreen(Box::new(move |is_fullscreen| { - app.update(|cx| cx.window_was_fullscreen_changed(window_id, is_fullscreen)) + app.update(|cx| cx.window_was_fullscreen_changed(handle, is_fullscreen)) })); } { let mut app = self.upgrade(); platform_window.on_close(Box::new(move || { - app.update(|cx| cx.update_window(window_id, |cx| cx.remove_window())); + app.update(|cx| cx.update_window(handle, |cx| cx.remove_window())); })); } @@ -1432,8 +1428,8 @@ impl AppContext { window: handle, })); - let mut window = Window::new(window_id, platform_window, self, build_root_view); - let mut cx = WindowContext::mutable(self, &mut window, window_id); + let mut window = Window::new(handle, platform_window, self, build_root_view); + let mut cx = WindowContext::mutable(self, &mut window, handle); cx.layout(false).expect("initial layout should not error"); let scene = cx.paint().expect("initial paint should not error"); window.platform_window.present_scene(scene); @@ -1455,7 +1451,7 @@ impl AppContext { } pub fn read_view(&self, handle: &ViewHandle) -> &T { - if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) { + if let Some(view) = self.views.get(&(handle.window.id(), handle.view_id)) { view.as_any().downcast_ref().expect("downcast is type safe") } else { panic!("circular view reference for type {}", type_name::()); @@ -1465,7 +1461,7 @@ impl AppContext { fn upgrade_view_handle(&self, handle: &WeakViewHandle) -> Option> { if self.ref_counts.lock().is_entity_alive(handle.view_id) { Some(ViewHandle::new( - handle.window_id, + handle.window, handle.view_id, &self.ref_counts, )) @@ -1477,7 +1473,7 @@ impl AppContext { fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option { if self.ref_counts.lock().is_entity_alive(handle.view_id) { Some(AnyViewHandle::new( - handle.window_id, + handle.window, handle.view_id, handle.view_type, self.ref_counts.clone(), @@ -1585,9 +1581,10 @@ impl AppContext { observations.emit(model_id, |callback| callback(self)); } - Effect::ViewNotification { window_id, view_id } => { - self.handle_view_notification_effect(window_id, view_id) - } + Effect::ViewNotification { + window: window_id, + view_id, + } => self.handle_view_notification_effect(window_id, view_id), Effect::GlobalNotification { type_id } => { let mut subscriptions = self.global_observations.clone(); @@ -1618,13 +1615,13 @@ impl AppContext { Effect::Focus(mut effect) => { if focus_effects - .get(&effect.window_id()) + .get(&effect.window().id()) .map_or(false, |prev_effect| prev_effect.is_forced()) { effect.force(); } - focus_effects.insert(effect.window_id(), effect); + focus_effects.insert(effect.window().id(), effect); } Effect::FocusObservation { @@ -1639,42 +1636,38 @@ impl AppContext { ); } - Effect::ResizeWindow { window_id } => { - if let Some(window) = self.windows.get_mut(&window_id) { + Effect::ResizeWindow { window } => { + if let Some(window) = self.windows.get_mut(&window.id()) { window .invalidation .get_or_insert(WindowInvalidation::default()); } - self.handle_window_moved(window_id); + self.handle_window_moved(window); } - Effect::MoveWindow { window_id } => { - self.handle_window_moved(window_id); + Effect::MoveWindow { window } => { + self.handle_window_moved(window); } Effect::WindowActivationObservation { - window_id, + window, subscription_id, callback, } => self.window_activation_observations.add_callback( - window_id, + window.id(), subscription_id, callback, ), - Effect::ActivateWindow { - window_id, - is_active, - } => { - if self.handle_window_activation_effect(window_id, is_active) - && is_active + Effect::ActivateWindow { window, is_active } => { + if self.handle_window_activation_effect(window, is_active) && is_active { focus_effects - .entry(window_id) + .entry(window.id()) .or_insert_with(|| FocusEffect::View { - window_id, + window, view_id: self - .read_window(window_id, |cx| cx.focused_view_id()) + .read_window(window, |cx| cx.focused_view_id()) .flatten(), is_forced: true, }) @@ -1683,26 +1676,26 @@ impl AppContext { } Effect::WindowFullscreenObservation { - window_id, + window, subscription_id, callback, } => self.window_fullscreen_observations.add_callback( - window_id, + window.id(), subscription_id, callback, ), Effect::FullscreenWindow { - window_id, + window, is_fullscreen, - } => self.handle_fullscreen_effect(window_id, is_fullscreen), + } => self.handle_fullscreen_effect(window, is_fullscreen), Effect::WindowBoundsObservation { - window_id, + window, subscription_id, callback, } => self.window_bounds_observations.add_callback( - window_id, + window.id(), subscription_id, callback, ), @@ -1714,18 +1707,15 @@ impl AppContext { Effect::ActionDispatchNotification { action_id } => { self.handle_action_dispatch_notification_effect(action_id) } - Effect::WindowShouldCloseSubscription { - window_id, - callback, - } => { - self.handle_window_should_close_subscription_effect(window_id, callback) + Effect::WindowShouldCloseSubscription { window, callback } => { + self.handle_window_should_close_subscription_effect(window, callback) } Effect::Keystroke { - window_id, + window, keystroke, handled_by, result, - } => self.handle_keystroke_effect(window_id, keystroke, handled_by, result), + } => self.handle_keystroke_effect(window, keystroke, handled_by, result), Effect::ActiveLabeledTasksChanged => { self.handle_active_labeled_tasks_changed_effect() } @@ -1740,8 +1730,8 @@ impl AppContext { } self.pending_notifications.clear(); } else { - for window_id in self.windows.keys().cloned().collect::>() { - self.update_window(window_id, |cx| { + for window in self.windows().collect::>() { + self.update_window(window, |cx| { let invalidation = if refreshing { let mut invalidation = cx.window.invalidation.take().unwrap_or_default(); @@ -1757,7 +1747,7 @@ impl AppContext { let appearance = cx.window.platform_window.appearance(); cx.invalidate(invalidation, appearance); if let Some(old_parents) = cx.layout(refreshing).log_err() { - updated_windows.insert(window_id); + updated_windows.insert(window); if let Some(focused_view_id) = cx.focused_view_id() { let old_ancestors = std::iter::successors( @@ -1772,7 +1762,7 @@ impl AppContext { for old_ancestor in old_ancestors.iter().copied() { if !new_ancestors.contains(&old_ancestor) { if let Some(mut view) = - cx.views.remove(&(window_id, old_ancestor)) + cx.views.remove(&(window.id(), old_ancestor)) { view.focus_out( focused_view_id, @@ -1780,7 +1770,7 @@ impl AppContext { old_ancestor, ); cx.views - .insert((window_id, old_ancestor), view); + .insert((window.id(), old_ancestor), view); } } } @@ -1789,7 +1779,7 @@ impl AppContext { for new_ancestor in new_ancestors.iter().copied() { if !old_ancestors.contains(&new_ancestor) { if let Some(mut view) = - cx.views.remove(&(window_id, new_ancestor)) + cx.views.remove(&(window.id(), new_ancestor)) { view.focus_in( focused_view_id, @@ -1797,7 +1787,7 @@ impl AppContext { new_ancestor, ); cx.views - .insert((window_id, new_ancestor), view); + .insert((window.id(), new_ancestor), view); } } } @@ -1806,13 +1796,15 @@ impl AppContext { // there isn't any pending focus, focus the root view. let root_view_id = cx.window.root_view().id(); if focused_view_id != root_view_id - && !cx.views.contains_key(&(window_id, focused_view_id)) - && !focus_effects.contains_key(&window_id) + && !cx + .views + .contains_key(&(window.id(), focused_view_id)) + && !focus_effects.contains_key(&window.id()) { focus_effects.insert( - window_id, + window.id(), FocusEffect::View { - window_id, + window, view_id: Some(root_view_id), is_forced: false, }, @@ -1833,8 +1825,8 @@ impl AppContext { callback(self); } - for window_id in updated_windows.drain() { - self.update_window(window_id, |cx| { + for window in updated_windows.drain() { + self.update_window(window, |cx| { if let Some(scene) = cx.paint().log_err() { cx.window.platform_window.present_scene(scene); } @@ -1855,39 +1847,37 @@ impl AppContext { } } - fn window_was_resized(&mut self, window_id: usize) { + fn window_was_resized(&mut self, window: AnyWindowHandle) { self.pending_effects - .push_back(Effect::ResizeWindow { window_id }); + .push_back(Effect::ResizeWindow { window }); } - fn window_was_moved(&mut self, window_id: usize) { + fn window_was_moved(&mut self, window: AnyWindowHandle) { self.pending_effects - .push_back(Effect::MoveWindow { window_id }); + .push_back(Effect::MoveWindow { window }); } - fn window_was_fullscreen_changed(&mut self, window_id: usize, is_fullscreen: bool) { + fn window_was_fullscreen_changed(&mut self, window: AnyWindowHandle, is_fullscreen: bool) { self.pending_effects.push_back(Effect::FullscreenWindow { - window_id, + window, is_fullscreen, }); } - fn window_changed_active_status(&mut self, window_id: usize, is_active: bool) { - self.pending_effects.push_back(Effect::ActivateWindow { - window_id, - is_active, - }); + fn window_changed_active_status(&mut self, window: AnyWindowHandle, is_active: bool) { + self.pending_effects + .push_back(Effect::ActivateWindow { window, is_active }); } fn keystroke( &mut self, - window_id: usize, + window: AnyWindowHandle, keystroke: Keystroke, handled_by: Option>, result: MatchResult, ) { self.pending_effects.push_back(Effect::Keystroke { - window_id, + window, keystroke, handled_by, result, @@ -1910,16 +1900,16 @@ impl AppContext { fn handle_view_notification_effect( &mut self, - observed_window_id: usize, + observed_window: AnyWindowHandle, observed_view_id: usize, ) { - let view_key = (observed_window_id, observed_view_id); + let view_key = (observed_window.id(), observed_view_id); if let Some((view, mut view_metadata)) = self .views .remove(&view_key) .zip(self.views_metadata.remove(&view_key)) { - if let Some(window) = self.windows.get_mut(&observed_window_id) { + if let Some(window) = self.windows.get_mut(&observed_window.id()) { window .invalidation .get_or_insert_with(Default::default) @@ -1946,17 +1936,17 @@ impl AppContext { }) } - fn handle_fullscreen_effect(&mut self, window_id: usize, is_fullscreen: bool) { - self.update_window(window_id, |cx| { + fn handle_fullscreen_effect(&mut self, window: AnyWindowHandle, is_fullscreen: bool) { + self.update_window(window, |cx| { cx.window.is_fullscreen = is_fullscreen; let mut fullscreen_observations = cx.window_fullscreen_observations.clone(); - fullscreen_observations.emit(window_id, |callback| callback(is_fullscreen, cx)); + fullscreen_observations.emit(window.id(), |callback| callback(is_fullscreen, cx)); if let Some(uuid) = cx.window_display_uuid() { let bounds = cx.window_bounds(); let mut bounds_observations = cx.window_bounds_observations.clone(); - bounds_observations.emit(window_id, |callback| callback(bounds, uuid, cx)); + bounds_observations.emit(window.id(), |callback| callback(bounds, uuid, cx)); } Some(()) @@ -1965,42 +1955,42 @@ impl AppContext { fn handle_keystroke_effect( &mut self, - window_id: usize, + window: AnyWindowHandle, keystroke: Keystroke, handled_by: Option>, result: MatchResult, ) { - self.update_window(window_id, |cx| { + self.update_window(window, |cx| { let mut observations = cx.keystroke_observations.clone(); - observations.emit(window_id, move |callback| { + observations.emit(window.id(), move |callback| { callback(&keystroke, &result, handled_by.as_ref(), cx) }); }); } - fn handle_window_activation_effect(&mut self, window_id: usize, active: bool) -> bool { - self.update_window(window_id, |cx| { + fn handle_window_activation_effect(&mut self, window: AnyWindowHandle, active: bool) -> bool { + self.update_window(window, |cx| { if cx.window.is_active == active { return false; } cx.window.is_active = active; let mut observations = cx.window_activation_observations.clone(); - observations.emit(window_id, |callback| callback(active, cx)); + observations.emit(window.id(), |callback| callback(active, cx)); true }) .unwrap_or(false) } fn handle_focus_effect(&mut self, effect: FocusEffect) { - let window_id = effect.window_id(); - self.update_window(window_id, |cx| { + let window = effect.window(); + self.update_window(window, |cx| { // Ensure the newly-focused view still exists, otherwise focus // the root view instead. let focused_id = match effect { FocusEffect::View { view_id, .. } => { if let Some(view_id) = view_id { - if cx.views.contains_key(&(window_id, view_id)) { + if cx.views.contains_key(&(window.id(), view_id)) { Some(view_id) } else { Some(cx.root_view().id()) @@ -2025,9 +2015,9 @@ impl AppContext { if focus_changed { if let Some(blurred_id) = blurred_id { for view_id in cx.ancestors(blurred_id).collect::>() { - if let Some(mut view) = cx.views.remove(&(window_id, view_id)) { + if let Some(mut view) = cx.views.remove(&(window.id(), view_id)) { view.focus_out(blurred_id, cx, view_id); - cx.views.insert((window_id, view_id), view); + cx.views.insert((window.id(), view_id), view); } } @@ -2039,9 +2029,9 @@ impl AppContext { if focus_changed || effect.is_forced() { if let Some(focused_id) = focused_id { for view_id in cx.ancestors(focused_id).collect::>() { - if let Some(mut view) = cx.views.remove(&(window_id, view_id)) { + if let Some(mut view) = cx.views.remove(&(window.id(), view_id)) { view.focus_in(focused_id, cx, view_id); - cx.views.insert((window_id, view_id), view); + cx.views.insert((window.id(), view_id), view); } } @@ -2063,24 +2053,24 @@ impl AppContext { fn handle_window_should_close_subscription_effect( &mut self, - window_id: usize, + window: AnyWindowHandle, mut callback: WindowShouldCloseSubscriptionCallback, ) { let mut app = self.upgrade(); - if let Some(window) = self.windows.get_mut(&window_id) { + if let Some(window) = self.windows.get_mut(&window.id()) { window .platform_window .on_should_close(Box::new(move || app.update(|cx| callback(cx)))) } } - fn handle_window_moved(&mut self, window_id: usize) { - self.update_window(window_id, |cx| { + fn handle_window_moved(&mut self, window: AnyWindowHandle) { + self.update_window(window, |cx| { if let Some(display) = cx.window_display_uuid() { let bounds = cx.window_bounds(); cx.window_bounds_observations .clone() - .emit(window_id, move |callback| { + .emit(window.id(), move |callback| { callback(bounds, display, cx); true }); @@ -2097,10 +2087,10 @@ impl AppContext { }); } - pub fn focus(&mut self, window_id: usize, view_id: Option) { + pub fn focus(&mut self, window: AnyWindowHandle, view_id: Option) { self.pending_effects .push_back(Effect::Focus(FocusEffect::View { - window_id, + window, view_id, is_forced: false, })); @@ -2185,40 +2175,40 @@ impl BorrowAppContext for AppContext { impl BorrowWindowContext for AppContext { type Result = Option; - fn read_window(&self, window_id: usize, f: F) -> Self::Result + fn read_window(&self, window: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&WindowContext) -> T, { - AppContext::read_window(self, window_id, f) + AppContext::read_window(self, window, f) } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { - AppContext::read_window(self, window_id, f).flatten() + AppContext::read_window(self, window, f).flatten() } - fn update_window(&mut self, window_id: usize, f: F) -> Self::Result + fn update_window(&mut self, handle: AnyWindowHandle, f: F) -> Self::Result where F: FnOnce(&mut WindowContext) -> T, { self.update(|app_context| { - let mut window = app_context.windows.remove(&window_id)?; - let mut window_context = WindowContext::mutable(app_context, &mut window, window_id); + let mut window = app_context.windows.remove(&handle.id())?; + let mut window_context = WindowContext::mutable(app_context, &mut window, handle); let result = f(&mut window_context); if !window_context.removed { - app_context.windows.insert(window_id, window); + app_context.windows.insert(handle.id(), window); } Some(result) }) } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, handle: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - AppContext::update_window(self, window_id, f).flatten() + AppContext::update_window(self, handle, f).flatten() } } @@ -2242,22 +2232,22 @@ pub struct WindowInvalidation { #[derive(Debug)] pub enum FocusEffect { View { - window_id: usize, + window: AnyWindowHandle, view_id: Option, is_forced: bool, }, ViewParent { - window_id: usize, + window: AnyWindowHandle, view_id: usize, is_forced: bool, }, } impl FocusEffect { - fn window_id(&self) -> usize { + fn window(&self) -> AnyWindowHandle { match self { - FocusEffect::View { window_id, .. } => *window_id, - FocusEffect::ViewParent { window_id, .. } => *window_id, + FocusEffect::View { window, .. } => *window, + FocusEffect::ViewParent { window, .. } => *window, } } @@ -2303,7 +2293,7 @@ pub enum Effect { model_id: usize, }, ViewNotification { - window_id: usize, + window: AnyWindowHandle, view_id: usize, }, Deferred { @@ -2328,36 +2318,36 @@ pub enum Effect { callback: FocusObservationCallback, }, ResizeWindow { - window_id: usize, + window: AnyWindowHandle, }, MoveWindow { - window_id: usize, + window: AnyWindowHandle, }, ActivateWindow { - window_id: usize, + window: AnyWindowHandle, is_active: bool, }, WindowActivationObservation { - window_id: usize, + window: AnyWindowHandle, subscription_id: usize, callback: WindowActivationCallback, }, FullscreenWindow { - window_id: usize, + window: AnyWindowHandle, is_fullscreen: bool, }, WindowFullscreenObservation { - window_id: usize, + window: AnyWindowHandle, subscription_id: usize, callback: WindowFullscreenCallback, }, WindowBoundsObservation { - window_id: usize, + window: AnyWindowHandle, subscription_id: usize, callback: WindowBoundsCallback, }, Keystroke { - window_id: usize, + window: AnyWindowHandle, keystroke: Keystroke, handled_by: Option>, result: MatchResult, @@ -2367,7 +2357,7 @@ pub enum Effect { action_id: TypeId, }, WindowShouldCloseSubscription { - window_id: usize, + window: AnyWindowHandle, callback: WindowShouldCloseSubscriptionCallback, }, ActiveLabeledTasksChanged, @@ -2419,9 +2409,9 @@ impl Debug for Effect { .debug_struct("Effect::ModelNotification") .field("model_id", model_id) .finish(), - Effect::ViewNotification { window_id, view_id } => f + Effect::ViewNotification { window, view_id } => f .debug_struct("Effect::ViewNotification") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("view_id", view_id) .finish(), Effect::GlobalNotification { type_id } => f @@ -2451,71 +2441,68 @@ impl Debug for Effect { .debug_struct("Effect::ActionDispatchNotification") .field("action_id", action_id) .finish(), - Effect::ResizeWindow { window_id } => f + Effect::ResizeWindow { window } => f .debug_struct("Effect::RefreshWindow") - .field("window_id", window_id) + .field("window_id", &window.id()) .finish(), - Effect::MoveWindow { window_id } => f + Effect::MoveWindow { window } => f .debug_struct("Effect::MoveWindow") - .field("window_id", window_id) + .field("window_id", &window.id()) .finish(), Effect::WindowActivationObservation { - window_id, + window, subscription_id, .. } => f .debug_struct("Effect::WindowActivationObservation") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("subscription_id", subscription_id) .finish(), - Effect::ActivateWindow { - window_id, - is_active, - } => f + Effect::ActivateWindow { window, is_active } => f .debug_struct("Effect::ActivateWindow") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("is_active", is_active) .finish(), Effect::FullscreenWindow { - window_id, + window, is_fullscreen, } => f .debug_struct("Effect::FullscreenWindow") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("is_fullscreen", is_fullscreen) .finish(), Effect::WindowFullscreenObservation { - window_id, + window, subscription_id, callback: _, } => f .debug_struct("Effect::WindowFullscreenObservation") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("subscription_id", subscription_id) .finish(), Effect::WindowBoundsObservation { - window_id, + window, subscription_id, callback: _, } => f .debug_struct("Effect::WindowBoundsObservation") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("subscription_id", subscription_id) .finish(), Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(), - Effect::WindowShouldCloseSubscription { window_id, .. } => f + Effect::WindowShouldCloseSubscription { window, .. } => f .debug_struct("Effect::WindowShouldCloseSubscription") - .field("window_id", window_id) + .field("window_id", &window.id()) .finish(), Effect::Keystroke { - window_id, + window, keystroke, handled_by, result, } => f .debug_struct("Effect::Keystroke") - .field("window_id", window_id) + .field("window_id", &window.id()) .field("keystroke", keystroke) .field( "keystroke", @@ -2613,9 +2600,14 @@ pub trait AnyView { cx: &mut WindowContext, view_id: usize, ); - fn any_handle(&self, window_id: usize, view_id: usize, cx: &AppContext) -> AnyViewHandle { + fn any_handle( + &self, + window: AnyWindowHandle, + view_id: usize, + cx: &AppContext, + ) -> AnyViewHandle { AnyViewHandle::new( - window_id, + window, view_id, self.as_any().type_id(), cx.ref_counts.clone(), @@ -2653,7 +2645,7 @@ where fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box { let mut view_context = ViewContext::mutable(cx, view_id); let element = V::render(self, &mut view_context); - let view = WeakViewHandle::new(cx.window_id, view_id); + let view = WeakViewHandle::new(cx.window_handle, view_id); Box::new(RootElement::new(element, view)) } @@ -2664,11 +2656,11 @@ where } else { let focused_type = cx .views_metadata - .get(&(cx.window_id, focused_id)) + .get(&(cx.window_handle.id(), focused_id)) .unwrap() .type_id; AnyViewHandle::new( - cx.window_id, + cx.window_handle, focused_id, focused_type, cx.ref_counts.clone(), @@ -2684,11 +2676,11 @@ where } else { let blurred_type = cx .views_metadata - .get(&(cx.window_id, blurred_id)) + .get(&(cx.window_handle.id(), blurred_id)) .unwrap() .type_id; AnyViewHandle::new( - cx.window_id, + cx.window_handle, blurred_id, blurred_type, cx.ref_counts.clone(), @@ -2995,18 +2987,22 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { pub fn handle(&self) -> ViewHandle { ViewHandle::new( - self.window_id, + self.window_handle, self.view_id, &self.window_context.ref_counts, ) } pub fn weak_handle(&self) -> WeakViewHandle { - WeakViewHandle::new(self.window_id, self.view_id) + WeakViewHandle::new(self.window_handle, self.view_id) } pub fn window_id(&self) -> usize { - self.window_id + self.window_handle.id() + } + + pub fn window(&self) -> AnyWindowHandle { + self.window_handle } pub fn view_id(&self) -> usize { @@ -3054,11 +3050,11 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { } pub fn focus_parent(&mut self) { - let window_id = self.window_id; + let window = self.window_handle; let view_id = self.view_id; self.pending_effects .push_back(Effect::Focus(FocusEffect::ViewParent { - window_id, + window, view_id, is_forced: false, })); @@ -3072,13 +3068,13 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { where F: 'static + FnMut(&mut V, &mut ViewContext) -> bool, { - let window_id = self.window_id; + let window = self.window_handle; let view = self.weak_handle(); self.pending_effects .push_back(Effect::WindowShouldCloseSubscription { - window_id, + window, callback: Box::new(move |cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(view) = view.upgrade(cx) { view.update(cx, |view, cx| callback(view, cx)) } else { @@ -3117,11 +3113,11 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { H: Handle, F: 'static + FnMut(&mut V, H, &mut ViewContext), { - let window_id = self.window_id; + let window = self.window_handle; let observer = self.weak_handle(); self.window_context .observe_internal(handle, move |observed, cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { callback(observer, observed, cx); @@ -3140,10 +3136,10 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { G: Any, F: 'static + FnMut(&mut V, &mut ViewContext), { - let window_id = self.window_id; + let window = self.window_handle; let observer = self.weak_handle(); self.window_context.observe_global::(move |cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| callback(observer, cx)); } @@ -3176,11 +3172,11 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { H: Handle, F: 'static + FnMut(&mut V, &E, &mut ViewContext), { - let window_id = self.window_id; + let window = self.window_handle; let observer = self.weak_handle(); self.window_context .observe_release(handle, move |released, cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { callback(observer, released, cx); @@ -3194,10 +3190,10 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { where F: 'static + FnMut(&mut V, TypeId, &mut ViewContext), { - let window_id = self.window_id; + let window = self.window_handle; let observer = self.weak_handle(); self.window_context.observe_actions(move |action_id, cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { callback(observer, action_id, cx); @@ -3289,10 +3285,10 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { where F: 'static + FnMut(&mut V, &mut ViewContext), { - let window_id = self.window_id; + let window = self.window_handle; let observer = self.weak_handle(); self.window_context.observe_active_labeled_tasks(move |cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { if let Some(observer) = observer.upgrade(cx) { observer.update(cx, |observer, cx| { callback(observer, cx); @@ -3316,9 +3312,9 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { } pub fn notify(&mut self) { - let window_id = self.window_id; + let window = self.window_handle; let view_id = self.view_id; - self.window_context.notify_view(window_id, view_id); + self.window_context.notify_view(window, view_id); } pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext)) { @@ -3331,10 +3327,10 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { &mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext), ) { - let window_id = self.window_id; + let window = self.window_handle; let handle = self.handle(); self.window_context.after_window_update(move |cx| { - cx.update_window(window_id, |cx| { + cx.update_window(window, |cx| { handle.update(cx, |view, cx| { callback(view, cx); }) @@ -3422,30 +3418,30 @@ impl BorrowAppContext for ViewContext<'_, '_, V> { impl BorrowWindowContext for ViewContext<'_, '_, V> { type Result = T; - fn read_window T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_window(&*self.window_context, window_id, f) + fn read_window T>(&self, window: AnyWindowHandle, f: F) -> T { + BorrowWindowContext::read_window(&*self.window_context, window, f) } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { - BorrowWindowContext::read_window_optional(&*self.window_context, window_id, f) + BorrowWindowContext::read_window_optional(&*self.window_context, window, f) } fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, f: F, ) -> T { - BorrowWindowContext::update_window(&mut *self.window_context, window_id, f) + BorrowWindowContext::update_window(&mut *self.window_context, window, f) } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - BorrowWindowContext::update_window_optional(&mut *self.window_context, window_id, f) + BorrowWindowContext::update_window_optional(&mut *self.window_context, window, f) } } @@ -3483,11 +3479,11 @@ impl<'a, 'b, 'c, V: View> LayoutContext<'a, 'b, 'c, V> { ) -> Option> { self.notify_if_view_ancestors_change(view_id); - let window_id = self.window_id; + let window = self.window_handle; let mut contexts = Vec::new(); let mut handler_depth = None; for (i, view_id) in self.ancestors(view_id).enumerate() { - if let Some(view_metadata) = self.views_metadata.get(&(window_id, view_id)) { + if let Some(view_metadata) = self.views_metadata.get(&(window.id(), view_id)) { if let Some(actions) = self.actions.get(&view_metadata.type_id) { if actions.contains_key(&action.id()) { handler_depth = Some(i); @@ -3547,30 +3543,30 @@ impl BorrowAppContext for LayoutContext<'_, '_, '_, V> { impl BorrowWindowContext for LayoutContext<'_, '_, '_, V> { type Result = T; - fn read_window T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_window(&*self.view_context, window_id, f) + fn read_window T>(&self, window: AnyWindowHandle, f: F) -> T { + BorrowWindowContext::read_window(&*self.view_context, window, f) } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { - BorrowWindowContext::read_window_optional(&*self.view_context, window_id, f) + BorrowWindowContext::read_window_optional(&*self.view_context, window, f) } fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, f: F, ) -> T { - BorrowWindowContext::update_window(&mut *self.view_context, window_id, f) + BorrowWindowContext::update_window(&mut *self.view_context, window, f) } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - BorrowWindowContext::update_window_optional(&mut *self.view_context, window_id, f) + BorrowWindowContext::update_window_optional(&mut *self.view_context, window, f) } } @@ -3619,30 +3615,30 @@ impl BorrowAppContext for EventContext<'_, '_, '_, V> { impl BorrowWindowContext for EventContext<'_, '_, '_, V> { type Result = T; - fn read_window T>(&self, window_id: usize, f: F) -> T { - BorrowWindowContext::read_window(&*self.view_context, window_id, f) + fn read_window T>(&self, window: AnyWindowHandle, f: F) -> T { + BorrowWindowContext::read_window(&*self.view_context, window, f) } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { - BorrowWindowContext::read_window_optional(&*self.view_context, window_id, f) + BorrowWindowContext::read_window_optional(&*self.view_context, window, f) } fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, f: F, ) -> T { - BorrowWindowContext::update_window(&mut *self.view_context, window_id, f) + BorrowWindowContext::update_window(&mut *self.view_context, window, f) } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - BorrowWindowContext::update_window_optional(&mut *self.view_context, window_id, f) + BorrowWindowContext::update_window_optional(&mut *self.view_context, window, f) } } @@ -3977,7 +3973,7 @@ impl WindowHandle { C: BorrowWindowContext, F: FnOnce(&mut V, &mut ViewContext) -> R, { - cx.update_window(self.id(), |cx| { + cx.update_window(self.any_handle, |cx| { cx.root_view() .clone() .downcast::() @@ -3991,7 +3987,7 @@ impl WindowHandle { C: BorrowWindowContext, F: FnOnce(&mut ViewContext) -> V, { - cx.update_window(self.id(), |cx| { + cx.update_window(self.any_handle, |cx| { let root_view = self.add_view(cx, |cx| build_root(cx)); cx.window.root_view = Some(root_view.clone().into_any()); cx.window.focused_view_id = Some(root_view.id()); @@ -4006,7 +4002,7 @@ impl Into for WindowHandle { } } -#[derive(Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct AnyWindowHandle { window_id: usize, root_view_type: TypeId, @@ -4029,7 +4025,7 @@ impl AnyWindowHandle { C: BorrowWindowContext, F: FnOnce(&WindowContext) -> R, { - cx.read_window(self.window_id, |cx| read(cx)) + cx.read_window(*self, |cx| read(cx)) } pub fn read_optional_with(&self, cx: &C, read: F) -> Option @@ -4037,7 +4033,7 @@ impl AnyWindowHandle { C: BorrowWindowContext, F: FnOnce(&WindowContext) -> Option, { - cx.read_window_optional(self.window_id, |cx| read(cx)) + cx.read_window_optional(*self, |cx| read(cx)) } pub fn update(&self, cx: &mut C, update: F) -> C::Result @@ -4045,7 +4041,7 @@ impl AnyWindowHandle { C: BorrowWindowContext, F: FnOnce(&mut WindowContext) -> R, { - cx.update_window(self.window_id, update) + cx.update_window(*self, update) } pub fn update_optional(&self, cx: &mut C, update: F) -> Option @@ -4053,7 +4049,7 @@ impl AnyWindowHandle { C: BorrowWindowContext, F: FnOnce(&mut WindowContext) -> Option, { - cx.update_window_optional(self.window_id, update) + cx.update_window_optional(*self, update) } pub fn add_view(&self, cx: &mut C, build_view: F) -> C::Result> @@ -4092,24 +4088,22 @@ impl AnyWindowHandle { pub fn simulate_activation(&self, cx: &mut TestAppContext) { self.update(cx, |cx| { let other_window_ids = cx - .windows - .keys() - .filter(|window_id| **window_id != self.window_id) - .copied() + .windows() + .filter(|window| *window != *self) .collect::>(); - for window_id in other_window_ids { - cx.window_changed_active_status(window_id, false) + for window in other_window_ids { + cx.window_changed_active_status(window, false) } - cx.window_changed_active_status(self.window_id, true) + cx.window_changed_active_status(*self, true) }); } #[cfg(any(test, feature = "test-support"))] pub fn simulate_deactivation(&self, cx: &mut TestAppContext) { self.update(cx, |cx| { - cx.window_changed_active_status(self.window_id, false); + cx.window_changed_active_status(*self, false); }) } } @@ -4129,20 +4123,15 @@ impl Deref for ViewHandle { } impl ViewHandle { - fn new(window_id: usize, view_id: usize, ref_counts: &Arc>) -> Self { + fn new(window: AnyWindowHandle, view_id: usize, ref_counts: &Arc>) -> Self { Self { - any_handle: AnyViewHandle::new( - window_id, - view_id, - TypeId::of::(), - ref_counts.clone(), - ), + any_handle: AnyViewHandle::new(window, view_id, TypeId::of::(), ref_counts.clone()), view_type: PhantomData, } } pub fn downgrade(&self) -> WeakViewHandle { - WeakViewHandle::new(self.window_id, self.view_id) + WeakViewHandle::new(self.window, self.view_id) } pub fn into_any(self) -> AnyViewHandle { @@ -4150,13 +4139,11 @@ impl ViewHandle { } pub fn window_id(&self) -> usize { - self.window_id + self.window.id() } - pub fn window(&self, cx: &C) -> C::Result { - cx.read_window(self.window_id, |cx| { - AnyWindowHandle::new(self.window_id, cx.window.root_view.type_id()) - }) + pub fn window(&self) -> AnyWindowHandle { + self.window } pub fn id(&self) -> usize { @@ -4172,7 +4159,7 @@ impl ViewHandle { C: BorrowWindowContext, F: FnOnce(&T, &ViewContext) -> S, { - cx.read_window(self.window_id, |cx| { + cx.read_window(self.window, |cx| { let cx = ViewContext::immutable(cx, self.view_id); read(cx.read_view(self), &cx) }) @@ -4185,7 +4172,7 @@ impl ViewHandle { { let mut update = Some(update); - cx.update_window(self.window_id, |cx| { + cx.update_window(self.window, |cx| { cx.update_view(self, &mut |view, cx| { let update = update.take().unwrap(); update(view, cx) @@ -4200,31 +4187,31 @@ impl ViewHandle { impl Clone for ViewHandle { fn clone(&self) -> Self { - ViewHandle::new(self.window_id, self.view_id, &self.ref_counts) + ViewHandle::new(self.window, self.view_id, &self.ref_counts) } } impl PartialEq for ViewHandle { fn eq(&self, other: &Self) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } impl PartialEq for ViewHandle { fn eq(&self, other: &AnyViewHandle) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } impl PartialEq> for ViewHandle { fn eq(&self, other: &WeakViewHandle) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } impl PartialEq> for WeakViewHandle { fn eq(&self, other: &ViewHandle) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } @@ -4232,7 +4219,7 @@ impl Eq for ViewHandle {} impl Hash for ViewHandle { fn hash(&self, state: &mut H) { - self.window_id.hash(state); + self.window.hash(state); self.view_id.hash(state); } } @@ -4240,7 +4227,7 @@ impl Hash for ViewHandle { impl Debug for ViewHandle { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct(&format!("ViewHandle<{}>", type_name::())) - .field("window_id", &self.window_id) + .field("window_id", &self.window) .field("view_id", &self.view_id) .finish() } @@ -4254,7 +4241,7 @@ impl Handle for ViewHandle { } fn location(&self) -> EntityLocation { - EntityLocation::View(self.window_id, self.view_id) + EntityLocation::View(self.window.id(), self.view_id) } fn downgrade(&self) -> Self::Weak { @@ -4270,7 +4257,7 @@ impl Handle for ViewHandle { } pub struct AnyViewHandle { - window_id: usize, + window: AnyWindowHandle, view_id: usize, view_type: TypeId, ref_counts: Arc>, @@ -4281,12 +4268,12 @@ pub struct AnyViewHandle { impl AnyViewHandle { fn new( - window_id: usize, + window: AnyWindowHandle, view_id: usize, view_type: TypeId, ref_counts: Arc>, ) -> Self { - ref_counts.lock().inc_view(window_id, view_id); + ref_counts.lock().inc_view(window.id(), view_id); #[cfg(any(test, feature = "test-support"))] let handle_id = ref_counts @@ -4296,7 +4283,7 @@ impl AnyViewHandle { .handle_created(None, view_id); Self { - window_id, + window, view_id, view_type, ref_counts, @@ -4305,8 +4292,12 @@ impl AnyViewHandle { } } + pub fn window(&self) -> AnyWindowHandle { + self.window + } + pub fn window_id(&self) -> usize { - self.window_id + self.window.id() } pub fn id(&self) -> usize { @@ -4338,7 +4329,7 @@ impl AnyViewHandle { pub fn downgrade(&self) -> AnyWeakViewHandle { AnyWeakViewHandle { - window_id: self.window_id, + window: self.window, view_id: self.view_id, view_type: self.view_type, } @@ -4350,7 +4341,7 @@ impl AnyViewHandle { pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a>) -> serde_json::Value { cx.views - .get(&(self.window_id, self.view_id)) + .get(&(self.window.id(), self.view_id)) .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx)) } } @@ -4358,7 +4349,7 @@ impl AnyViewHandle { impl Clone for AnyViewHandle { fn clone(&self) -> Self { Self::new( - self.window_id, + self.window, self.view_id, self.view_type, self.ref_counts.clone(), @@ -4368,13 +4359,13 @@ impl Clone for AnyViewHandle { impl PartialEq for AnyViewHandle { fn eq(&self, other: &Self) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } impl PartialEq> for AnyViewHandle { fn eq(&self, other: &ViewHandle) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } @@ -4382,7 +4373,7 @@ impl Drop for AnyViewHandle { fn drop(&mut self) { self.ref_counts .lock() - .dec_view(self.window_id, self.view_id); + .dec_view(self.window.id(), self.view_id); #[cfg(any(test, feature = "test-support"))] self.ref_counts .lock() @@ -4395,7 +4386,7 @@ impl Drop for AnyViewHandle { impl Debug for AnyViewHandle { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("AnyViewHandle") - .field("window_id", &self.window_id) + .field("window_id", &self.window.id()) .field("view_id", &self.view_id) .finish() } @@ -4531,10 +4522,10 @@ impl WeakHandle for WeakViewHandle { } impl WeakViewHandle { - fn new(window_id: usize, view_id: usize) -> Self { + fn new(window: AnyWindowHandle, view_id: usize) -> Self { Self { any_handle: AnyWeakViewHandle { - window_id, + window, view_id, view_type: TypeId::of::(), }, @@ -4546,8 +4537,12 @@ impl WeakViewHandle { self.view_id } + pub fn window(&self) -> AnyWindowHandle { + self.window + } + pub fn window_id(&self) -> usize { - self.window_id + self.window.id() } pub fn into_any(self) -> AnyWeakViewHandle { @@ -4567,7 +4562,7 @@ impl WeakViewHandle { let handle = cx .upgrade_view_handle(self) .ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?; - cx.read_window(self.window_id, |cx| handle.read_with(cx, read)) + cx.read_window(self.window, |cx| handle.read_with(cx, read)) .ok_or_else(|| anyhow!("window was removed")) }) } @@ -4581,7 +4576,7 @@ impl WeakViewHandle { let handle = cx .upgrade_view_handle(self) .ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?; - cx.update_window(self.window_id, |cx| handle.update(cx, update)) + cx.update_window(self.window, |cx| handle.update(cx, update)) .ok_or_else(|| anyhow!("window was removed")) }) } @@ -4606,7 +4601,7 @@ impl Clone for WeakViewHandle { impl PartialEq for WeakViewHandle { fn eq(&self, other: &Self) -> bool { - self.window_id == other.window_id && self.view_id == other.view_id + self.window == other.window && self.view_id == other.view_id } } @@ -4620,7 +4615,7 @@ impl Hash for WeakViewHandle { #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub struct AnyWeakViewHandle { - window_id: usize, + window: AnyWindowHandle, view_id: usize, view_type: TypeId, } @@ -4652,7 +4647,7 @@ impl AnyWeakViewHandle { impl Hash for AnyWeakViewHandle { fn hash(&self, state: &mut H) { - self.window_id.hash(state); + self.window.hash(state); self.view_id.hash(state); self.view_type.hash(state); } @@ -6393,7 +6388,7 @@ mod tests { // Check that global actions do not have a binding, even if a binding does exist in another view assert_eq!( - &available_actions(window.id(), view_1.id(), cx), + &available_actions(window.into(), view_1.id(), cx), &[ ("test::Action1", vec![Keystroke::parse("a").unwrap()]), ("test::GlobalAction", vec![]) @@ -6402,7 +6397,7 @@ mod tests { // Check that view 1 actions and bindings are available even when called from view 2 assert_eq!( - &available_actions(window.id(), view_2.id(), cx), + &available_actions(window.into(), view_2.id(), cx), &[ ("test::Action1", vec![Keystroke::parse("a").unwrap()]), ("test::Action2", vec![Keystroke::parse("b").unwrap()]), @@ -6412,11 +6407,11 @@ mod tests { // Produces a list of actions and key bindings fn available_actions( - window_id: usize, + window: AnyWindowHandle, view_id: usize, cx: &TestAppContext, ) -> Vec<(&'static str, Vec)> { - cx.available_actions(window_id, view_id) + cx.available_actions(window.into(), view_id) .into_iter() .map(|(action_name, _, bindings)| { ( @@ -6465,7 +6460,7 @@ mod tests { ]); }); - let actions = cx.available_actions(window.id(), view.id()); + let actions = cx.available_actions(window.into(), view.id()); assert_eq!( actions[0].1.as_any().downcast_ref::(), Some(&ActionWithArg { arg: false }) diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index ff988607b094f8d3253b8baaad2e6332bee4ad84..b1729d89b8591176f1fa9aa27ccc93cebdc65e8d 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -72,8 +72,8 @@ impl TestAppContext { cx } - pub fn dispatch_action(&mut self, window_id: usize, action: A) { - self.update_window(window_id, |window| { + pub fn dispatch_action(&mut self, window: AnyWindowHandle, action: A) { + self.update_window(window, |window| { window.dispatch_action(window.focused_view_id(), &action); }) .expect("window not found"); @@ -81,10 +81,10 @@ impl TestAppContext { pub fn available_actions( &self, - window_id: usize, + window: AnyWindowHandle, view_id: usize, ) -> Vec<(&'static str, Box, SmallVec<[Binding; 1]>)> { - self.read_window(window_id, |cx| cx.available_actions(view_id)) + self.read_window(window, |cx| cx.available_actions(view_id)) .unwrap_or_default() } @@ -127,18 +127,18 @@ impl TestAppContext { pub fn read_window T>( &self, - window_id: usize, + window: AnyWindowHandle, callback: F, ) -> Option { - self.cx.borrow().read_window(window_id, callback) + self.cx.borrow().read_window(window, callback) } pub fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, callback: F, ) -> Option { - self.cx.borrow_mut().update_window(window_id, callback) + self.cx.borrow_mut().update_window(window, callback) } pub fn add_model(&mut self, build_model: F) -> ModelHandle @@ -317,36 +317,36 @@ impl BorrowAppContext for TestAppContext { impl BorrowWindowContext for TestAppContext { type Result = T; - fn read_window T>(&self, window_id: usize, f: F) -> T { + fn read_window T>(&self, window: AnyWindowHandle, f: F) -> T { self.cx .borrow() - .read_window(window_id, f) + .read_window(window, f) .expect("window was closed") } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { - BorrowWindowContext::read_window(self, window_id, f) + BorrowWindowContext::read_window(self, window, f) } fn update_window T>( &mut self, - window_id: usize, + window: AnyWindowHandle, f: F, ) -> T { self.cx .borrow_mut() - .update_window(window_id, f) + .update_window(window, f) .expect("window was closed") } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - BorrowWindowContext::update_window(self, window_id, f) + BorrowWindowContext::update_window(self, window, f) } } diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 70d02c1fa1265b5449b127a6736c8a81573be1e1..44a3c5cfdc8ded2e004df2da56ee6ce510396871 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -13,9 +13,9 @@ use crate::{ }, text_layout::TextLayoutCache, util::post_inc, - Action, AnyView, AnyViewHandle, AppContext, BorrowAppContext, BorrowWindowContext, Effect, - Element, Entity, Handle, LayoutContext, MouseRegion, MouseRegionId, SceneBuilder, Subscription, - View, ViewContext, ViewHandle, WindowHandle, WindowInvalidation, + Action, AnyView, AnyViewHandle, AnyWindowHandle, AppContext, BorrowAppContext, + BorrowWindowContext, Effect, Element, Entity, Handle, LayoutContext, MouseRegion, + MouseRegionId, SceneBuilder, Subscription, View, ViewContext, ViewHandle, WindowInvalidation, }; use anyhow::{anyhow, bail, Result}; use collections::{HashMap, HashSet}; @@ -60,7 +60,7 @@ pub struct Window { impl Window { pub fn new( - window_id: usize, + handle: AnyWindowHandle, platform_window: Box, cx: &mut AppContext, build_view: F, @@ -92,7 +92,7 @@ impl Window { appearance, }; - let mut window_context = WindowContext::mutable(cx, &mut window, window_id); + let mut window_context = WindowContext::mutable(cx, &mut window, handle); let root_view = window_context.add_view(|cx| build_view(cx)); if let Some(invalidation) = window_context.window.invalidation.take() { window_context.invalidate(invalidation, appearance); @@ -113,7 +113,7 @@ impl Window { pub struct WindowContext<'a> { pub(crate) app_context: Reference<'a, AppContext>, pub(crate) window: Reference<'a, Window>, - pub(crate) window_id: usize, + pub(crate) window_handle: AnyWindowHandle, pub(crate) removed: bool, } @@ -144,15 +144,15 @@ impl BorrowAppContext for WindowContext<'_> { impl BorrowWindowContext for WindowContext<'_> { type Result = T; - fn read_window T>(&self, window_id: usize, f: F) -> T { - if self.window_id == window_id { + fn read_window T>(&self, handle: AnyWindowHandle, f: F) -> T { + if self.window_handle == handle { f(self) } else { panic!("read_with called with id of window that does not belong to this context") } } - fn read_window_optional(&self, window_id: usize, f: F) -> Option + fn read_window_optional(&self, window_id: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { @@ -161,21 +161,21 @@ impl BorrowWindowContext for WindowContext<'_> { fn update_window T>( &mut self, - window_id: usize, + handle: AnyWindowHandle, f: F, ) -> T { - if self.window_id == window_id { + if self.window_handle == handle { f(self) } else { panic!("update called with id of window that does not belong to this context") } } - fn update_window_optional(&mut self, window_id: usize, f: F) -> Option + fn update_window_optional(&mut self, handle: AnyWindowHandle, f: F) -> Option where F: FnOnce(&mut WindowContext) -> Option, { - BorrowWindowContext::update_window(self, window_id, f) + BorrowWindowContext::update_window(self, handle, f) } } @@ -183,21 +183,25 @@ impl<'a> WindowContext<'a> { pub fn mutable( app_context: &'a mut AppContext, window: &'a mut Window, - window_id: usize, + handle: AnyWindowHandle, ) -> Self { Self { app_context: Reference::Mutable(app_context), window: Reference::Mutable(window), - window_id, + window_handle: handle, removed: false, } } - pub fn immutable(app_context: &'a AppContext, window: &'a Window, window_id: usize) -> Self { + pub fn immutable( + app_context: &'a AppContext, + window: &'a Window, + handle: AnyWindowHandle, + ) -> Self { Self { app_context: Reference::Immutable(app_context), window: Reference::Immutable(window), - window_id, + window_handle: handle, removed: false, } } @@ -207,17 +211,11 @@ impl<'a> WindowContext<'a> { } pub fn window_id(&self) -> usize { - self.window_id + self.window_handle.id() } - pub fn window(&self) -> Option> { - self.window.root_view.as_ref().and_then(|root_view| { - if root_view.is::() { - Some(WindowHandle::new(self.window_id)) - } else { - None - } - }) + pub fn window(&self) -> AnyWindowHandle { + self.window_handle } pub fn app_context(&mut self) -> &mut AppContext { @@ -240,10 +238,10 @@ impl<'a> WindowContext<'a> { where F: FnOnce(&mut dyn AnyView, &mut Self) -> T, { - let window_id = self.window_id; - let mut view = self.views.remove(&(window_id, view_id))?; + let handle = self.window_handle; + let mut view = self.views.remove(&(handle.id(), view_id))?; let result = f(view.as_mut(), self); - self.views.insert((window_id, view_id), view); + self.views.insert((handle.id(), view_id), view); Some(result) } @@ -268,9 +266,9 @@ impl<'a> WindowContext<'a> { } pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut WindowContext)) { - let window_id = self.window_id; + let handle = self.window_handle; self.app_context.defer(move |cx| { - cx.update_window(window_id, |cx| callback(cx)); + cx.update_window(handle, |cx| callback(cx)); }) } @@ -310,10 +308,10 @@ impl<'a> WindowContext<'a> { H: Handle, F: 'static + FnMut(H, &E::Event, &mut WindowContext) -> bool, { - let window_id = self.window_id; + let window_handle = self.window_handle; self.app_context .subscribe_internal(handle, move |emitter, event, cx| { - cx.update_window(window_id, |cx| callback(emitter, event, cx)) + cx.update_window(window_handle, |cx| callback(emitter, event, cx)) .unwrap_or(false) }) } @@ -322,17 +320,17 @@ impl<'a> WindowContext<'a> { where F: 'static + FnMut(bool, &mut WindowContext) -> bool, { - let window_id = self.window_id; + let handle = self.window_handle; let subscription_id = post_inc(&mut self.next_subscription_id); self.pending_effects .push_back(Effect::WindowActivationObservation { - window_id, + window: handle, subscription_id, callback: Box::new(callback), }); Subscription::WindowActivationObservation( self.window_activation_observations - .subscribe(window_id, subscription_id), + .subscribe(handle.id(), subscription_id), ) } @@ -340,17 +338,17 @@ impl<'a> WindowContext<'a> { where F: 'static + FnMut(bool, &mut WindowContext) -> bool, { - let window_id = self.window_id; + let window = self.window_handle; let subscription_id = post_inc(&mut self.next_subscription_id); self.pending_effects .push_back(Effect::WindowFullscreenObservation { - window_id, + window, subscription_id, callback: Box::new(callback), }); Subscription::WindowActivationObservation( self.window_activation_observations - .subscribe(window_id, subscription_id), + .subscribe(window.id(), subscription_id), ) } @@ -358,17 +356,17 @@ impl<'a> WindowContext<'a> { where F: 'static + FnMut(WindowBounds, Uuid, &mut WindowContext) -> bool, { - let window_id = self.window_id; + let window = self.window_handle; let subscription_id = post_inc(&mut self.next_subscription_id); self.pending_effects .push_back(Effect::WindowBoundsObservation { - window_id, + window, subscription_id, callback: Box::new(callback), }); Subscription::WindowBoundsObservation( self.window_bounds_observations - .subscribe(window_id, subscription_id), + .subscribe(window.id(), subscription_id), ) } @@ -377,13 +375,13 @@ impl<'a> WindowContext<'a> { F: 'static + FnMut(&Keystroke, &MatchResult, Option<&Box>, &mut WindowContext) -> bool, { - let window_id = self.window_id; + let window = self.window_handle; let subscription_id = post_inc(&mut self.next_subscription_id); self.keystroke_observations - .add_callback(window_id, subscription_id, Box::new(callback)); + .add_callback(window.id(), subscription_id, Box::new(callback)); Subscription::KeystrokeObservation( self.keystroke_observations - .subscribe(window_id, subscription_id), + .subscribe(window.id(), subscription_id), ) } @@ -391,11 +389,11 @@ impl<'a> WindowContext<'a> { &self, view_id: usize, ) -> Vec<(&'static str, Box, SmallVec<[Binding; 1]>)> { - let window_id = self.window_id; + let handle = self.window_handle; let mut contexts = Vec::new(); let mut handler_depths_by_action_id = HashMap::::default(); for (depth, view_id) in self.ancestors(view_id).enumerate() { - if let Some(view_metadata) = self.views_metadata.get(&(window_id, view_id)) { + if let Some(view_metadata) = self.views_metadata.get(&(handle.id(), view_id)) { contexts.push(view_metadata.keymap_context.clone()); if let Some(actions) = self.actions.get(&view_metadata.type_id) { handler_depths_by_action_id @@ -440,13 +438,13 @@ impl<'a> WindowContext<'a> { } pub(crate) fn dispatch_keystroke(&mut self, keystroke: &Keystroke) -> bool { - let window_id = self.window_id; + let handle = self.window_handle; if let Some(focused_view_id) = self.focused_view_id() { let dispatch_path = self .ancestors(focused_view_id) .filter_map(|view_id| { self.views_metadata - .get(&(window_id, view_id)) + .get(&(handle.id(), view_id)) .map(|view| (view_id, view.keymap_context.clone())) }) .collect(); @@ -471,15 +469,10 @@ impl<'a> WindowContext<'a> { } }; - self.keystroke( - window_id, - keystroke.clone(), - handled_by, - match_result.clone(), - ); + self.keystroke(handle, keystroke.clone(), handled_by, match_result.clone()); keystroke_handled } else { - self.keystroke(window_id, keystroke.clone(), None, MatchResult::None); + self.keystroke(handle, keystroke.clone(), None, MatchResult::None); false } } @@ -487,7 +480,7 @@ impl<'a> WindowContext<'a> { pub(crate) fn dispatch_event(&mut self, event: Event, event_reused: bool) -> bool { let mut mouse_events = SmallVec::<[_; 2]>::new(); let mut notified_views: HashSet = Default::default(); - let window_id = self.window_id; + let handle = self.window_handle; // 1. Handle platform event. Keyboard events get dispatched immediately, while mouse events // get mapped into the mouse-specific MouseEvent type. @@ -851,19 +844,19 @@ impl<'a> WindowContext<'a> { } for view_id in notified_views { - self.notify_view(window_id, view_id); + self.notify_view(handle, view_id); } any_event_handled } pub(crate) fn dispatch_key_down(&mut self, event: &KeyDownEvent) -> bool { - let window_id = self.window_id; + let handle = self.window_handle; if let Some(focused_view_id) = self.window.focused_view_id { for view_id in self.ancestors(focused_view_id).collect::>() { - if let Some(mut view) = self.views.remove(&(window_id, view_id)) { + if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { let handled = view.key_down(event, self, view_id); - self.views.insert((window_id, view_id), view); + self.views.insert((handle.id(), view_id), view); if handled { return true; } @@ -877,12 +870,12 @@ impl<'a> WindowContext<'a> { } pub(crate) fn dispatch_key_up(&mut self, event: &KeyUpEvent) -> bool { - let window_id = self.window_id; + let handle = self.window_handle; if let Some(focused_view_id) = self.window.focused_view_id { for view_id in self.ancestors(focused_view_id).collect::>() { - if let Some(mut view) = self.views.remove(&(window_id, view_id)) { + if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { let handled = view.key_up(event, self, view_id); - self.views.insert((window_id, view_id), view); + self.views.insert((handle.id(), view_id), view); if handled { return true; } @@ -896,12 +889,12 @@ impl<'a> WindowContext<'a> { } pub(crate) fn dispatch_modifiers_changed(&mut self, event: &ModifiersChangedEvent) -> bool { - let window_id = self.window_id; + let handle = self.window_handle; if let Some(focused_view_id) = self.window.focused_view_id { for view_id in self.ancestors(focused_view_id).collect::>() { - if let Some(mut view) = self.views.remove(&(window_id, view_id)) { + if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { let handled = view.modifiers_changed(event, self, view_id); - self.views.insert((window_id, view_id), view); + self.views.insert((handle.id(), view_id), view); if handled { return true; } @@ -936,14 +929,14 @@ impl<'a> WindowContext<'a> { } pub fn render_view(&mut self, params: RenderParams) -> Result> { - let window_id = self.window_id; + let handle = self.window_handle; let view_id = params.view_id; let mut view = self .views - .remove(&(window_id, view_id)) + .remove(&(handle.id(), view_id)) .ok_or_else(|| anyhow!("view not found"))?; let element = view.render(self, view_id); - self.views.insert((window_id, view_id), view); + self.views.insert((handle.id(), view_id), view); Ok(element) } @@ -971,9 +964,9 @@ impl<'a> WindowContext<'a> { } else if old_parent_id == new_parent_id { current_view_id = *old_parent_id.unwrap(); } else { - let window_id = self.window_id; + let handle = self.window_handle; for view_id_to_notify in view_ids_to_notify { - self.notify_view(window_id, view_id_to_notify); + self.notify_view(handle, view_id_to_notify); } break; } @@ -1141,7 +1134,7 @@ impl<'a> WindowContext<'a> { } pub fn focus(&mut self, view_id: Option) { - self.app_context.focus(self.window_id, view_id); + self.app_context.focus(self.window_handle, view_id); } pub fn window_bounds(&self) -> WindowBounds { @@ -1194,26 +1187,26 @@ impl<'a> WindowContext<'a> { T: View, F: FnOnce(&mut ViewContext) -> Option, { - let window_id = self.window_id; + let handle = self.window_handle; let view_id = post_inc(&mut self.next_id); let mut cx = ViewContext::mutable(self, view_id); let handle = if let Some(view) = build_view(&mut cx) { let mut keymap_context = KeymapContext::default(); view.update_keymap_context(&mut keymap_context, cx.app_context()); self.views_metadata.insert( - (window_id, view_id), + (handle.id(), view_id), ViewMetadata { type_id: TypeId::of::(), keymap_context, }, ); - self.views.insert((window_id, view_id), Box::new(view)); + self.views.insert((handle.id(), view_id), Box::new(view)); self.window .invalidation .get_or_insert_with(Default::default) .updated .insert(view_id); - Some(ViewHandle::new(window_id, view_id, &self.ref_counts)) + Some(ViewHandle::new(handle, view_id, &self.ref_counts)) } else { None }; @@ -1390,7 +1383,7 @@ pub struct ChildView { impl ChildView { pub fn new(view: &AnyViewHandle, cx: &AppContext) -> Self { - let view_name = cx.view_ui_name(view.window_id(), view.id()).unwrap(); + let view_name = cx.view_ui_name(view.window, view.id()).unwrap(); Self { view_id: view.id(), view_name, diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 07aaea812a98d5758bb15b801c5cd8bdf1688e8f..df4334a19fc7daf862504c6ef7ccfc6f3f9e3da0 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1726,7 +1726,7 @@ impl ClipboardEntry { #[cfg(test)] mod tests { use super::*; - use gpui::{AnyWindowHandle, TestAppContext, ViewHandle}; + use gpui::{AnyWindowHandle, TestAppContext, ViewHandle, WindowHandle}; use pretty_assertions::assert_eq; use project::FakeFs; use serde_json::json; @@ -1872,7 +1872,6 @@ mod tests { let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "root1", cx); @@ -1894,7 +1893,7 @@ mod tests { // Add a file with the root folder selected. The filename editor is placed // before the first file in the root folder. panel.update(cx, |panel, cx| panel.new_file(&NewFile, cx)); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { let panel = panel.read(cx); assert!(panel.filename_editor.is_focused(cx)); }); @@ -2225,7 +2224,6 @@ mod tests { let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "root1", cx); @@ -2247,7 +2245,7 @@ mod tests { // Add a file with the root folder selected. The filename editor is placed // before the first file in the root folder. panel.update(cx, |panel, cx| panel.new_file(&NewFile, cx)); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { let panel = panel.read(cx); assert!(panel.filename_editor.is_focused(cx)); }); @@ -2402,7 +2400,6 @@ mod tests { let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); toggle_expand_dir(&panel, "src/test", cx); @@ -2419,7 +2416,7 @@ mod tests { " third.rs" ] ); - ensure_single_file_is_opened(window_id, &workspace, "test/first.rs", cx); + ensure_single_file_is_opened(window, "test/first.rs", cx); submit_deletion(window.into(), &panel, cx); assert_eq!( @@ -2446,9 +2443,9 @@ mod tests { " third.rs" ] ); - ensure_single_file_is_opened(window_id, &workspace, "test/second.rs", cx); + ensure_single_file_is_opened(window, "test/second.rs", cx); - cx.update_window(window_id, |cx| { + window.update(cx, |cx| { let active_items = workspace .read(cx) .panes() @@ -2493,7 +2490,6 @@ mod tests { let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let workspace = window.root(cx); - let window_id = window.id(); let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)); select_path(&panel, "src/", cx); @@ -2504,7 +2500,7 @@ mod tests { &["v src <== selected", " > test"] ); panel.update(cx, |panel, cx| panel.new_directory(&NewDirectory, cx)); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { let panel = panel.read(cx); assert!(panel.filename_editor.is_focused(cx)); }); @@ -2535,7 +2531,7 @@ mod tests { &["v src", " > test <== selected"] ); panel.update(cx, |panel, cx| panel.new_file(&NewFile, cx)); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { let panel = panel.read(cx); assert!(panel.filename_editor.is_focused(cx)); }); @@ -2585,7 +2581,7 @@ mod tests { ], ); panel.update(cx, |panel, cx| panel.rename(&Rename, cx)); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { let panel = panel.read(cx); assert!(panel.filename_editor.is_focused(cx)); }); @@ -2882,13 +2878,11 @@ mod tests { } fn ensure_single_file_is_opened( - window_id: usize, - workspace: &ViewHandle, + window: WindowHandle, expected_path: &str, cx: &mut TestAppContext, ) { - cx.read_window(window_id, |cx| { - let workspace = workspace.read(cx); + window.update_root(cx, |workspace, cx| { let worktrees = workspace.worktrees(cx).collect::>(); assert_eq!(worktrees.len(), 1); let worktree_id = WorktreeId::from_usize(worktrees[0].id()); diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index b20ffed6d7e1ad94e9c311503c332e066e5c9b91..c3b4f5caa668c7a74ef446744cfc4aaa04ee6df7 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -1229,8 +1229,6 @@ mod tests { ); let buffer = cx.add_model(|cx| Buffer::new(0, buffer_text, cx)); let window = cx.add_window(|_| EmptyView); - let window_id = window.id(); - let editor = window.add_view(cx, |cx| Editor::for_buffer(buffer.clone(), None, cx)); let search_bar = window.add_view(cx, |cx| { @@ -1249,12 +1247,13 @@ mod tests { search_bar.activate_current_match(cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( !editor.is_focused(cx), "Initially, the editor should not be focused" ); }); + let initial_selections = editor.update(cx, |editor, cx| { let initial_selections = editor.selections.display_ranges(cx); assert_eq!( @@ -1271,7 +1270,7 @@ mod tests { cx.focus(search_bar.query_editor.as_any()); search_bar.select_all_matches(&SelectAllMatches, cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( editor.is_focused(cx), "Should focus editor after successful SelectAllMatches" @@ -1295,7 +1294,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_next_match(&SelectNextMatch, cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( editor.is_focused(cx), "Should still have editor focused after SelectNextMatch" @@ -1324,7 +1323,7 @@ mod tests { cx.focus(search_bar.query_editor.as_any()); search_bar.select_all_matches(&SelectAllMatches, cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( editor.is_focused(cx), "Should focus editor after successful SelectAllMatches" @@ -1348,7 +1347,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_prev_match(&SelectPrevMatch, cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( editor.is_focused(cx), "Should still have editor focused after SelectPrevMatch" @@ -1384,7 +1383,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.select_all_matches(&SelectAllMatches, cx); }); - cx.read_window(window_id, |cx| { + window.read_with(cx, |cx| { assert!( !editor.is_focused(cx), "Should not switch focus to editor if SelectAllMatches does not find any matches" diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index dffd88db14229871a805a282ccbc49670697206e..202d494560e7388b689a4b9f8750b07c62758697 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1568,7 +1568,6 @@ pub mod tests { let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); let active_item = cx.read(|cx| { workspace @@ -1599,9 +1598,9 @@ pub mod tests { }; let search_view_id = search_view.id(); - cx.spawn( - |mut cx| async move { cx.dispatch_action(window_id, search_view_id, &ToggleFocus) }, - ) + cx.spawn(|mut cx| async move { + cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + }) .detach(); deterministic.run_until_parked(); search_view.update(cx, |search_view, cx| { @@ -1651,9 +1650,9 @@ pub mod tests { "Search view should be focused after mismatching query had been used in search", ); }); - cx.spawn( - |mut cx| async move { cx.dispatch_action(window_id, search_view_id, &ToggleFocus) }, - ) + cx.spawn(|mut cx| async move { + cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + }) .detach(); deterministic.run_until_parked(); search_view.update(cx, |search_view, cx| { @@ -1683,9 +1682,9 @@ pub mod tests { "Search view with mismatching query should be focused after search results are available", ); }); - cx.spawn( - |mut cx| async move { cx.dispatch_action(window_id, search_view_id, &ToggleFocus) }, - ) + cx.spawn(|mut cx| async move { + cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + }) .detach(); deterministic.run_until_parked(); search_view.update(cx, |search_view, cx| { @@ -1713,9 +1712,9 @@ pub mod tests { ); }); - cx.spawn( - |mut cx| async move { cx.dispatch_action(window_id, search_view_id, &ToggleFocus) }, - ) + cx.spawn(|mut cx| async move { + cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + }) .detach(); deterministic.run_until_parked(); search_view.update(cx, |search_view, cx| { diff --git a/crates/vim/src/editor_events.rs b/crates/vim/src/editor_events.rs index 4fef6bd715eedbe49b1347b679a2ebe6d3a89f33..893f5e8a854aed40abc9ced5cb9219a57c8e1d53 100644 --- a/crates/vim/src/editor_events.rs +++ b/crates/vim/src/editor_events.rs @@ -1,6 +1,6 @@ use crate::Vim; use editor::{EditorBlurred, EditorFocused, EditorReleased}; -use gpui::{AppContext, BorrowWindowContext}; +use gpui::AppContext; pub fn init(cx: &mut AppContext) { cx.subscribe_global(focused).detach(); @@ -10,7 +10,7 @@ pub fn init(cx: &mut AppContext) { fn focused(EditorFocused(editor): &EditorFocused, cx: &mut AppContext) { if let Some(previously_active_editor) = Vim::read(cx).active_editor.clone() { - cx.update_window(previously_active_editor.window_id(), |cx| { + previously_active_editor.window().update(cx, |cx| { Vim::update(cx, |vim, cx| { vim.update_active_editor(cx, |previously_active_editor, cx| { vim.unhook_vim_settings(previously_active_editor, cx) @@ -19,7 +19,7 @@ fn focused(EditorFocused(editor): &EditorFocused, cx: &mut AppContext) { }); } - cx.update_window(editor.window_id(), |cx| { + editor.window().update(cx, |cx| { Vim::update(cx, |vim, cx| { vim.set_active_editor(editor.clone(), cx); }); @@ -27,7 +27,7 @@ fn focused(EditorFocused(editor): &EditorFocused, cx: &mut AppContext) { } fn blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut AppContext) { - cx.update_window(editor.window_id(), |cx| { + editor.window().update(cx, |cx| { Vim::update(cx, |vim, cx| { if let Some(previous_editor) = vim.active_editor.clone() { if previous_editor == editor.clone() { @@ -41,7 +41,7 @@ fn blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut AppContext) { } fn released(EditorReleased(editor): &EditorReleased, cx: &mut AppContext) { - cx.update_window(editor.window_id(), |cx| { + editor.window().update(cx, |cx| { cx.update_default_global(|vim: &mut Vim, _| { if let Some(previous_editor) = vim.active_editor.clone() { if previous_editor == editor.clone() { diff --git a/crates/vim/src/mode_indicator.rs b/crates/vim/src/mode_indicator.rs index afd60af848be052060988ba961bb75e811f33d3b..5d54a66723da31ab271c55510820a87a48e207cd 100644 --- a/crates/vim/src/mode_indicator.rs +++ b/crates/vim/src/mode_indicator.rs @@ -1,6 +1,6 @@ use gpui::{ elements::{Empty, Label}, - AnyElement, Element, Entity, Subscription, View, ViewContext, BorrowWindowContext + AnyElement, Element, Entity, Subscription, View, ViewContext, }; use settings::SettingsStore; use workspace::{item::ItemHandle, StatusItemView}; @@ -20,7 +20,7 @@ impl ModeIndicator { if let Some(mode_indicator) = handle.upgrade(cx) { match event { VimEvent::ModeChanged { mode } => { - cx.update_window(mode_indicator.window_id(), |cx| { + mode_indicator.window().update(cx, |cx| { mode_indicator.update(cx, move |mode_indicator, cx| { mode_indicator.set_mode(mode, cx); }) diff --git a/crates/vim/src/test/vim_test_context.rs b/crates/vim/src/test/vim_test_context.rs index 839ab3aafc87e535a8b09096be6b58a5837063da..5eaaef900e4719e0f17ff7aebd62cb0377cd1980 100644 --- a/crates/vim/src/test/vim_test_context.rs +++ b/crates/vim/src/test/vim_test_context.rs @@ -85,8 +85,8 @@ impl<'a> VimTestContext<'a> { } pub fn set_state(&mut self, text: &str, mode: Mode) -> ContextHandle { - let window_id = self.window.id(); - self.update_window(window_id, |cx| { + let window = self.window; + window.update(self.cx.cx.cx, |cx| { Vim::update(cx, |vim, cx| { vim.switch_mode(mode, false, cx); }) diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index ebaf399e22b3ecfa51b217327f5912a34dc7b542..5bb0fd93f8c9290c6f71f0ff94972115c9e3629c 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -203,7 +203,7 @@ impl Dock { pub fn panel_index_for_ui_name(&self, ui_name: &str, cx: &AppContext) -> Option { self.panel_entries.iter().position(|entry| { let panel = entry.panel.as_any(); - cx.view_ui_name(panel.window_id(), panel.id()) == Some(ui_name) + cx.view_ui_name(panel.window(), panel.id()) == Some(ui_name) }) } @@ -530,16 +530,12 @@ impl View for PanelButtons { tooltip_action.as_ref().map(|action| action.boxed_clone()); move |_, this, cx| { if let Some(tooltip_action) = &tooltip_action { - let window_id = cx.window_id(); + let window = cx.window(); let view_id = this.workspace.id(); let tooltip_action = tooltip_action.boxed_clone(); cx.spawn(|_, mut cx| async move { - cx.dispatch_action( - window_id, - view_id, - &*tooltip_action, - ) - .ok(); + cx.dispatch_action(window, view_id, &*tooltip_action) + .ok(); }) .detach(); } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 98883fac3372246d462585be76eb0bfd1a20bbae..ecbe25accad0ee5f1e52c785ddd80c588bb911df 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -1917,8 +1917,8 @@ impl Element for PaneBackdrop { MouseRegion::new::(child_view_id, 0, visible_bounds).on_down( gpui::platform::MouseButton::Left, move |_, _: &mut V, cx| { - let window_id = cx.window_id(); - cx.app_context().focus(window_id, Some(child_view_id)) + let window = cx.window(); + cx.app_context().focus(window, Some(child_view_id)) }, ), ); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index da708c6ea727de82b1c288a9549e6d627fad07b3..f0990322653757344d459e2bc2ef1f8c569cbdcf 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1250,11 +1250,11 @@ impl Workspace { _: &CloseWindow, cx: &mut ViewContext, ) -> Option>> { - let window_id = cx.window_id(); + let window = cx.window(); let prepare = self.prepare_to_close(false, cx); Some(cx.spawn(|_, mut cx| async move { if prepare.await? { - cx.remove_window(window_id); + cx.remove_window(window); } Ok(()) })) @@ -1266,7 +1266,7 @@ impl Workspace { cx: &mut ViewContext, ) -> Task> { let active_call = self.active_call().cloned(); - let window_id = cx.window_id(); + let window = cx.window(); cx.spawn(|this, mut cx| async move { let workspace_count = cx @@ -1281,7 +1281,7 @@ impl Workspace { && active_call.read_with(&cx, |call, _| call.room().is_some()) { let answer = cx.prompt( - window_id, + window, PromptLevel::Warning, "Do you want to leave the current call?", &["Close window and hang up", "Cancel"], @@ -1390,7 +1390,7 @@ impl Workspace { paths: Vec, cx: &mut ViewContext, ) -> Task> { - let window = cx.window::(); + let window = cx.window().downcast::(); let is_remote = self.project.read(cx).is_remote(); let has_worktree = self.project.read(cx).worktrees(cx).next().is_some(); let has_dirty_items = self.items(cx).any(|item| item.is_dirty(cx)); @@ -3181,7 +3181,7 @@ impl Workspace { let left_visible = left_dock.is_open(); let left_active_panel = left_dock.visible_panel().and_then(|panel| { Some( - cx.view_ui_name(panel.as_any().window_id(), panel.id())? + cx.view_ui_name(panel.as_any().window(), panel.id())? .to_string(), ) }); @@ -3194,7 +3194,7 @@ impl Workspace { let right_visible = right_dock.is_open(); let right_active_panel = right_dock.visible_panel().and_then(|panel| { Some( - cx.view_ui_name(panel.as_any().window_id(), panel.id())? + cx.view_ui_name(panel.as_any().window(), panel.id())? .to_string(), ) }); @@ -3207,7 +3207,7 @@ impl Workspace { let bottom_visible = bottom_dock.is_open(); let bottom_active_panel = bottom_dock.visible_panel().and_then(|panel| { Some( - cx.view_ui_name(panel.as_any().window_id(), panel.id())? + cx.view_ui_name(panel.as_any().window(), panel.id())? .to_string(), ) }); @@ -4000,7 +4000,7 @@ pub fn join_remote_project( workspace.downgrade() }; - cx.activate_window(workspace.window_id()); + cx.activate_window(workspace.window()); cx.platform().activate(true); workspace.update(&mut cx, |workspace, cx| { @@ -4049,9 +4049,9 @@ pub fn restart(_: &Restart, cx: &mut AppContext) { // prompt in the active window before switching to a different window. workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); - if let (true, Some(window)) = (should_confirm, workspace_windows.first()) { + if let (true, Some(window)) = (should_confirm, workspace_windows.first().copied()) { let answer = cx.prompt( - window.id(), + window.into(), PromptLevel::Info, "Are you sure you want to restart?", &["Restart", "Cancel"], diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 3435727b1e0345ab1eef4cb63870b6b71f03c7f9..6397a1e6b2a818525b9e29879f0bd012dbc35e22 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -179,13 +179,12 @@ pub fn init(app_state: &Arc, cx: &mut gpui::AppContext) { move |workspace: &mut Workspace, _: &DebugElements, cx: &mut ViewContext| { let app_state = workspace.app_state().clone(); let markdown = app_state.languages.language_for_name("JSON"); - let window_id = cx.window_id(); + let window = cx.window(); cx.spawn(|workspace, mut cx| async move { let markdown = markdown.await.log_err(); - let content = to_string_pretty( - &cx.debug_elements(window_id) - .ok_or_else(|| anyhow!("could not debug elements for {window_id}"))?, - ) + let content = to_string_pretty(&cx.debug_elements(window).ok_or_else(|| { + anyhow!("could not debug elements for window {}", window.id()) + })?) .unwrap(); workspace .update(&mut cx, |workspace, cx| { @@ -416,9 +415,9 @@ fn quit(_: &Quit, cx: &mut gpui::AppContext) { // prompt in the active window before switching to a different window. workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); - if let (true, Some(window)) = (should_confirm, workspace_windows.first()) { + if let (true, Some(window)) = (should_confirm, workspace_windows.first().copied()) { let answer = cx.prompt( - window.id(), + window.into(), PromptLevel::Info, "Are you sure you want to quit?", &["Quit", "Cancel"], @@ -716,8 +715,8 @@ mod tests { use editor::{scroll::autoscroll::Autoscroll, DisplayPoint, Editor}; use fs::{FakeFs, Fs}; use gpui::{ - actions, elements::Empty, executor::Deterministic, Action, AnyElement, AppContext, - AssetSource, Element, Entity, TestAppContext, View, ViewHandle, + actions, elements::Empty, executor::Deterministic, Action, AnyElement, AnyWindowHandle, + AppContext, AssetSource, Element, Entity, TestAppContext, View, ViewHandle, }; use language::LanguageRegistry; use node_runtime::NodeRuntime; @@ -1317,11 +1316,10 @@ mod tests { project.update(cx, |project, _| project.languages().add(rust_lang())); let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); let worktree = cx.read(|cx| workspace.read(cx).worktrees(cx).next().unwrap()); // Create a new untitled buffer - cx.dispatch_action(window_id, NewFile); + cx.dispatch_action(window.into(), NewFile); let editor = workspace.read_with(cx, |workspace, cx| { workspace .active_item(cx) @@ -1376,7 +1374,7 @@ mod tests { // Open the same newly-created file in another pane item. The new editor should reuse // the same buffer. - cx.dispatch_action(window_id, NewFile); + cx.dispatch_action(window.into(), NewFile); workspace .update(cx, |workspace, cx| { workspace.split_and_clone( @@ -1412,10 +1410,9 @@ mod tests { project.update(cx, |project, _| project.languages().add(rust_lang())); let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); // Create a new untitled buffer - cx.dispatch_action(window_id, NewFile); + cx.dispatch_action(window.into(), NewFile); let editor = workspace.read_with(cx, |workspace, cx| { workspace .active_item(cx) @@ -1465,7 +1462,6 @@ mod tests { let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx); - let window_id = window.id(); let entries = cx.read(|cx| workspace.file_project_paths(cx)); let file1 = entries[0].clone(); @@ -1487,7 +1483,7 @@ mod tests { (editor.downgrade(), buffer) }); - cx.dispatch_action(window_id, pane::SplitRight); + cx.dispatch_action(window.into(), pane::SplitRight); let editor_2 = cx.update(|cx| { let pane_2 = workspace.read(cx).active_pane().clone(); assert_ne!(pane_1, pane_2); @@ -1497,7 +1493,7 @@ mod tests { pane2_item.downcast::().unwrap().downgrade() }); - cx.dispatch_action(window_id, workspace::CloseActiveItem); + cx.dispatch_action(window.into(), workspace::CloseActiveItem); cx.foreground().run_until_parked(); workspace.read_with(cx, |workspace, _| { @@ -1505,7 +1501,7 @@ mod tests { assert_eq!(workspace.active_pane(), &pane_1); }); - cx.dispatch_action(window_id, workspace::CloseActiveItem); + cx.dispatch_action(window.into(), workspace::CloseActiveItem); cx.foreground().run_until_parked(); window.simulate_prompt_answer(1, cx); cx.foreground().run_until_parked(); @@ -2063,11 +2059,10 @@ mod tests { cx.foreground().run_until_parked(); let window = cx.add_window(|_| TestView); - let window_id = window.id(); // Test loading the keymap base at all assert_key_bindings_for( - window_id, + window.into(), cx, vec![("backspace", &A), ("k", &ActivatePreviousPane)], line!(), @@ -2094,7 +2089,7 @@ mod tests { cx.foreground().run_until_parked(); assert_key_bindings_for( - window_id, + window.into(), cx, vec![("backspace", &B), ("k", &ActivatePreviousPane)], line!(), @@ -2117,7 +2112,7 @@ mod tests { cx.foreground().run_until_parked(); assert_key_bindings_for( - window_id, + window.into(), cx, vec![("backspace", &B), ("[", &ActivatePrevItem)], line!(), @@ -2125,7 +2120,7 @@ mod tests { #[track_caller] fn assert_key_bindings_for<'a>( - window_id: usize, + window: AnyWindowHandle, cx: &TestAppContext, actions: Vec<(&'static str, &'a dyn Action)>, line: u32, @@ -2133,7 +2128,7 @@ mod tests { for (key, action) in actions { // assert that... assert!( - cx.available_actions(window_id, 0) + cx.available_actions(window, 0) .into_iter() .any(|(_, bound_action, b)| { // action names match... @@ -2234,11 +2229,10 @@ mod tests { cx.foreground().run_until_parked(); let window = cx.add_window(|_| TestView); - let window_id = window.id(); // Test loading the keymap base at all assert_key_bindings_for( - window_id, + window.into(), cx, vec![("backspace", &A), ("k", &ActivatePreviousPane)], line!(), @@ -2264,7 +2258,12 @@ mod tests { cx.foreground().run_until_parked(); - assert_key_bindings_for(window_id, cx, vec![("k", &ActivatePreviousPane)], line!()); + assert_key_bindings_for( + window.into(), + cx, + vec![("k", &ActivatePreviousPane)], + line!(), + ); // Test modifying the base, while retaining the users keymap fs.save( @@ -2282,11 +2281,11 @@ mod tests { cx.foreground().run_until_parked(); - assert_key_bindings_for(window_id, cx, vec![("[", &ActivatePrevItem)], line!()); + assert_key_bindings_for(window.into(), cx, vec![("[", &ActivatePrevItem)], line!()); #[track_caller] fn assert_key_bindings_for<'a>( - window_id: usize, + window: AnyWindowHandle, cx: &TestAppContext, actions: Vec<(&'static str, &'a dyn Action)>, line: u32, @@ -2294,7 +2293,7 @@ mod tests { for (key, action) in actions { // assert that... assert!( - cx.available_actions(window_id, 0) + cx.available_actions(window, 0) .into_iter() .any(|(_, bound_action, b)| { // action names match... From da7dc9c880b06cf465aafacd8756abd9a6f60f86 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 11:12:32 -0600 Subject: [PATCH 149/160] Work with window handles instead of ids in drag code --- crates/command_palette/src/command_palette.rs | 6 +-- crates/drag_and_drop/src/drag_and_drop.rs | 40 +++++++++---------- crates/project_panel/src/project_panel.rs | 6 +-- crates/terminal_view/src/terminal_panel.rs | 4 +- .../src/pane/dragged_item_receiver.rs | 12 +++--- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index b3703aa64a4549596caf47b57fc91971c985b8f0..0d398fcce909863991a198018eba6df4c84f929c 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -1,8 +1,8 @@ use collections::CommandPaletteFilter; use fuzzy::{StringMatch, StringMatchCandidate}; use gpui::{ - actions, elements::*, keymap_matcher::Keystroke, Action, AppContext, Element, MouseState, - ViewContext, + actions, elements::*, keymap_matcher::Keystroke, Action, AnyWindowHandle, AppContext, Element, + MouseState, ViewContext, }; use picker::{Picker, PickerDelegate, PickerEvent}; use std::cmp; @@ -28,7 +28,7 @@ pub struct CommandPaletteDelegate { pub enum Event { Dismissed, Confirmed { - window_id: usize, + window: AnyWindowHandle, focused_view_id: usize, action: Box, }, diff --git a/crates/drag_and_drop/src/drag_and_drop.rs b/crates/drag_and_drop/src/drag_and_drop.rs index 828e73040387058ca89adcdb164986513ef96860..ddfed0c858237077bd9ec20b5ace46dfe41e34d9 100644 --- a/crates/drag_and_drop/src/drag_and_drop.rs +++ b/crates/drag_and_drop/src/drag_and_drop.rs @@ -6,7 +6,7 @@ use gpui::{ geometry::{rect::RectF, vector::Vector2F}, platform::{CursorStyle, MouseButton}, scene::{MouseDown, MouseDrag}, - AnyElement, Element, View, ViewContext, WeakViewHandle, WindowContext, + AnyElement, AnyWindowHandle, Element, View, ViewContext, WeakViewHandle, WindowContext, }; const DEAD_ZONE: f32 = 4.; @@ -21,7 +21,7 @@ enum State { region: RectF, }, Dragging { - window_id: usize, + window: AnyWindowHandle, position: Vector2F, region_offset: Vector2F, region: RectF, @@ -49,14 +49,14 @@ impl Clone for State { region, }, State::Dragging { - window_id, + window, position, region_offset, region, payload, render, } => Self::Dragging { - window_id: window_id.clone(), + window: window.clone(), position: position.clone(), region_offset: region_offset.clone(), region: region.clone(), @@ -87,16 +87,16 @@ impl DragAndDrop { self.containers.insert(handle); } - pub fn currently_dragged(&self, window_id: usize) -> Option<(Vector2F, Rc)> { + pub fn currently_dragged(&self, window: AnyWindowHandle) -> Option<(Vector2F, Rc)> { self.currently_dragged.as_ref().and_then(|state| { if let State::Dragging { position, payload, - window_id: window_dragged_from, + window: window_dragged_from, .. } = state { - if &window_id != window_dragged_from { + if &window != window_dragged_from { return None; } @@ -126,9 +126,9 @@ impl DragAndDrop { cx: &mut WindowContext, render: Rc) -> AnyElement>, ) { - let window_id = cx.window_id(); + let window = cx.window(); cx.update_global(|this: &mut Self, cx| { - this.notify_containers_for_window(window_id, cx); + this.notify_containers_for_window(window, cx); match this.currently_dragged.as_ref() { Some(&State::Down { @@ -141,7 +141,7 @@ impl DragAndDrop { }) => { if (event.position - (region.origin() + region_offset)).length() > DEAD_ZONE { this.currently_dragged = Some(State::Dragging { - window_id, + window, region_offset, region, position: event.position, @@ -163,7 +163,7 @@ impl DragAndDrop { .. }) => { this.currently_dragged = Some(State::Dragging { - window_id, + window, region_offset, region, position: event.position, @@ -188,14 +188,14 @@ impl DragAndDrop { State::Down { .. } => None, State::DeadZone { .. } => None, State::Dragging { - window_id, + window, region_offset, position, region, payload, render, } => { - if cx.window_id() != window_id { + if cx.window() != window { return None; } @@ -260,27 +260,27 @@ impl DragAndDrop { pub fn cancel_dragging(&mut self, cx: &mut WindowContext) { if let Some(State::Dragging { - payload, window_id, .. + payload, window, .. }) = &self.currently_dragged { if payload.is::

() { - let window_id = *window_id; + let window = *window; self.currently_dragged = Some(State::Canceled); - self.notify_containers_for_window(window_id, cx); + self.notify_containers_for_window(window, cx); } } } fn finish_dragging(&mut self, cx: &mut WindowContext) { - if let Some(State::Dragging { window_id, .. }) = self.currently_dragged.take() { - self.notify_containers_for_window(window_id, cx); + if let Some(State::Dragging { window, .. }) = self.currently_dragged.take() { + self.notify_containers_for_window(window, cx); } } - fn notify_containers_for_window(&mut self, window_id: usize, cx: &mut WindowContext) { + fn notify_containers_for_window(&mut self, window: AnyWindowHandle, cx: &mut WindowContext) { self.containers.retain(|container| { if let Some(container) = container.upgrade(cx) { - if container.window_id() == window_id { + if container.window() == window { container.update(cx, |_, cx| cx.notify()); } true diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index df4334a19fc7daf862504c6ef7ccfc6f3f9e3da0..f7582f1764c573ee5e72ba66c09472e7643aa075 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1415,7 +1415,7 @@ impl ProjectPanel { if cx .global::>() - .currently_dragged::(cx.window_id()) + .currently_dragged::(cx.window()) .is_some() && dragged_entry_destination .as_ref() @@ -1459,7 +1459,7 @@ impl ProjectPanel { .on_up(MouseButton::Left, move |_, this, cx| { if let Some((_, dragged_entry)) = cx .global::>() - .currently_dragged::(cx.window_id()) + .currently_dragged::(cx.window()) { this.move_entry( *dragged_entry, @@ -1472,7 +1472,7 @@ impl ProjectPanel { .on_move(move |_, this, cx| { if cx .global::>() - .currently_dragged::(cx.window_id()) + .currently_dragged::(cx.window()) .is_some() { this.dragged_entry_destination = if matches!(kind, EntryKind::File(_)) { diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index 6ad321c735deb00bb557058db5082761da9f7bbb..d00324cf166e8be68f355c0f4ad018a6d3d01fc1 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -48,7 +48,7 @@ impl TerminalPanel { fn new(workspace: &Workspace, cx: &mut ViewContext) -> Self { let weak_self = cx.weak_handle(); let pane = cx.add_view(|cx| { - let window_id = cx.window_id(); + let window = cx.window(); let mut pane = Pane::new( workspace.weak_handle(), workspace.project().clone(), @@ -60,7 +60,7 @@ impl TerminalPanel { pane.set_can_navigate(false, cx); pane.on_can_drop(move |drag_and_drop, cx| { drag_and_drop - .currently_dragged::(window_id) + .currently_dragged::(window) .map_or(false, |(_, item)| { item.handle.act_as::(cx).is_some() }) diff --git a/crates/workspace/src/pane/dragged_item_receiver.rs b/crates/workspace/src/pane/dragged_item_receiver.rs index 7146ab7b85b5dd4d91ceb4895fce060e34422ae3..2d3fe8ea8324411a7de5c2a70c1254648994652e 100644 --- a/crates/workspace/src/pane/dragged_item_receiver.rs +++ b/crates/workspace/src/pane/dragged_item_receiver.rs @@ -28,11 +28,11 @@ where let drag_and_drop = cx.global::>(); let drag_position = if (pane.can_drop)(drag_and_drop, cx) { drag_and_drop - .currently_dragged::(cx.window_id()) + .currently_dragged::(cx.window()) .map(|(drag_position, _)| drag_position) .or_else(|| { drag_and_drop - .currently_dragged::(cx.window_id()) + .currently_dragged::(cx.window()) .map(|(drag_position, _)| drag_position) }) } else { @@ -91,10 +91,10 @@ where let drag_and_drop = cx.global::>(); if drag_and_drop - .currently_dragged::(cx.window_id()) + .currently_dragged::(cx.window()) .is_some() || drag_and_drop - .currently_dragged::(cx.window_id()) + .currently_dragged::(cx.window()) .is_some() { cx.notify(); @@ -122,11 +122,11 @@ pub fn handle_dropped_item( } let drag_and_drop = cx.global::>(); let action = if let Some((_, dragged_item)) = - drag_and_drop.currently_dragged::(cx.window_id()) + drag_and_drop.currently_dragged::(cx.window()) { Action::Move(dragged_item.pane.clone(), dragged_item.handle.id()) } else if let Some((_, project_entry)) = - drag_and_drop.currently_dragged::(cx.window_id()) + drag_and_drop.currently_dragged::(cx.window()) { Action::Open(*project_entry) } else { From 0a4633f88f2166818ab57859783181a0972c0e77 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 11:20:09 -0600 Subject: [PATCH 150/160] Remove more window id usage --- crates/gpui/src/app.rs | 14 +++----------- crates/gpui/src/app/menu.rs | 2 +- crates/gpui/src/app/window.rs | 8 ++------ crates/project/src/terminals.rs | 6 +++--- crates/terminal/src/terminal.rs | 6 +++--- crates/terminal_view/src/terminal_panel.rs | 4 ++-- crates/terminal_view/src/terminal_view.rs | 8 ++++---- crates/workspace/src/item.rs | 7 ++++--- crates/workspace/src/searchable.rs | 2 +- crates/zed/src/main.rs | 4 ++-- 10 files changed, 25 insertions(+), 36 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index e0f46b036a07322844daf0fd7ca30c4d546e185f..e44ac93818fb768a8ae6ea12825ecb3a0e8d39ae 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -833,7 +833,7 @@ impl AppContext { &mut self, callback: F, ) -> Option { - self.main_window() + self.active_window() .and_then(|window| window.update(self, callback)) } @@ -1093,7 +1093,7 @@ impl AppContext { pub fn is_action_available(&self, action: &dyn Action) -> bool { let mut available_in_window = false; let action_id = action.id(); - if let Some(window) = self.main_window() { + if let Some(window) = self.active_window() { available_in_window = self .read_window(window, |cx| { if let Some(focused_view_id) = cx.focused_view_id() { @@ -1436,7 +1436,7 @@ impl AppContext { window } - pub fn main_window(&self) -> Option { + pub fn active_window(&self) -> Option { self.platform.main_window_id().and_then(|main_window_id| { self.windows .get(&main_window_id) @@ -2997,10 +2997,6 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> { WeakViewHandle::new(self.window_handle, self.view_id) } - pub fn window_id(&self) -> usize { - self.window_handle.id() - } - pub fn window(&self) -> AnyWindowHandle { self.window_handle } @@ -4138,10 +4134,6 @@ impl ViewHandle { self.any_handle } - pub fn window_id(&self) -> usize { - self.window.id() - } - pub fn window(&self) -> AnyWindowHandle { self.window } diff --git a/crates/gpui/src/app/menu.rs b/crates/gpui/src/app/menu.rs index 1d8908b8fdda9627d2eb7df433a7c5b819f024ed..67531a82975481c6a0bfa42511e6612175c94945 100644 --- a/crates/gpui/src/app/menu.rs +++ b/crates/gpui/src/app/menu.rs @@ -77,7 +77,7 @@ pub(crate) fn setup_menu_handlers(foreground_platform: &dyn ForegroundPlatform, let cx = app.0.clone(); move |action| { let mut cx = cx.borrow_mut(); - if let Some(main_window) = cx.main_window() { + if let Some(main_window) = cx.active_window() { let dispatched = main_window .update(&mut *cx, |cx| { if let Some(view_id) = cx.focused_view_id() { diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 44a3c5cfdc8ded2e004df2da56ee6ce510396871..df3f8207556ced0bc1cff4521711a1468084f915 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -152,11 +152,11 @@ impl BorrowWindowContext for WindowContext<'_> { } } - fn read_window_optional(&self, window_id: AnyWindowHandle, f: F) -> Option + fn read_window_optional(&self, window: AnyWindowHandle, f: F) -> Option where F: FnOnce(&WindowContext) -> Option, { - BorrowWindowContext::read_window(self, window_id, f) + BorrowWindowContext::read_window(self, window, f) } fn update_window T>( @@ -210,10 +210,6 @@ impl<'a> WindowContext<'a> { self.removed = true; } - pub fn window_id(&self) -> usize { - self.window_handle.id() - } - pub fn window(&self) -> AnyWindowHandle { self.window_handle } diff --git a/crates/project/src/terminals.rs b/crates/project/src/terminals.rs index 7bd9ce8aecb011e287005803e5e186573b35899c..db5996829fa278db04e793d751d02ace086594e3 100644 --- a/crates/project/src/terminals.rs +++ b/crates/project/src/terminals.rs @@ -1,5 +1,5 @@ use crate::Project; -use gpui::{ModelContext, ModelHandle, WeakModelHandle}; +use gpui::{AnyWindowHandle, ModelContext, ModelHandle, WeakModelHandle}; use std::path::PathBuf; use terminal::{Terminal, TerminalBuilder, TerminalSettings}; @@ -11,7 +11,7 @@ impl Project { pub fn create_terminal( &mut self, working_directory: Option, - window_id: usize, + window: AnyWindowHandle, cx: &mut ModelContext, ) -> anyhow::Result> { if self.is_remote() { @@ -27,7 +27,7 @@ impl Project { settings.env.clone(), Some(settings.blinking.clone()), settings.alternate_scroll, - window_id, + window, ) .map(|builder| { let terminal_handle = cx.add_model(|cx| builder.subscribe(cx)); diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 06befd5f4ef5b76a4cedccad0fdd526c7d6c0edc..f6cfe5ae309093ddffb7cca1b00666f22448b08d 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -53,7 +53,7 @@ use gpui::{ keymap_matcher::Keystroke, platform::{Modifiers, MouseButton, MouseMovedEvent, TouchPhase}, scene::{MouseDown, MouseDrag, MouseScrollWheel, MouseUp}, - AppContext, ClipboardItem, Entity, ModelContext, Task, + AnyWindowHandle, AppContext, ClipboardItem, Entity, ModelContext, Task, }; use crate::mappings::{ @@ -404,7 +404,7 @@ impl TerminalBuilder { mut env: HashMap, blink_settings: Option, alternate_scroll: AlternateScroll, - window_id: usize, + window: AnyWindowHandle, ) -> Result { let pty_config = { let alac_shell = match shell.clone() { @@ -462,7 +462,7 @@ impl TerminalBuilder { let pty = match tty::new( &pty_config, TerminalSize::default().into(), - window_id as u64, + window.id() as u64, ) { Ok(pty) => pty, Err(error) => { diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index d00324cf166e8be68f355c0f4ad018a6d3d01fc1..6be8a547cd37c8dc8c5fad225b06dd9fcbc6dafd 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -255,10 +255,10 @@ impl TerminalPanel { .clone(); let working_directory = crate::get_working_directory(workspace, cx, working_directory_strategy); - let window_id = cx.window_id(); + let window = cx.window(); if let Some(terminal) = workspace.project().update(cx, |project, cx| { project - .create_terminal(working_directory, window_id, cx) + .create_terminal(working_directory, window, cx) .log_err() }) { let terminal = Box::new(cx.add_view(|cx| { diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index a600046ac2861fb7b0b1250c65d4b31c1af3166c..970e0115df2545ce9f8979fc5e2efc876d08242f 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -112,11 +112,11 @@ impl TerminalView { let working_directory = get_working_directory(workspace, cx, strategy.working_directory.clone()); - let window_id = cx.window_id(); + let window = cx.window(); let terminal = workspace .project() .update(cx, |project, cx| { - project.create_terminal(working_directory, window_id, cx) + project.create_terminal(working_directory, window, cx) }) .notify_err(workspace, cx); @@ -741,7 +741,7 @@ impl Item for TerminalView { item_id: workspace::ItemId, cx: &mut ViewContext, ) -> Task>> { - let window_id = cx.window_id(); + let window = cx.window(); cx.spawn(|pane, mut cx| async move { let cwd = TERMINAL_DB .get_working_directory(item_id, workspace_id) @@ -762,7 +762,7 @@ impl Item for TerminalView { }); let terminal = project.update(&mut cx, |project, cx| { - project.create_terminal(cwd, window_id, cx) + project.create_terminal(cwd, window, cx) })?; Ok(pane.update(&mut cx, |_, cx| { cx.add_view(|cx| TerminalView::new(terminal, workspace, workspace_id, cx)) diff --git a/crates/workspace/src/item.rs b/crates/workspace/src/item.rs index f0af080d4a6cd9719db897a6320c869695092fe9..67827b78038b048ad619209b9a26bc5c0ba031b6 100644 --- a/crates/workspace/src/item.rs +++ b/crates/workspace/src/item.rs @@ -6,6 +6,7 @@ use crate::{AutosaveSetting, DelayedDebouncedEditAction, WorkspaceSettings}; use anyhow::Result; use client::{proto, Client}; use gpui::geometry::vector::Vector2F; +use gpui::AnyWindowHandle; use gpui::{ fonts::HighlightStyle, AnyElement, AnyViewHandle, AppContext, ModelHandle, Task, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext, @@ -250,7 +251,7 @@ pub trait ItemHandle: 'static + fmt::Debug { fn workspace_deactivated(&self, cx: &mut WindowContext); fn navigate(&self, data: Box, cx: &mut WindowContext) -> bool; fn id(&self) -> usize; - fn window_id(&self) -> usize; + fn window(&self) -> AnyWindowHandle; fn as_any(&self) -> &AnyViewHandle; fn is_dirty(&self, cx: &AppContext) -> bool; fn has_conflict(&self, cx: &AppContext) -> bool; @@ -542,8 +543,8 @@ impl ItemHandle for ViewHandle { self.id() } - fn window_id(&self) -> usize { - self.window_id() + fn window(&self) -> AnyWindowHandle { + AnyViewHandle::window(self) } fn as_any(&self) -> &AnyViewHandle { diff --git a/crates/workspace/src/searchable.rs b/crates/workspace/src/searchable.rs index ae95838a742bb623a9376947e905d6054a82fff4..72117e1cabbefec98ba3af35ba5bd00571851647 100644 --- a/crates/workspace/src/searchable.rs +++ b/crates/workspace/src/searchable.rs @@ -235,7 +235,7 @@ impl From<&Box> for AnyViewHandle { impl PartialEq for Box { fn eq(&self, other: &Self) -> bool { - self.id() == other.id() && self.window_id() == other.window_id() + self.id() == other.id() && self.window() == other.window() } } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 2a1fef6a56efc5bf1c5496c935c134a752767066..bb30cac6d308b8df2a9a8d1db83084390b6adb61 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -931,11 +931,11 @@ pub fn dock_default_item_factory( .clone(); let working_directory = get_working_directory(workspace, cx, strategy); - let window_id = cx.window_id(); + let window = cx.window(); let terminal = workspace .project() .update(cx, |project, cx| { - project.create_terminal(working_directory, window_id, cx) + project.create_terminal(working_directory, window, cx) }) .notify_err(workspace, cx)?; From fe6a1886c1e26e821bc05cfc106ff3bffe322299 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 11:20:42 -0600 Subject: [PATCH 151/160] Remove unused dock code --- crates/zed/src/main.rs | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index bb30cac6d308b8df2a9a8d1db83084390b6adb61..795c83aba6583e71a9da1eecb77c2d4d41e0780b 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -14,7 +14,7 @@ use futures::{ channel::{mpsc, oneshot}, FutureExt, SinkExt, StreamExt, }; -use gpui::{Action, App, AppContext, AssetSource, AsyncAppContext, Task, ViewContext}; +use gpui::{Action, App, AppContext, AssetSource, AsyncAppContext, Task}; use isahc::{config::Configurable, Request}; use language::{LanguageRegistry, Point}; use log::LevelFilter; @@ -43,7 +43,6 @@ use std::{ time::{Duration, SystemTime, UNIX_EPOCH}, }; use sum_tree::Bias; -use terminal_view::{get_working_directory, TerminalSettings, TerminalView}; use util::{ channel::ReleaseChannel, http::{self, HttpClient}, @@ -56,7 +55,7 @@ use fs::RealFs; #[cfg(debug_assertions)] use staff_mode::StaffMode; use util::{channel::RELEASE_CHANNEL, paths, ResultExt, TryFutureExt}; -use workspace::{item::ItemHandle, notifications::NotifyResultExt, AppState, Workspace}; +use workspace::AppState; use zed::{ assets::Assets, build_window_options, handle_keymap_file_changes, initialize_workspace, languages, menus, @@ -922,35 +921,6 @@ async fn handle_cli_connection( } } -pub fn dock_default_item_factory( - workspace: &mut Workspace, - cx: &mut ViewContext, -) -> Option> { - let strategy = settings::get::(cx) - .working_directory - .clone(); - let working_directory = get_working_directory(workspace, cx, strategy); - - let window = cx.window(); - let terminal = workspace - .project() - .update(cx, |project, cx| { - project.create_terminal(working_directory, window, cx) - }) - .notify_err(workspace, cx)?; - - let terminal_view = cx.add_view(|cx| { - TerminalView::new( - terminal, - workspace.weak_handle(), - workspace.database_id(), - cx, - ) - }); - - Some(Box::new(terminal_view)) -} - pub fn background_actions() -> &'static [(&'static str, &'static dyn Action)] { &[ ("Go to file", &file_finder::Toggle), From 1fd80ba8bd12e6dcfb26da3090ab876563422dee Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 11:22:43 -0600 Subject: [PATCH 152/160] Remove AsyncAppContext::remove_window --- crates/gpui/src/app.rs | 4 ---- crates/workspace/src/workspace.rs | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index e44ac93818fb768a8ae6ea12825ecb3a0e8d39ae..2b3a3f3bf4a012f6e19b910fb4d0775faae2d9a8 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -411,10 +411,6 @@ impl AsyncAppContext { self.update(|cx| cx.add_window(window_options, build_root_view)) } - pub fn remove_window(&mut self, window: AnyWindowHandle) { - self.update_window(window, |cx| cx.remove_window()); - } - pub fn activate_window(&mut self, window: AnyWindowHandle) { self.update_window(window, |cx| cx.activate_window()); } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index f0990322653757344d459e2bc2ef1f8c569cbdcf..f2a7a442f446a34ca265592dfdba46bcbbee855f 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1254,7 +1254,7 @@ impl Workspace { let prepare = self.prepare_to_close(false, cx); Some(cx.spawn(|_, mut cx| async move { if prepare.await? { - cx.remove_window(window); + window.remove(&mut cx); } Ok(()) })) From 4f10f0ee865b92f6853cef9f9cd046d0c01eb8c0 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 11:23:49 -0600 Subject: [PATCH 153/160] Remove window methods from AsyncAppContext --- crates/gpui/src/app.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 2b3a3f3bf4a012f6e19b910fb4d0775faae2d9a8..ddec0e10a3ccdbcdbe43b8b564fbba0501a913b0 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -344,22 +344,6 @@ impl AsyncAppContext { self.0.borrow().windows().collect() } - pub fn read_window T>( - &self, - window: AnyWindowHandle, - callback: F, - ) -> Option { - self.0.borrow_mut().read_window(window, callback) - } - - pub fn update_window T>( - &mut self, - window: AnyWindowHandle, - callback: F, - ) -> Option { - self.0.borrow_mut().update_window(window, callback) - } - pub fn debug_elements(&self, window: AnyWindowHandle) -> Option { self.0.borrow().read_window(window, |cx| { let root_view = cx.window.root_view(); From 95cd96e4becbf8e1404effb90893e5a1f6f0b3ce Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 11:27:19 -0600 Subject: [PATCH 154/160] Move debug_elements to AnyWindowHandle --- crates/gpui/src/app.rs | 16 ++++++++-------- crates/zed/src/zed.rs | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index ddec0e10a3ccdbcdbe43b8b564fbba0501a913b0..5eb4ed744cbcfb54d83e0f72eab6a7e9dcf6bf97 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -344,14 +344,6 @@ impl AsyncAppContext { self.0.borrow().windows().collect() } - pub fn debug_elements(&self, window: AnyWindowHandle) -> Option { - self.0.borrow().read_window(window, |cx| { - let root_view = cx.window.root_view(); - let root_element = cx.window.rendered_views.get(&root_view.id())?; - root_element.debug(cx).log_err() - })? - } - pub fn dispatch_action( &mut self, window: AnyWindowHandle, @@ -4060,6 +4052,14 @@ impl AnyWindowHandle { self.update(cx, |cx| cx.remove_window()) } + pub fn debug_elements(&self, cx: &C) -> Option { + self.read_optional_with(cx, |cx| { + let root_view = cx.window.root_view(); + let root_element = cx.window.rendered_views.get(&root_view.id())?; + root_element.debug(cx).log_err() + }) + } + #[cfg(any(test, feature = "test-support"))] pub fn simulate_activation(&self, cx: &mut TestAppContext) { self.update(cx, |cx| { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 6397a1e6b2a818525b9e29879f0bd012dbc35e22..1cde8d5b9a52b7970ae116f62752182eace1427d 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -182,7 +182,7 @@ pub fn init(app_state: &Arc, cx: &mut gpui::AppContext) { let window = cx.window(); cx.spawn(|workspace, mut cx| async move { let markdown = markdown.await.log_err(); - let content = to_string_pretty(&cx.debug_elements(window).ok_or_else(|| { + let content = to_string_pretty(&window.debug_elements(&cx).ok_or_else(|| { anyhow!("could not debug elements for window {}", window.id()) })?) .unwrap(); From b2d9ccc0a2f97a8ad4cde4fa15aa9bd500bfc63e Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 11:38:07 -0600 Subject: [PATCH 155/160] Move more window methods off AsyncAppContext --- crates/collab_ui/src/contact_list.rs | 4 +- crates/command_palette/src/command_palette.rs | 13 ++-- crates/context_menu/src/context_menu.rs | 14 +++- crates/gpui/src/app.rs | 71 +++++++++---------- crates/search/src/project_search.rs | 12 ++-- crates/workspace/src/dock.rs | 7 +- crates/workspace/src/workspace.rs | 12 ++-- crates/zed/src/zed.rs | 4 +- 8 files changed, 73 insertions(+), 64 deletions(-) diff --git a/crates/collab_ui/src/contact_list.rs b/crates/collab_ui/src/contact_list.rs index a2b281856d923754e715e0e112eca2f5c682e605..49784523845918b601e2d856fc4fcec6ebe60550 100644 --- a/crates/collab_ui/src/contact_list.rs +++ b/crates/collab_ui/src/contact_list.rs @@ -312,11 +312,11 @@ impl ContactList { .update(&mut cx, |store, cx| store.remove_contact(user_id, cx)) .await { - cx.prompt( - window, + window.prompt( PromptLevel::Info, &format!("Failed to remove contact: {}", e), &["Ok"], + &mut cx, ); } } diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 0d398fcce909863991a198018eba6df4c84f929c..101d4dc545cc2ecc2130a19989b8d57fea62fe97 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -1,8 +1,8 @@ use collections::CommandPaletteFilter; use fuzzy::{StringMatch, StringMatchCandidate}; use gpui::{ - actions, elements::*, keymap_matcher::Keystroke, Action, AnyWindowHandle, AppContext, Element, - MouseState, ViewContext, + actions, anyhow::anyhow, elements::*, keymap_matcher::Keystroke, Action, AnyWindowHandle, + AppContext, Element, MouseState, ViewContext, }; use picker::{Picker, PickerDelegate, PickerEvent}; use std::cmp; @@ -83,9 +83,10 @@ impl PickerDelegate for CommandPaletteDelegate { let view_id = self.focused_view_id; let window = cx.window(); cx.spawn(move |picker, mut cx| async move { - let actions = cx - .available_actions(window, view_id) + let actions = window + .available_actions(view_id, &cx) .into_iter() + .flatten() .filter_map(|(name, action, bindings)| { let filtered = cx.read(|cx| { if cx.has_global::() { @@ -168,7 +169,9 @@ impl PickerDelegate for CommandPaletteDelegate { let action = self.actions.remove(action_ix).action; cx.app_context() .spawn(move |mut cx| async move { - cx.dispatch_action(window, focused_view_id, action.as_ref()) + window + .dispatch_action(focused_view_id, action.as_ref(), &mut cx) + .ok_or_else(|| anyhow!("window was closed")) }) .detach_and_log_err(cx); } diff --git a/crates/context_menu/src/context_menu.rs b/crates/context_menu/src/context_menu.rs index 75cfd872b29aba9b03b1235faeaba24d8ac95ae7..a5534b6262c03166d462fe001ae130a891d4cfa3 100644 --- a/crates/context_menu/src/context_menu.rs +++ b/crates/context_menu/src/context_menu.rs @@ -1,5 +1,5 @@ use gpui::{ - anyhow, + anyhow::{self, anyhow}, elements::*, geometry::vector::Vector2F, keymap_matcher::KeymapContext, @@ -223,7 +223,9 @@ impl ContextMenu { let action = action.boxed_clone(); cx.app_context() .spawn(|mut cx| async move { - cx.dispatch_action(window, view_id, action.as_ref()) + window + .dispatch_action(view_id, action.as_ref(), &mut cx) + .ok_or_else(|| anyhow!("window was closed")) }) .detach_and_log_err(cx); } @@ -486,7 +488,13 @@ impl ContextMenu { let action = action.boxed_clone(); cx.app_context() .spawn(|mut cx| async move { - cx.dispatch_action(window, view_id, action.as_ref()) + window + .dispatch_action( + view_id, + action.as_ref(), + &mut cx, + ) + .ok_or_else(|| anyhow!("window was closed")) }) .detach_and_log_err(cx); } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 5eb4ed744cbcfb54d83e0f72eab6a7e9dcf6bf97..e6e11ca321bfe73a16a1755ce482878519009842 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -344,29 +344,6 @@ impl AsyncAppContext { self.0.borrow().windows().collect() } - pub fn dispatch_action( - &mut self, - window: AnyWindowHandle, - view_id: usize, - action: &dyn Action, - ) -> Result<()> { - self.0 - .borrow_mut() - .update_window(window, |cx| { - cx.dispatch_action(Some(view_id), action); - }) - .ok_or_else(|| anyhow!("window not found")) - } - - pub fn available_actions( - &self, - window: AnyWindowHandle, - view_id: usize, - ) -> Vec<(&'static str, Box, SmallVec<[Binding; 1]>)> { - self.read_window(window, |cx| cx.available_actions(view_id)) - .unwrap_or_default() - } - pub fn add_model(&mut self, build_model: F) -> ModelHandle where T: Entity, @@ -387,21 +364,6 @@ impl AsyncAppContext { self.update(|cx| cx.add_window(window_options, build_root_view)) } - pub fn activate_window(&mut self, window: AnyWindowHandle) { - self.update_window(window, |cx| cx.activate_window()); - } - - // TODO: Can we eliminate this method and move it to WindowContext then call it with update_window?s - pub fn prompt( - &mut self, - window: AnyWindowHandle, - level: PromptLevel, - msg: &str, - answers: &[&str], - ) -> Option> { - self.update_window(window, |cx| cx.prompt(level, msg, answers)) - } - pub fn platform(&self) -> Arc { self.0.borrow().platform().clone() } @@ -4060,6 +4022,39 @@ impl AnyWindowHandle { }) } + pub fn activate(&mut self, cx: &mut C) -> C::Result<()> { + self.update(cx, |cx| cx.activate_window()) + } + + pub fn prompt( + &self, + level: PromptLevel, + msg: &str, + answers: &[&str], + cx: &mut C, + ) -> C::Result> { + self.update(cx, |cx| cx.prompt(level, msg, answers)) + } + + pub fn dispatch_action( + &self, + view_id: usize, + action: &dyn Action, + cx: &mut C, + ) -> C::Result<()> { + self.update(cx, |cx| { + cx.dispatch_action(Some(view_id), action); + }) + } + + pub fn available_actions( + &self, + view_id: usize, + cx: &C, + ) -> C::Result, SmallVec<[Binding; 1]>)>> { + self.read_with(cx, |cx| cx.available_actions(view_id)) + } + #[cfg(any(test, feature = "test-support"))] pub fn simulate_activation(&self, cx: &mut TestAppContext) { self.update(cx, |cx| { diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 202d494560e7388b689a4b9f8750b07c62758697..018ab9cb11525a1c3145ec96316095573d6406ef 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1599,7 +1599,7 @@ pub mod tests { let search_view_id = search_view.id(); cx.spawn(|mut cx| async move { - cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + window.dispatch_action(search_view_id, &ToggleFocus, &mut cx); }) .detach(); deterministic.run_until_parked(); @@ -1650,9 +1650,9 @@ pub mod tests { "Search view should be focused after mismatching query had been used in search", ); }); - cx.spawn(|mut cx| async move { - cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) - }) + cx.spawn( + |mut cx| async move { window.dispatch_action(search_view_id, &ToggleFocus, &mut cx) }, + ) .detach(); deterministic.run_until_parked(); search_view.update(cx, |search_view, cx| { @@ -1683,7 +1683,7 @@ pub mod tests { ); }); cx.spawn(|mut cx| async move { - cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + window.dispatch_action(search_view_id, &ToggleFocus, &mut cx); }) .detach(); deterministic.run_until_parked(); @@ -1713,7 +1713,7 @@ pub mod tests { }); cx.spawn(|mut cx| async move { - cx.dispatch_action(window.into(), search_view_id, &ToggleFocus) + window.dispatch_action(search_view_id, &ToggleFocus, &mut cx); }) .detach(); deterministic.run_until_parked(); diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 5bb0fd93f8c9290c6f71f0ff94972115c9e3629c..e33c0a5391724ba16012ac87bf210f62da857461 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -534,8 +534,11 @@ impl View for PanelButtons { let view_id = this.workspace.id(); let tooltip_action = tooltip_action.boxed_clone(); cx.spawn(|_, mut cx| async move { - cx.dispatch_action(window, view_id, &*tooltip_action) - .ok(); + window.dispatch_action( + view_id, + &*tooltip_action, + &mut cx, + ); }) .detach(); } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index f2a7a442f446a34ca265592dfdba46bcbbee855f..2f884b0ceb33d10e598057a65e1c44a60471227e 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1280,11 +1280,11 @@ impl Workspace { && workspace_count == 1 && active_call.read_with(&cx, |call, _| call.room().is_some()) { - let answer = cx.prompt( - window, + let answer = window.prompt( PromptLevel::Warning, "Do you want to leave the current call?", &["Close window and hang up", "Cancel"], + &mut cx, ); if let Some(mut answer) = answer { @@ -4000,7 +4000,7 @@ pub fn join_remote_project( workspace.downgrade() }; - cx.activate_window(workspace.window()); + workspace.window().activate(&mut cx); cx.platform().activate(true); workspace.update(&mut cx, |workspace, cx| { @@ -4049,12 +4049,12 @@ pub fn restart(_: &Restart, cx: &mut AppContext) { // prompt in the active window before switching to a different window. workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); - if let (true, Some(window)) = (should_confirm, workspace_windows.first().copied()) { - let answer = cx.prompt( - window.into(), + if let (true, Some(window)) = (should_confirm, workspace_windows.first()) { + let answer = window.prompt( PromptLevel::Info, "Are you sure you want to restart?", &["Restart", "Cancel"], + &mut cx, ); if let Some(mut answer) = answer { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 1cde8d5b9a52b7970ae116f62752182eace1427d..8ad8080375ec22e1c60840a0cac0565e95969aaa 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -416,11 +416,11 @@ fn quit(_: &Quit, cx: &mut gpui::AppContext) { workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false)); if let (true, Some(window)) = (should_confirm, workspace_windows.first().copied()) { - let answer = cx.prompt( - window.into(), + let answer = window.prompt( PromptLevel::Info, "Are you sure you want to quit?", &["Quit", "Cancel"], + &mut cx, ); if let Some(mut answer) = answer { From b77c336a3d719cc1a483e58319bcdf310739e774 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 11:39:56 -0600 Subject: [PATCH 156/160] Return window handles from WeakItemHandle --- crates/workspace/src/item.rs | 6 +++--- crates/workspace/src/searchable.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/workspace/src/item.rs b/crates/workspace/src/item.rs index 67827b78038b048ad619209b9a26bc5c0ba031b6..21956be44683f0160c7be0d6387d4d03a60c25d7 100644 --- a/crates/workspace/src/item.rs +++ b/crates/workspace/src/item.rs @@ -281,7 +281,7 @@ pub trait ItemHandle: 'static + fmt::Debug { pub trait WeakItemHandle { fn id(&self) -> usize; - fn window_id(&self) -> usize; + fn window(&self) -> AnyWindowHandle; fn upgrade(&self, cx: &AppContext) -> Option>; } @@ -650,8 +650,8 @@ impl WeakItemHandle for WeakViewHandle { self.id() } - fn window_id(&self) -> usize { - self.window_id() + fn window(&self) -> AnyWindowHandle { + self.window() } fn upgrade(&self, cx: &AppContext) -> Option> { diff --git a/crates/workspace/src/searchable.rs b/crates/workspace/src/searchable.rs index 72117e1cabbefec98ba3af35ba5bd00571851647..7a470db7c926dd8d2a2aee171fd5d269b6eebab3 100644 --- a/crates/workspace/src/searchable.rs +++ b/crates/workspace/src/searchable.rs @@ -259,7 +259,7 @@ impl WeakSearchableItemHandle for WeakViewHandle { impl PartialEq for Box { fn eq(&self, other: &Self) -> bool { - self.id() == other.id() && self.window_id() == other.window_id() + self.id() == other.id() && self.window() == other.window() } } @@ -267,6 +267,6 @@ impl Eq for Box {} impl std::hash::Hash for Box { fn hash(&self, state: &mut H) { - (self.id(), self.window_id()).hash(state) + (self.id(), self.window().id()).hash(state) } } From afd89b256abb4e5519446de40c6c52067d1b6587 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 16:06:53 -0600 Subject: [PATCH 157/160] Store AnyWindowHandles instead of usizes --- crates/gpui/src/app.rs | 126 ++++++++------------ crates/gpui/src/app/ref_counts.rs | 14 +-- crates/gpui/src/app/test_app_context.rs | 4 +- crates/gpui/src/app/window.rs | 28 ++--- crates/gpui/src/app/window_input_handler.rs | 2 +- crates/gpui/src/platform.rs | 8 +- crates/gpui/src/platform/mac/platform.rs | 12 +- crates/gpui/src/platform/mac/window.rs | 17 +-- crates/gpui/src/platform/test.rs | 40 ++++--- 9 files changed, 117 insertions(+), 134 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index e6e11ca321bfe73a16a1755ce482878519009842..507cbffad279553dea2612dbb9a898ab4358ae8b 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -444,9 +444,9 @@ type WindowShouldCloseSubscriptionCallback = Box b pub struct AppContext { models: HashMap>, - views: HashMap<(usize, usize), Box>, - views_metadata: HashMap<(usize, usize), ViewMetadata>, - windows: HashMap, + views: HashMap<(AnyWindowHandle, usize), Box>, + views_metadata: HashMap<(AnyWindowHandle, usize), ViewMetadata>, + windows: HashMap, globals: HashMap>, element_states: HashMap>, background: Arc, @@ -727,12 +727,12 @@ impl AppContext { } pub fn view_ui_name(&self, window: AnyWindowHandle, view_id: usize) -> Option<&'static str> { - Some(self.views.get(&(window.id(), view_id))?.ui_name()) + Some(self.views.get(&(window, view_id))?.ui_name()) } pub fn view_type_id(&self, window: AnyWindowHandle, view_id: usize) -> Option { self.views_metadata - .get(&(window.id(), view_id)) + .get(&(window, view_id)) .map(|metadata| metadata.type_id) } @@ -758,7 +758,7 @@ impl AppContext { handle: AnyWindowHandle, callback: F, ) -> Option { - let window = self.windows.get(&handle.id())?; + let window = self.windows.get(&handle)?; let window_context = WindowContext::immutable(self, &window, handle); Some(callback(&window_context)) } @@ -1033,7 +1033,7 @@ impl AppContext { if let Some(focused_view_id) = cx.focused_view_id() { for view_id in cx.ancestors(focused_view_id) { if let Some(view_metadata) = - cx.views_metadata.get(&(cx.window_handle.id(), view_id)) + cx.views_metadata.get(&(cx.window_handle, view_id)) { if let Some(actions) = cx.actions.get(&view_metadata.type_id) { if actions.contains_key(&action_id) { @@ -1259,13 +1259,12 @@ impl AppContext { F: FnOnce(&mut ViewContext) -> V, { self.update(|this| { - let window_id = post_inc(&mut this.next_id); + let handle = WindowHandle::::new(post_inc(&mut this.next_id)); let platform_window = this.platform - .open_window(window_id, window_options, this.foreground.clone()); - let handle = WindowHandle::::new(window_id); - let window = this.build_window(handle, platform_window, build_root_view); - this.windows.insert(window_id, window); + .open_window(handle.into(), window_options, this.foreground.clone()); + let window = this.build_window(handle.into(), platform_window, build_root_view); + this.windows.insert(handle.into(), window); handle }) } @@ -1276,29 +1275,25 @@ impl AppContext { F: FnOnce(&mut ViewContext) -> V, { self.update(|this| { - let window_id = post_inc(&mut this.next_id); - let platform_window = this.platform.add_status_item(window_id); - let handle = WindowHandle::::new(window_id); - let window = this.build_window(handle, platform_window, build_root_view); - this.windows.insert(window_id, window); + let handle = WindowHandle::::new(post_inc(&mut this.next_id)); + let platform_window = this.platform.add_status_item(handle.into()); + let window = this.build_window(handle.into(), platform_window, build_root_view); + this.windows.insert(handle.into(), window); handle.update_root(this, |view, cx| view.focus_in(cx.handle().into_any(), cx)); handle }) } - pub fn build_window( + pub fn build_window( &mut self, - handle: H, + handle: AnyWindowHandle, mut platform_window: Box, build_root_view: F, ) -> Window where - H: Into, V: View, F: FnOnce(&mut ViewContext) -> V, { - let handle: AnyWindowHandle = handle.into(); - { let mut app = self.upgrade(); @@ -1371,21 +1366,15 @@ impl AppContext { } pub fn active_window(&self) -> Option { - self.platform.main_window_id().and_then(|main_window_id| { - self.windows - .get(&main_window_id) - .map(|window| AnyWindowHandle::new(main_window_id, window.root_view().type_id())) - }) + self.platform.main_window() } pub fn windows(&self) -> impl '_ + Iterator { - self.windows.iter().map(|(window_id, window)| { - AnyWindowHandle::new(*window_id, window.root_view().type_id()) - }) + self.windows.keys().copied() } pub fn read_view(&self, handle: &ViewHandle) -> &T { - if let Some(view) = self.views.get(&(handle.window.id(), handle.view_id)) { + if let Some(view) = self.views.get(&(handle.window, handle.view_id)) { view.as_any().downcast_ref().expect("downcast is type safe") } else { panic!("circular view reference for type {}", type_name::()); @@ -1437,13 +1426,13 @@ impl AppContext { .push_back(Effect::ModelRelease { model_id, model }); } - for (window_id, view_id) in dropped_views { + for (window, view_id) in dropped_views { self.subscriptions.remove(view_id); self.observations.remove(view_id); - self.views_metadata.remove(&(window_id, view_id)); - let mut view = self.views.remove(&(window_id, view_id)).unwrap(); + self.views_metadata.remove(&(window, view_id)); + let mut view = self.views.remove(&(window, view_id)).unwrap(); view.release(self); - if let Some(window) = self.windows.get_mut(&window_id) { + if let Some(window) = self.windows.get_mut(&window) { window.parents.remove(&view_id); window .invalidation @@ -1571,7 +1560,7 @@ impl AppContext { } Effect::ResizeWindow { window } => { - if let Some(window) = self.windows.get_mut(&window.id()) { + if let Some(window) = self.windows.get_mut(&window) { window .invalidation .get_or_insert(WindowInvalidation::default()); @@ -1696,15 +1685,14 @@ impl AppContext { for old_ancestor in old_ancestors.iter().copied() { if !new_ancestors.contains(&old_ancestor) { if let Some(mut view) = - cx.views.remove(&(window.id(), old_ancestor)) + cx.views.remove(&(window, old_ancestor)) { view.focus_out( focused_view_id, cx, old_ancestor, ); - cx.views - .insert((window.id(), old_ancestor), view); + cx.views.insert((window, old_ancestor), view); } } } @@ -1713,15 +1701,14 @@ impl AppContext { for new_ancestor in new_ancestors.iter().copied() { if !old_ancestors.contains(&new_ancestor) { if let Some(mut view) = - cx.views.remove(&(window.id(), new_ancestor)) + cx.views.remove(&(window, new_ancestor)) { view.focus_in( focused_view_id, cx, new_ancestor, ); - cx.views - .insert((window.id(), new_ancestor), view); + cx.views.insert((window, new_ancestor), view); } } } @@ -1730,9 +1717,7 @@ impl AppContext { // there isn't any pending focus, focus the root view. let root_view_id = cx.window.root_view().id(); if focused_view_id != root_view_id - && !cx - .views - .contains_key(&(window.id(), focused_view_id)) + && !cx.views.contains_key(&(window, focused_view_id)) && !focus_effects.contains_key(&window.id()) { focus_effects.insert( @@ -1837,13 +1822,13 @@ impl AppContext { observed_window: AnyWindowHandle, observed_view_id: usize, ) { - let view_key = (observed_window.id(), observed_view_id); + let view_key = (observed_window, observed_view_id); if let Some((view, mut view_metadata)) = self .views .remove(&view_key) .zip(self.views_metadata.remove(&view_key)) { - if let Some(window) = self.windows.get_mut(&observed_window.id()) { + if let Some(window) = self.windows.get_mut(&observed_window) { window .invalidation .get_or_insert_with(Default::default) @@ -1924,7 +1909,7 @@ impl AppContext { let focused_id = match effect { FocusEffect::View { view_id, .. } => { if let Some(view_id) = view_id { - if cx.views.contains_key(&(window.id(), view_id)) { + if cx.views.contains_key(&(window, view_id)) { Some(view_id) } else { Some(cx.root_view().id()) @@ -1949,9 +1934,9 @@ impl AppContext { if focus_changed { if let Some(blurred_id) = blurred_id { for view_id in cx.ancestors(blurred_id).collect::>() { - if let Some(mut view) = cx.views.remove(&(window.id(), view_id)) { + if let Some(mut view) = cx.views.remove(&(window, view_id)) { view.focus_out(blurred_id, cx, view_id); - cx.views.insert((window.id(), view_id), view); + cx.views.insert((window, view_id), view); } } @@ -1963,9 +1948,9 @@ impl AppContext { if focus_changed || effect.is_forced() { if let Some(focused_id) = focused_id { for view_id in cx.ancestors(focused_id).collect::>() { - if let Some(mut view) = cx.views.remove(&(window.id(), view_id)) { + if let Some(mut view) = cx.views.remove(&(window, view_id)) { view.focus_in(focused_id, cx, view_id); - cx.views.insert((window.id(), view_id), view); + cx.views.insert((window, view_id), view); } } @@ -1991,7 +1976,7 @@ impl AppContext { mut callback: WindowShouldCloseSubscriptionCallback, ) { let mut app = self.upgrade(); - if let Some(window) = self.windows.get_mut(&window.id()) { + if let Some(window) = self.windows.get_mut(&window) { window .platform_window .on_should_close(Box::new(move || app.update(|cx| callback(cx)))) @@ -2127,15 +2112,13 @@ impl BorrowWindowContext for AppContext { where F: FnOnce(&mut WindowContext) -> T, { - self.update(|app_context| { - let mut window = app_context.windows.remove(&handle.id())?; - let mut window_context = WindowContext::mutable(app_context, &mut window, handle); - let result = f(&mut window_context); - if !window_context.removed { - app_context.windows.insert(handle.id(), window); - } - Some(result) - }) + let mut window = self.windows.remove(&handle)?; + let mut window_context = WindowContext::mutable(self, &mut window, handle); + let result = f(&mut window_context); + if !window_context.removed { + self.windows.insert(handle, window); + } + Some(result) } fn update_window_optional(&mut self, handle: AnyWindowHandle, f: F) -> Option @@ -2590,7 +2573,7 @@ where } else { let focused_type = cx .views_metadata - .get(&(cx.window_handle.id(), focused_id)) + .get(&(cx.window_handle, focused_id)) .unwrap() .type_id; AnyViewHandle::new( @@ -2610,7 +2593,7 @@ where } else { let blurred_type = cx .views_metadata - .get(&(cx.window_handle.id(), blurred_id)) + .get(&(cx.window_handle, blurred_id)) .unwrap() .type_id; AnyViewHandle::new( @@ -3413,7 +3396,7 @@ impl<'a, 'b, 'c, V: View> LayoutContext<'a, 'b, 'c, V> { let mut contexts = Vec::new(); let mut handler_depth = None; for (i, view_id) in self.ancestors(view_id).enumerate() { - if let Some(view_metadata) = self.views_metadata.get(&(window.id(), view_id)) { + if let Some(view_metadata) = self.views_metadata.get(&(window, view_id)) { if let Some(actions) = self.actions.get(&view_metadata.type_id) { if actions.contains_key(&action.id()) { handler_depth = Some(i); @@ -3873,10 +3856,7 @@ impl Copy for WindowHandle {} impl WindowHandle { fn new(window_id: usize) -> Self { WindowHandle { - any_handle: AnyWindowHandle { - window_id, - root_view_type: TypeId::of::(), - }, + any_handle: AnyWindowHandle::new(window_id, TypeId::of::()), root_view_type: PhantomData, } } @@ -4240,7 +4220,7 @@ impl AnyViewHandle { view_type: TypeId, ref_counts: Arc>, ) -> Self { - ref_counts.lock().inc_view(window.id(), view_id); + ref_counts.lock().inc_view(window, view_id); #[cfg(any(test, feature = "test-support"))] let handle_id = ref_counts @@ -4308,7 +4288,7 @@ impl AnyViewHandle { pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a>) -> serde_json::Value { cx.views - .get(&(self.window.id(), self.view_id)) + .get(&(self.window, self.view_id)) .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx)) } } @@ -4338,9 +4318,7 @@ impl PartialEq> for AnyViewHandle { impl Drop for AnyViewHandle { fn drop(&mut self) { - self.ref_counts - .lock() - .dec_view(self.window.id(), self.view_id); + self.ref_counts.lock().dec_view(self.window, self.view_id); #[cfg(any(test, feature = "test-support"))] self.ref_counts .lock() diff --git a/crates/gpui/src/app/ref_counts.rs b/crates/gpui/src/app/ref_counts.rs index f0c1699f165ea8100ccdfe1facbfb8a3ac1a2d8e..63905326fe2483118221e79a57942d525c41701f 100644 --- a/crates/gpui/src/app/ref_counts.rs +++ b/crates/gpui/src/app/ref_counts.rs @@ -9,7 +9,7 @@ use collections::{hash_map::Entry, HashMap, HashSet}; #[cfg(any(test, feature = "test-support"))] use crate::util::post_inc; -use crate::ElementStateId; +use crate::{AnyWindowHandle, ElementStateId}; lazy_static! { static ref LEAK_BACKTRACE: bool = @@ -26,7 +26,7 @@ pub struct RefCounts { entity_counts: HashMap, element_state_counts: HashMap, dropped_models: HashSet, - dropped_views: HashSet<(usize, usize)>, + dropped_views: HashSet<(AnyWindowHandle, usize)>, dropped_element_states: HashSet, #[cfg(any(test, feature = "test-support"))] @@ -55,12 +55,12 @@ impl RefCounts { } } - pub fn inc_view(&mut self, window_id: usize, view_id: usize) { + pub fn inc_view(&mut self, window: AnyWindowHandle, view_id: usize) { match self.entity_counts.entry(view_id) { Entry::Occupied(mut entry) => *entry.get_mut() += 1, Entry::Vacant(entry) => { entry.insert(1); - self.dropped_views.remove(&(window_id, view_id)); + self.dropped_views.remove(&(window, view_id)); } } } @@ -94,12 +94,12 @@ impl RefCounts { } } - pub fn dec_view(&mut self, window_id: usize, view_id: usize) { + pub fn dec_view(&mut self, window: AnyWindowHandle, view_id: usize) { let count = self.entity_counts.get_mut(&view_id).unwrap(); *count -= 1; if *count == 0 { self.entity_counts.remove(&view_id); - self.dropped_views.insert((window_id, view_id)); + self.dropped_views.insert((window, view_id)); } } @@ -120,7 +120,7 @@ impl RefCounts { &mut self, ) -> ( HashSet, - HashSet<(usize, usize)>, + HashSet<(AnyWindowHandle, usize)>, HashSet, ) { ( diff --git a/crates/gpui/src/app/test_app_context.rs b/crates/gpui/src/app/test_app_context.rs index b1729d89b8591176f1fa9aa27ccc93cebdc65e8d..6d593c2e7247d6d6005b32320b2b4dd235b4cac8 100644 --- a/crates/gpui/src/app/test_app_context.rs +++ b/crates/gpui/src/app/test_app_context.rs @@ -159,7 +159,7 @@ impl TestAppContext { .borrow_mut() .add_window(Default::default(), build_root_view); window.simulate_activation(self); - WindowHandle::new(window.id()) + window } pub fn observe_global(&mut self, callback: F) -> Subscription @@ -516,7 +516,7 @@ impl AnyWindowHandle { cx: &'a mut TestAppContext, ) -> std::cell::RefMut<'a, platform::test::Window> { std::cell::RefMut::map(cx.cx.borrow_mut(), |state| { - let window = state.windows.get_mut(&self.window_id).unwrap(); + let window = state.windows.get_mut(&self).unwrap(); let test_window = window .platform_window .as_any_mut() diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index df3f8207556ced0bc1cff4521711a1468084f915..d39219e65d4b0f19e251676b0901b7a3019328d7 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -235,9 +235,9 @@ impl<'a> WindowContext<'a> { F: FnOnce(&mut dyn AnyView, &mut Self) -> T, { let handle = self.window_handle; - let mut view = self.views.remove(&(handle.id(), view_id))?; + let mut view = self.views.remove(&(handle, view_id))?; let result = f(view.as_mut(), self); - self.views.insert((handle.id(), view_id), view); + self.views.insert((handle, view_id), view); Some(result) } @@ -389,7 +389,7 @@ impl<'a> WindowContext<'a> { let mut contexts = Vec::new(); let mut handler_depths_by_action_id = HashMap::::default(); for (depth, view_id) in self.ancestors(view_id).enumerate() { - if let Some(view_metadata) = self.views_metadata.get(&(handle.id(), view_id)) { + if let Some(view_metadata) = self.views_metadata.get(&(handle, view_id)) { contexts.push(view_metadata.keymap_context.clone()); if let Some(actions) = self.actions.get(&view_metadata.type_id) { handler_depths_by_action_id @@ -440,7 +440,7 @@ impl<'a> WindowContext<'a> { .ancestors(focused_view_id) .filter_map(|view_id| { self.views_metadata - .get(&(handle.id(), view_id)) + .get(&(handle, view_id)) .map(|view| (view_id, view.keymap_context.clone())) }) .collect(); @@ -850,9 +850,9 @@ impl<'a> WindowContext<'a> { let handle = self.window_handle; if let Some(focused_view_id) = self.window.focused_view_id { for view_id in self.ancestors(focused_view_id).collect::>() { - if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { + if let Some(mut view) = self.views.remove(&(handle, view_id)) { let handled = view.key_down(event, self, view_id); - self.views.insert((handle.id(), view_id), view); + self.views.insert((handle, view_id), view); if handled { return true; } @@ -869,9 +869,9 @@ impl<'a> WindowContext<'a> { let handle = self.window_handle; if let Some(focused_view_id) = self.window.focused_view_id { for view_id in self.ancestors(focused_view_id).collect::>() { - if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { + if let Some(mut view) = self.views.remove(&(handle, view_id)) { let handled = view.key_up(event, self, view_id); - self.views.insert((handle.id(), view_id), view); + self.views.insert((handle, view_id), view); if handled { return true; } @@ -888,9 +888,9 @@ impl<'a> WindowContext<'a> { let handle = self.window_handle; if let Some(focused_view_id) = self.window.focused_view_id { for view_id in self.ancestors(focused_view_id).collect::>() { - if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { + if let Some(mut view) = self.views.remove(&(handle, view_id)) { let handled = view.modifiers_changed(event, self, view_id); - self.views.insert((handle.id(), view_id), view); + self.views.insert((handle, view_id), view); if handled { return true; } @@ -929,10 +929,10 @@ impl<'a> WindowContext<'a> { let view_id = params.view_id; let mut view = self .views - .remove(&(handle.id(), view_id)) + .remove(&(handle, view_id)) .ok_or_else(|| anyhow!("view not found"))?; let element = view.render(self, view_id); - self.views.insert((handle.id(), view_id), view); + self.views.insert((handle, view_id), view); Ok(element) } @@ -1190,13 +1190,13 @@ impl<'a> WindowContext<'a> { let mut keymap_context = KeymapContext::default(); view.update_keymap_context(&mut keymap_context, cx.app_context()); self.views_metadata.insert( - (handle.id(), view_id), + (handle, view_id), ViewMetadata { type_id: TypeId::of::(), keymap_context, }, ); - self.views.insert((handle.id(), view_id), Box::new(view)); + self.views.insert((handle, view_id), Box::new(view)); self.window .invalidation .get_or_insert_with(Default::default) diff --git a/crates/gpui/src/app/window_input_handler.rs b/crates/gpui/src/app/window_input_handler.rs index d7c65b11fae6f6c66de0c4c0a1c4302400d651ba..bdc871a80278eaf140887fa9e6d3b64077ac3150 100644 --- a/crates/gpui/src/app/window_input_handler.rs +++ b/crates/gpui/src/app/window_input_handler.rs @@ -23,7 +23,7 @@ impl WindowInputHandler { let mut app = self.app.try_borrow_mut().ok()?; self.window.update_optional(&mut *app, |cx| { let view_id = cx.window.focused_view_id?; - let view = cx.views.get(&(self.window.id(), view_id))?; + let view = cx.views.get(&(self.window, view_id))?; let result = f(view.as_ref(), &cx); Some(result) }) diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 67f8e52c04f0cdf18aaf340860d0fe9adc44bc88..1d93a45fc7bd0e58ba2fd514e9db33a5c74e590b 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -19,7 +19,7 @@ use crate::{ }, keymap_matcher::KeymapMatcher, text_layout::{LineLayout, RunStyle}, - Action, ClipboardItem, Menu, Scene, + Action, AnyWindowHandle, ClipboardItem, Menu, Scene, }; use anyhow::{anyhow, bail, Result}; use async_task::Runnable; @@ -58,13 +58,13 @@ pub trait Platform: Send + Sync { fn open_window( &self, - id: usize, + handle: AnyWindowHandle, options: WindowOptions, executor: Rc, ) -> Box; - fn main_window_id(&self) -> Option; + fn main_window(&self) -> Option; - fn add_status_item(&self, id: usize) -> Box; + fn add_status_item(&self, handle: AnyWindowHandle) -> Box; fn write_to_clipboard(&self, item: ClipboardItem); fn read_from_clipboard(&self) -> Option; diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index 509c979b8536dfde31a9246b34edd7bd0ca88e0e..277ff8403f8df8ce96984c4a6fc896ad818df6f7 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -6,7 +6,7 @@ use crate::{ executor, keymap_matcher::KeymapMatcher, platform::{self, AppVersion, CursorStyle, Event}, - Action, ClipboardItem, Menu, MenuItem, + Action, AnyWindowHandle, ClipboardItem, Menu, MenuItem, }; use anyhow::{anyhow, Result}; use block::ConcreteBlock; @@ -590,18 +590,18 @@ impl platform::Platform for MacPlatform { fn open_window( &self, - id: usize, + handle: AnyWindowHandle, options: platform::WindowOptions, executor: Rc, ) -> Box { - Box::new(Window::open(id, options, executor, self.fonts())) + Box::new(Window::open(handle, options, executor, self.fonts())) } - fn main_window_id(&self) -> Option { - Window::main_window_id() + fn main_window(&self) -> Option { + Window::main_window() } - fn add_status_item(&self, _id: usize) -> Box { + fn add_status_item(&self, _handle: AnyWindowHandle) -> Box { Box::new(StatusItem::add(self.fonts())) } diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index c0f0ade7b926b59dc3a49a714483f576f3a64026..59324f473a97a4682efc277cce5b46e916a37b9a 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -13,6 +13,7 @@ use crate::{ Event, InputHandler, KeyDownEvent, Modifiers, ModifiersChangedEvent, MouseButton, MouseButtonEvent, MouseMovedEvent, Scene, WindowBounds, WindowKind, }, + AnyWindowHandle, }; use block::ConcreteBlock; use cocoa::{ @@ -282,7 +283,7 @@ struct InsertText { } struct WindowState { - id: usize, + handle: AnyWindowHandle, native_window: id, kind: WindowKind, event_callback: Option bool>>, @@ -426,7 +427,7 @@ pub struct Window(Rc>); impl Window { pub fn open( - id: usize, + handle: AnyWindowHandle, options: platform::WindowOptions, executor: Rc, fonts: Arc, @@ -504,7 +505,7 @@ impl Window { assert!(!native_view.is_null()); let window = Self(Rc::new(RefCell::new(WindowState { - id, + handle, native_window, kind: options.kind, event_callback: None, @@ -621,13 +622,13 @@ impl Window { } } - pub fn main_window_id() -> Option { + pub fn main_window() -> Option { unsafe { let app = NSApplication::sharedApplication(nil); let main_window: id = msg_send![app, mainWindow]; if msg_send![main_window, isKindOfClass: WINDOW_CLASS] { - let id = get_window_state(&*main_window).borrow().id; - Some(id) + let handle = get_window_state(&*main_window).borrow().handle; + Some(handle) } else { None } @@ -881,7 +882,7 @@ impl platform::Window for Window { fn is_topmost_for_position(&self, position: Vector2F) -> bool { let self_borrow = self.0.borrow(); - let self_id = self_borrow.id; + let self_id = self_borrow.handle; unsafe { let app = NSApplication::sharedApplication(nil); @@ -898,7 +899,7 @@ impl platform::Window for Window { let is_panel: BOOL = msg_send![top_most_window, isKindOfClass: PANEL_CLASS]; let is_window: BOOL = msg_send![top_most_window, isKindOfClass: WINDOW_CLASS]; if is_panel == YES || is_window == YES { - let topmost_window_id = get_window_state(&*top_most_window).borrow().id; + let topmost_window_id = get_window_state(&*top_most_window).borrow().handle; topmost_window_id == self_id } else { // Someone else's window is on top diff --git a/crates/gpui/src/platform/test.rs b/crates/gpui/src/platform/test.rs index f949a6cd78e90c3f4a0025fc5aaae5ad4d251d9a..6c11817b5c14171c6934c68acfd335c9b2790522 100644 --- a/crates/gpui/src/platform/test.rs +++ b/crates/gpui/src/platform/test.rs @@ -5,7 +5,7 @@ use crate::{ vector::{vec2f, Vector2F}, }, keymap_matcher::KeymapMatcher, - Action, ClipboardItem, Menu, + Action, AnyWindowHandle, ClipboardItem, Menu, }; use anyhow::{anyhow, Result}; use collections::VecDeque; @@ -102,7 +102,7 @@ pub struct Platform { fonts: Arc, current_clipboard_item: Mutex>, cursor: Mutex, - active_window_id: Arc>>, + active_window: Arc>>, } impl Platform { @@ -112,7 +112,7 @@ impl Platform { fonts: Arc::new(super::current::FontSystem::new()), current_clipboard_item: Default::default(), cursor: Mutex::new(CursorStyle::Arrow), - active_window_id: Default::default(), + active_window: Default::default(), } } } @@ -146,30 +146,30 @@ impl super::Platform for Platform { fn open_window( &self, - id: usize, + handle: AnyWindowHandle, options: super::WindowOptions, _executor: Rc, ) -> Box { - *self.active_window_id.lock() = Some(id); + *self.active_window.lock() = Some(handle); Box::new(Window::new( - id, + handle, match options.bounds { WindowBounds::Maximized | WindowBounds::Fullscreen => vec2f(1024., 768.), WindowBounds::Fixed(rect) => rect.size(), }, - self.active_window_id.clone(), + self.active_window.clone(), )) } - fn main_window_id(&self) -> Option { - self.active_window_id.lock().clone() + fn main_window(&self) -> Option { + self.active_window.lock().clone() } - fn add_status_item(&self, id: usize) -> Box { + fn add_status_item(&self, handle: AnyWindowHandle) -> Box { Box::new(Window::new( - id, + handle, vec2f(24., 24.), - self.active_window_id.clone(), + self.active_window.clone(), )) } @@ -256,7 +256,7 @@ impl super::Screen for Screen { } pub struct Window { - id: usize, + handle: AnyWindowHandle, pub(crate) size: Vector2F, scale_factor: f32, current_scene: Option, @@ -270,13 +270,17 @@ pub struct Window { pub(crate) title: Option, pub(crate) edited: bool, pub(crate) pending_prompts: RefCell>>, - active_window_id: Arc>>, + active_window: Arc>>, } impl Window { - pub fn new(id: usize, size: Vector2F, active_window_id: Arc>>) -> Self { + pub fn new( + handle: AnyWindowHandle, + size: Vector2F, + active_window: Arc>>, + ) -> Self { Self { - id, + handle, size, event_handlers: Default::default(), resize_handlers: Default::default(), @@ -290,7 +294,7 @@ impl Window { title: None, edited: false, pending_prompts: Default::default(), - active_window_id, + active_window, } } @@ -342,7 +346,7 @@ impl super::Window for Window { } fn activate(&self) { - *self.active_window_id.lock() = Some(self.id); + *self.active_window.lock() = Some(self.handle); } fn set_title(&mut self, title: &str) { From 8e49d1419a2ec3e832fc6716f2795305f35320df Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 16:38:46 -0600 Subject: [PATCH 158/160] Minimize window id usage --- crates/gpui/src/app.rs | 58 +++++++++++++------------- crates/gpui/src/app/window.rs | 10 ++--- crates/gpui/src/platform/mac/window.rs | 6 +-- crates/theme/src/ui.rs | 1 - 4 files changed, 38 insertions(+), 37 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 507cbffad279553dea2612dbb9a898ab4358ae8b..8020147844d946ba7bb1ca307a6ee5df7445f4e3 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -477,10 +477,10 @@ pub struct AppContext { focus_observations: CallbackCollection, release_observations: CallbackCollection, action_dispatch_observations: CallbackCollection<(), ActionObservationCallback>, - window_activation_observations: CallbackCollection, - window_fullscreen_observations: CallbackCollection, - window_bounds_observations: CallbackCollection, - keystroke_observations: CallbackCollection, + window_activation_observations: CallbackCollection, + window_fullscreen_observations: CallbackCollection, + window_bounds_observations: CallbackCollection, + keystroke_observations: CallbackCollection, active_labeled_task_observations: CallbackCollection<(), ActiveLabeledTasksCallback>, foreground: Rc, @@ -1460,7 +1460,7 @@ impl AppContext { let mut refreshing = false; let mut updated_windows = HashSet::default(); - let mut focus_effects = HashMap::::default(); + let mut focus_effects = HashMap::::default(); loop { self.remove_dropped_entities(); if let Some(effect) = self.pending_effects.pop_front() { @@ -1538,13 +1538,13 @@ impl AppContext { Effect::Focus(mut effect) => { if focus_effects - .get(&effect.window().id()) + .get(&effect.window()) .map_or(false, |prev_effect| prev_effect.is_forced()) { effect.force(); } - focus_effects.insert(effect.window().id(), effect); + focus_effects.insert(effect.window(), effect); } Effect::FocusObservation { @@ -1577,7 +1577,7 @@ impl AppContext { subscription_id, callback, } => self.window_activation_observations.add_callback( - window.id(), + window, subscription_id, callback, ), @@ -1586,7 +1586,7 @@ impl AppContext { if self.handle_window_activation_effect(window, is_active) && is_active { focus_effects - .entry(window.id()) + .entry(window) .or_insert_with(|| FocusEffect::View { window, view_id: self @@ -1603,7 +1603,7 @@ impl AppContext { subscription_id, callback, } => self.window_fullscreen_observations.add_callback( - window.id(), + window, subscription_id, callback, ), @@ -1618,7 +1618,7 @@ impl AppContext { subscription_id, callback, } => self.window_bounds_observations.add_callback( - window.id(), + window, subscription_id, callback, ), @@ -1718,10 +1718,10 @@ impl AppContext { let root_view_id = cx.window.root_view().id(); if focused_view_id != root_view_id && !cx.views.contains_key(&(window, focused_view_id)) - && !focus_effects.contains_key(&window.id()) + && !focus_effects.contains_key(&window) { focus_effects.insert( - window.id(), + window, FocusEffect::View { window, view_id: Some(root_view_id), @@ -1860,12 +1860,12 @@ impl AppContext { cx.window.is_fullscreen = is_fullscreen; let mut fullscreen_observations = cx.window_fullscreen_observations.clone(); - fullscreen_observations.emit(window.id(), |callback| callback(is_fullscreen, cx)); + fullscreen_observations.emit(window, |callback| callback(is_fullscreen, cx)); if let Some(uuid) = cx.window_display_uuid() { let bounds = cx.window_bounds(); let mut bounds_observations = cx.window_bounds_observations.clone(); - bounds_observations.emit(window.id(), |callback| callback(bounds, uuid, cx)); + bounds_observations.emit(window, |callback| callback(bounds, uuid, cx)); } Some(()) @@ -1881,7 +1881,7 @@ impl AppContext { ) { self.update_window(window, |cx| { let mut observations = cx.keystroke_observations.clone(); - observations.emit(window.id(), move |callback| { + observations.emit(window, move |callback| { callback(&keystroke, &result, handled_by.as_ref(), cx) }); }); @@ -1895,7 +1895,7 @@ impl AppContext { cx.window.is_active = active; let mut observations = cx.window_activation_observations.clone(); - observations.emit(window.id(), |callback| callback(active, cx)); + observations.emit(window, |callback| callback(active, cx)); true }) .unwrap_or(false) @@ -1989,7 +1989,7 @@ impl AppContext { let bounds = cx.window_bounds(); cx.window_bounds_observations .clone() - .emit(window.id(), move |callback| { + .emit(window, move |callback| { callback(bounds, display, cx); true }); @@ -4038,12 +4038,12 @@ impl AnyWindowHandle { #[cfg(any(test, feature = "test-support"))] pub fn simulate_activation(&self, cx: &mut TestAppContext) { self.update(cx, |cx| { - let other_window_ids = cx + let other_windows = cx .windows() .filter(|window| *window != *self) .collect::>(); - for window in other_window_ids { + for window in other_windows { cx.window_changed_active_status(window, false) } @@ -4243,10 +4243,6 @@ impl AnyViewHandle { self.window } - pub fn window_id(&self) -> usize { - self.window.id() - } - pub fn id(&self) -> usize { self.view_id } @@ -4660,10 +4656,16 @@ pub enum Subscription { GlobalSubscription(callback_collection::Subscription), GlobalObservation(callback_collection::Subscription), FocusObservation(callback_collection::Subscription), - WindowActivationObservation(callback_collection::Subscription), - WindowFullscreenObservation(callback_collection::Subscription), - WindowBoundsObservation(callback_collection::Subscription), - KeystrokeObservation(callback_collection::Subscription), + WindowActivationObservation( + callback_collection::Subscription, + ), + WindowFullscreenObservation( + callback_collection::Subscription, + ), + WindowBoundsObservation( + callback_collection::Subscription, + ), + KeystrokeObservation(callback_collection::Subscription), ReleaseObservation(callback_collection::Subscription), ActionObservation(callback_collection::Subscription<(), ActionObservationCallback>), ActiveLabeledTasksObservation( diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index d39219e65d4b0f19e251676b0901b7a3019328d7..1012d7e77ecda14e9b1fcd98cfe6434a89da249c 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -326,7 +326,7 @@ impl<'a> WindowContext<'a> { }); Subscription::WindowActivationObservation( self.window_activation_observations - .subscribe(handle.id(), subscription_id), + .subscribe(handle, subscription_id), ) } @@ -344,7 +344,7 @@ impl<'a> WindowContext<'a> { }); Subscription::WindowActivationObservation( self.window_activation_observations - .subscribe(window.id(), subscription_id), + .subscribe(window, subscription_id), ) } @@ -362,7 +362,7 @@ impl<'a> WindowContext<'a> { }); Subscription::WindowBoundsObservation( self.window_bounds_observations - .subscribe(window.id(), subscription_id), + .subscribe(window, subscription_id), ) } @@ -374,10 +374,10 @@ impl<'a> WindowContext<'a> { let window = self.window_handle; let subscription_id = post_inc(&mut self.next_subscription_id); self.keystroke_observations - .add_callback(window.id(), subscription_id, Box::new(callback)); + .add_callback(window, subscription_id, Box::new(callback)); Subscription::KeystrokeObservation( self.keystroke_observations - .subscribe(window.id(), subscription_id), + .subscribe(window, subscription_id), ) } diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 59324f473a97a4682efc277cce5b46e916a37b9a..2a722cad8293797a8dd54d6854729d4f0d2b44a3 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -882,7 +882,7 @@ impl platform::Window for Window { fn is_topmost_for_position(&self, position: Vector2F) -> bool { let self_borrow = self.0.borrow(); - let self_id = self_borrow.handle; + let self_handle = self_borrow.handle; unsafe { let app = NSApplication::sharedApplication(nil); @@ -899,8 +899,8 @@ impl platform::Window for Window { let is_panel: BOOL = msg_send![top_most_window, isKindOfClass: PANEL_CLASS]; let is_window: BOOL = msg_send![top_most_window, isKindOfClass: WINDOW_CLASS]; if is_panel == YES || is_window == YES { - let topmost_window_id = get_window_state(&*top_most_window).borrow().handle; - topmost_window_id == self_id + let topmost_window = get_window_state(&*top_most_window).borrow().handle; + topmost_window == self_handle } else { // Someone else's window is on top false diff --git a/crates/theme/src/ui.rs b/crates/theme/src/ui.rs index 308ea6f2d7b5e02c222a4e9f049ce58fa866e2bd..a16c3cb21e7631feab176dd33ce11fc48f126fec 100644 --- a/crates/theme/src/ui.rs +++ b/crates/theme/src/ui.rs @@ -192,7 +192,6 @@ where F: FnOnce(&mut gpui::ViewContext) -> D, { const TITLEBAR_HEIGHT: f32 = 28.; - // let active = cx.window_is_active(cx.window_id()); Flex::column() .with_child( From fc96676662f1dc9a06d08cdcf19993fc40c6c08e Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 17:20:46 -0600 Subject: [PATCH 159/160] Use AppContext::update when updating windows so we handle effects --- crates/gpui/src/app.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 8020147844d946ba7bb1ca307a6ee5df7445f4e3..8682e6c9dd6050b6586e64b9751d50d11bf924c4 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -2112,13 +2112,15 @@ impl BorrowWindowContext for AppContext { where F: FnOnce(&mut WindowContext) -> T, { - let mut window = self.windows.remove(&handle)?; - let mut window_context = WindowContext::mutable(self, &mut window, handle); - let result = f(&mut window_context); - if !window_context.removed { - self.windows.insert(handle, window); - } - Some(result) + self.update(|cx| { + let mut window = cx.windows.remove(&handle)?; + let mut window_context = WindowContext::mutable(cx, &mut window, handle); + let result = f(&mut window_context); + if !window_context.removed { + cx.windows.insert(handle, window); + } + Some(result) + }) } fn update_window_optional(&mut self, handle: AnyWindowHandle, f: F) -> Option From 0dc70e6cbf07e70c00c99aeab775410626c6a05a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Aug 2023 17:21:06 -0600 Subject: [PATCH 160/160] Rename mac platform Window to MacWindow for clarity --- crates/gpui/src/platform/mac.rs | 2 +- crates/gpui/src/platform/mac/platform.rs | 6 +++--- crates/gpui/src/platform/mac/window.rs | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/gpui/src/platform/mac.rs b/crates/gpui/src/platform/mac.rs index 342c1c66d0cf424f95728db7065ea39fa8b79b64..92ab53f15e34dae90db9635d95eb6721c3a53ee6 100644 --- a/crates/gpui/src/platform/mac.rs +++ b/crates/gpui/src/platform/mac.rs @@ -21,7 +21,7 @@ pub use fonts::FontSystem; use platform::{MacForegroundPlatform, MacPlatform}; pub use renderer::Surface; use std::{ops::Range, rc::Rc, sync::Arc}; -use window::Window; +use window::MacWindow; use crate::executor; diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index 277ff8403f8df8ce96984c4a6fc896ad818df6f7..9a799c3a3a17767bb1be4fcdd9d7a7a217f52e11 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -1,6 +1,6 @@ use super::{ event::key_to_native, screen::Screen, status_item::StatusItem, BoolExt as _, Dispatcher, - FontSystem, Window, + FontSystem, MacWindow, }; use crate::{ executor, @@ -594,11 +594,11 @@ impl platform::Platform for MacPlatform { options: platform::WindowOptions, executor: Rc, ) -> Box { - Box::new(Window::open(handle, options, executor, self.fonts())) + Box::new(MacWindow::open(handle, options, executor, self.fonts())) } fn main_window(&self) -> Option { - Window::main_window() + MacWindow::main_window() } fn add_status_item(&self, _handle: AnyWindowHandle) -> Box { diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 2a722cad8293797a8dd54d6854729d4f0d2b44a3..022346ea67b24e99a9644b9dce77b843d05a6fd0 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -423,9 +423,9 @@ impl WindowState { } } -pub struct Window(Rc>); +pub struct MacWindow(Rc>); -impl Window { +impl MacWindow { pub fn open( handle: AnyWindowHandle, options: platform::WindowOptions, @@ -636,7 +636,7 @@ impl Window { } } -impl Drop for Window { +impl Drop for MacWindow { fn drop(&mut self) { let this = self.0.borrow(); let window = this.native_window; @@ -650,7 +650,7 @@ impl Drop for Window { } } -impl platform::Window for Window { +impl platform::Window for MacWindow { fn bounds(&self) -> WindowBounds { self.0.as_ref().borrow().bounds() }

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%0Al@y$KT_NX@dcx0VLtxX}2X*JFI#u&LG=?j|b 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

-rToxsYl`DZ2ZvE}s zp0$3lB|AGWYqfGgC0a{gl8pf9+w=Vz>K~oIsjF-t4RVbE5$KA+@@9LF)4&|t`xzVt zP6qdAV>D)l@L&Nh2uDBKu^vvX0vc@R@Oj*E?a#>_+1$6v8!S%4U9Z3%jurr>9Agf9 zuLgFC%ykEm5l*9v$GQk){DZAC2)TuV&$aXY?6Bdc?@ZU(Zh+JTBOD1#1S8rr-q@m? z*h_t{r$W-5@r>PA`A(v4l)D{N$;y{tsH=Q+n&8BTlUE8n6nRmOlI()Kc-`gdL!5*} zS(c(O_cVb?nYI-X&TaKakS{&AXF{N@Df3C7HYM|~8F&IGlzdDiN-~cVE>W3)ZouPG zoF>G&1{Wd$uib;N0+3vBaYU>pB>4E-xZpy#!zk-OyxME@=YXLfKLh7Kbe76L&Gc)p zUU*KOe?9YW^n0w%zwOkR$^*U=@=SAvRED!mQ{eW(y|L|IpuXn(|Hl9Rug1!M&%D!C zoqs8xHSw9>M`g~XA}gtm>(nP#{ARj-*`sIpuF^-YXlGUC2sT-iJHqcebXwJSE<#Wuo-pv<HVddhi>J5^&g)sW-D*eSp|$oTvZeez#yvV zJs_DYbVYY3jSdf6wpicG?35=WNoJZDV8{(#{=UibMy5`x-uN@u;9=B>&E z#w)^|K!dgYVoJME}}KP#~n{#f#pK)j31Xc_go+$Bw8e5L$jLW%HU!x@a2oMF}-IU)b- zTFKf`SuQ)bj8{=9`cWR}hrwr@ML;Z$gm^txF0-%DOZPA6pZ|m5{3ABwsy}u9g}e@4 z>8Az8G;tNieeOFmw}>B3&#BWx=eD;!9VWgE1n0m57Bq=PzZ zSt{`1n2+CUSt;#RJmoyhDF2=h+C|G`EV6OmscSkam8T)OBPM|UZZZKYCS5nf`6k=3 zn->ppkcqe^<2{q>q9fc7`Wmk~zkmOJj{)GtH3;ASs4CF(30B700kA&EH0z2`^SBXS;GK+A;$-ZjvBMhnd-O$KwTRltJsMHxLOdGZ zXn$5i#6IvSiz?}-&S6h8Pu`&R;A4_R(I3ydEm=wX8f8bQh6 zWg*q-W9H7_HL<}R z9wc+WD7WkHIP1Ts{tw;JqmnD{xY6z%I}RmtVMp&0&9`mQE$Da)>^jN1#uzjBK8z<^ zrHu)qbT_%-0lL%RHe)E`LFKjpg$s3v;^vNO#AZz?AMv2%9C;iNq2#a)-eQN@Ce5NB zIh8|^L?_X3vK>G>!e=xmqI5fk9eI+#869+tc|cCr(J)T3IL-iLOsA>7la*M?G=y57 zeWz(8U{^jt2;Wg7q2o8da$(3+3#4dH^DY8o!MLI;DKsJ1%`v7xJQoGju4QHY&yMHx zzdelcpgZs#EbS%QlIkTg+?3V?YEH!EIMI$EzJ-jd{{DHp>hEVG+J8%S=Km7v70N1@ zfIpL-LYW{+^#%s{>zF`edT?_7H#`?Yw({T3{EzKTeRA_|3;6ev!{A5}bU<`WK$7^X zz$6*8oP_eAMnDA0a9Eoze3+l+_UnMb2l>5jo}bsh)Q+s%q=Wp3gMG@G=anwlhCusE z*br_|3`cpbURval0vE`?D|pYaz-x)C06!bU7kpe-rk??q=@Hj!Dx13<-Q;|AF@U(W zT`nSerLAfUwI!?pzB4mzpSbr4c5$0f^tLFE4<@#FrNBz%6YJDMrTl9mZx_yk{h?fv!j2eCtXC_B3+x_!=Z1s@}*A%8TV289JG+o1sq~WTx=XGrz`k*P!Z>&VK}fmTQ<2w zbvTbs&~_zm%W&RSmQ^~L{l6<-n@unfR`fJ52r`Y={8wv z^s-MOn5-q75QZIG;vJ=v6EYlLxW?5{(%n~taBE*|zEc5UMrw%z?E1=iS19?Zu`??6 zBiN*Y?e;R3vU(cN5|GXL#&)Q|%a{Zvdhy=Yo&SF39{_&*csT#N%o8uz4p9+v4&3c| z8UtwP2~bs#Z(Q})&iteQ-=h8hO?CcVjoiBzEC0qG(eai5OeUCy)i}sWUL>73~4<7o|g005U9BtQw!ZM%$ z?HkN$v-DjAk0k@8@H1!l94{jB#Vpg25;{2dDbM(f(cy(rOj;1Yw)@!v0eV2dwgaH; zmPVhc1ypaT?XcDf0J=?IPPz>Oc!T8I@Kn&=c;gK`2G9anY!=C~G4;cT5BZ&U-k}#> zc!BDSfgS_MR?GCA2$ifz1T9NBBpZ#EdeAX1UzHO_FcBMVPZepPf3Fy~CvF7MnZZDt z^x{IH%i`Pk$qC1Gsj6&DL17+seZUB{Ra&RQP(4IRS4SI8*Q)PT`Fb5*ZoG{^Y1U68 zfEzm9zPCGWnmEdFT zahK`Mc3<=xP1v1bW^huAo@&o7cf(5*Gy`Om-`)5T4-kkfL9H&ATTD7fyV@sUhCEPfNP8kcDw~?u|vJ>Wjpi#Pk-|l z=yhHBHxT=_|Bt_Lc#&Vxj|_x~pd0e55NG8Z_UAj$!LIt-E^-6S`Tx!z{R{f+i?Nfb z_5ZWa->1*M^1|FO$Rs>~?|j8?y5?`mpCV`S6oS`c}VXE?)=o<>-y|)bB@+xV)3~yHy{h37!hiL7!qdLc2iqmDf4SjU6(ZQ)I;I zIZ4KaE+TlGmcj29Tv+s(jg>or!_EaS*z9+T=;IP8m^u+0Q0^kN|wd!xF&03vS^u;Cs z8dG0hUdn?94>lP|$9Q2o|33l;UNs<9VY5kqSY1<_j?me+6(}>zunIdD+KiG7jMSc* zVbG(5iR0||%@g^A00tOpsXG8%Ay?z_toSDLfhw-&lsncND+_=>g^_495*^^ou>%_q z5_=i@z6wHbjCOKJeqm9T1A1y!$P9FqmR8_Sdow)SIV=r@X$ zJp+`*%-Nlw2MJdrNeyUI^cc3;`;jv}3|fh8AboWPXQ89)!lto52@W^%*!vCg5YT1C z711Ea!0b*}=|v+lM^x(ex4H8)8W{uQmK^Ue=qcA}@JM7HI2iv!A9=p$O9t?LK<21@ zm#|anq#M34-WCwd5j8lBylzx`y$UD8h7SrS!}x0h$I@3}18XOR8wDdEPF(wRbE-tEmyQDPw{S5_jURN$|Plejt|b&FK1v|mq{v3a=E^Xh;<^{?69Vv zFGS^hBR?icCRd^D(lG)1&VWz1=Qkf?eGve<(|6Bm%oB!VMp6gBGk6-0=n;T^{JHG{ z&|3ib-FM$@H>K@u65zC8>V++!y6pfMRq#~;d7G}0ZjS)mFqu%cH~=l^-?zX0ZMJ|F zEe61wdJ6zVFO7Rj56pWhgArn@$U778Xf-% z!o{TquzV&$TmC&6K(-QO&eTrfv~9(49#QRY^B{KpX`FK>qC9Z|@WR}N=L4Zg?;uuP`2xQktU<*98@A7RI~)#7 zr|sb29fQ@8D;_XIMddq-vEKAmo_v2;J7Iu z3=Mrs?&Lcj)!?D7<*=?c#&-aH^WSOx_Er?pEfRGQV`IV>KXj#~{L3bvLhtQqm zJ?ZJ zJT>t(@(^VQkguqtewXrm)!ypes-1IXu7Ss49;PoRU8f#7`}2I2D_rG@!YjVO_t#7u z6JNHlHim4~@pkoxE_H3uw-hOff&0L>^E}&W%YGyO>pRlT^BS>7{vF&o~gHm;*h~!-$5ZEN_~&y5d%{3 z#h0w38iMWT#_bO*b2Ls#Bn_tMK-$0=!P3Hb7Y&$+18^NocO8(K%{^!D5#AWKkn2FM zJhgHp`qt!)%H8M!1G-G&*P&6^&0(~>Lcz1!GvR+7V5%7-6n3AURS=;viPyT*h`ET{K zfPWu+{6#wQgZQ8vn0B+@>FPqFG@%jHr)l!foc}u)aeSqHeE-jz^Zx^SuSNUUj@wSo z|GigV8LOL9FI|=7OUm;U`E#e!m!G(N$DX;WU0&4jB<-E6`$^MN)U!hM+6AwIK^D*O zXL&DYYLu9q>#eImnO@udie;U;*KyKj42Qe}%pe0}Y!})CSL_&{0 zUFy4@Kl$Vn(nZi-^@9fwy7S+TOSjY(Pfz|+^Nqw7RTVz#$tPjN+q6ix696|z;W+vA z6n&QJt6%-9G^YLLH^13;0JN-czx{U4*v`3}X1lme64(xa_P%XtIhA=ThDPJd4D^r= z5MPc#pTL;v3P&i;55hG`0tSIQQM#I;e#&SI4AHKKbU!9asU&#up`6hr=adYuv$!E2 zrfe8+8eyFBcz{Ej(XpYY`+BzA#X*907}n0x+y!QSsp`-+(8S-Ccd1d;Y{l+xl+;V&UId1hP)h`r6qJ>?DP)rQjWPxqRj|qbTd+cxtc8iG@Nqufx#;MSS zICwJUVGf*0U>AvLB->TPz;4K2(FX%2b8u7Bo~-V+fE2v0yDd0&@L<0(lul<~2`49D zOFhkrYh_a4OZ14_E9}*fStyil{ZPG1>|67#FsJ&BC-jyRkQ0Hr>Oa>n*Xgs` z<`eYuvW|1lT9PNIqrBsTcjb8!e+pfWJGZuUa~FmEqWx;erA{-)r3+$g?R9s78o%BC zr#z+_9OH?k-{aZB9=t}72^V7m=I|9&dS|iD;Rk!H|={5$y zmz3JJl+y>l@x~ke>?>dSO4|XzpMU;2w_^b9ii?(BeDTH3)c5b-XBDD8Bi42SJZTab z#La*j13QSX{uZ&}bq_rmnbH|Ez5YeuXk1~9Z?Te(lPQ{#0Qq!IbujXbt9 zu4;^{MP}R1&4-LLt~Mw{=ey%(&ccoWi{36^#y-1YZ`TO8@uv7|hXNmIn|>CSfRm(8 z9^|`Y4Oq^0hWDNRmEhe~PaIF(R1Tb3v;V}t2e@@C% zDR80$^b#K35IdiAVcn5qdK)K)U$YzZvfHG3 z2r*V?^cnI`slWUCE%xH`)^d~La|IgkfBw^c?(zpFn zR=lPwP-?k+kN$}iSEW+$ImdWsFuz!~{Wn;e^Z#pq^ag$K>1F7LJ9mg5;>tfLjhZU3 z6}Y44n7HJnEAnHxWf?gJS)eSP$#WH~wZ0{uOp9PhC9kY2JZi_@;SABTfzsBwJcq>M z<9AEg^~F(}QmW-E^4Ecr4=U60Rfkyhz8Zg_N2uC^2FfE%RBe0U2$V_J&=(6+U-Ab^dz+YW%n>}{98#~*)eMXx7Pa{Pj) zEHDLNSNJgs_Au7ka)cS6u<%djyyJAeMQHDeWhc8CFts>>lBl5t1}g&h#1n^g0Krdx zAA^dkEFX_-y);zWyt4BArBAyxYCOcy7^| zNrThvjBrxy+R(qTq7U2dFEgP>zi_My>dpmoLOIY-P$b$)&TDjJz%bskok?fU;#OXE z7GMlL7>lipWyZ182gsZ~7l;1S(Uc}Hv>s%qXxAMvg7dsWVU!cO^Dp282af@uP%i~U zJ#XB-OUcni9C5|YY^V;MRO3PXu3($zK(vWsJ(rk0a=B+l8Z)Ka7y9u7%4B0E06_e= zHz(pN7rrUQj*Ez{LL&p5wKT;0gR?0>I0=yik7AW_IHBse?cvIs!))-mV@Bi-uLl=Q z%}V0ak#*B3?eTlk%392Vsdlg}5G#rA~blm*RKfL(UzU{xQ{O>U?pH}|2pZQuvin7p_-xXME1XTzh<;z8a zS<&hYL#@udn^}v-Q-5El_!cD35b}>=AokOXoX5x1jmC|Ae+#~NeN%? zme>VgTTUG!7`T`~w~6@5FdB7uZM7?9sc?$@?{th_f&SUY+2?MPdLXxP`8MlWu1$^L z9qzkxIPFd(2U#3>k1c>#B%zb0-fTn&Z#43|WCo>#e3j0(UQ=ux4MI>DZ7@j6rLI8g zwgqQ3p=`7Rjj>9%qXdj%$$5lkP=X*)`B;f1pCBOuCtHK!x${Ik+Z;wG?IMFY-Vglt zJ$8?|-I8nA{gAUK=s{jW}I-4W>UYi8pu0s4wLQpv#^#9-%l3A%8= z+Z|Mum)4J4KW7XRBwon$!l=M_+Ftl>0Mmo*yf$;;@6e&$QQtvl7(AwrT>u6icH@e{ zXlb|3={j^wy08bzWY-=3Tk}TWisLrm<8rrs&~4gjp<4yIv#vDVHU7ca#h~G1MLe>< z)hpUxgLZ?-jJ~l#PB11#xqY|iWy}$s%rONmV>dwG6{UFYy8U8IsBnr*kNuT&9Oxh9 zug>dj`|V{=Fz7}AztPNg;>4~nRv9r}Vv0fl4GS7e{ziGhbsESFBP_v_R3`Zl$@c2S zd#9Cub^ZzPYytn8^G^o@xUyZ;2K;6;aG)%RXzw@0tvmnaxK(rhf9(%{&{zJA zU)sw5_R`m~G6~dZaz4w?^bBPQ>sTR;e-pB$ywtjQQNHFuLQ<}~w&A}eh)YNHmNG)e z?Nm5weOx}VJi z;481ZGF0G+`8DEY|K4W7bo+k~9Jo}{sZn??F?d$}lIzIQykSlqu)2OwgEG(wE61Ia zO9`D}S#;pG6(k&cO!=S#msU9{o>d{^AcBfNA_1~K57fKq8GH|*HZlw+HMVyn40b%lcnytLHpVM_8?f75@K8)& zTA%Mb`IU!$3x$kef#Dbjj~nh(%gtHV0^q$|nH zuokP%+-6QQ>+KF~6DRDGO0BeSR8d*9qX)L*zzjs&`i#2ECw-aX-46O`Gp#Lz69MR~ z4VcM!cMy9J*sl$RzO>0h*Tv4lqkoK+-h-&0;Ted(2VgY*+Ab_RJM9Lq#d^EZ+t1xY zAj6<9m3{?$DR{N!sbiSSCPn=z@E~dMUFF4%Vf0q`z2g>oEod)fJFc*gP5A&A&?nNJ zhe20?Nt{69rIWMWR{npfp7}pH{~xrK|8@fg+@@E%jJbTbcMSZf?{`BcgA-t5pI0q;&^2$q8wh${lhx^AUtOSa9pIKX{)BU?`SiNF0YdxnhQL|j|lk6Kfvdc45KlvTS4&wNBp_d1xF0c<9OT3wLm1DRahHL z+k}HVv{2lkxJ!ZJP+W_<6?Z7^?poa4-6`%)aS!h94k3Tu??1~?4wAigpPik#r^gJQ z;fC_?^K{F1mAtGQop;TMK4y-n;65Gz2YY((>Z4uI7EuQ4C~-`983Stxhazj_P7(TF zgiWB)1n+|NRNeH#geLJhLvAp~#gepE398u=V@sq=Bpb}sk4@)qDWlm~_2%sr>(O3L zhgmf%NK!tJh5kr@Yy_o12pT4S z@=3E`&-V|9i|!)&5)$wA_}3_|qJC5u8U)rtzBsRk zNv)Su&e?wI&7{H*o9)iRYfyx4fmru?QjOwt2(rR=wNPR(S#sw76v$45&pE83jQ z1R0qxJ-TkawskgnJ&SmU<-%N;unt_hGwBd%a5(rOsNc-H1e-JlUoRpPYpQDb@ejlA zOXLj7@F-sBpbxRnonwd=Ft8qj9`$30_!23{t{PvjdcRMVPvJk3Bp!kR7)+;`hN6c9 zT*3xL>{Q@YSiP>m#{Q7bo{Elsq1m9awTu8PrtQBK+1A_P9msWC*2GAUiySr`z0Id? z-sZN$KaN|)bs{!9nS(&FOvfkzRuj{Tk3=c%tT=X(NAXRbu06Xx2^*2ItUbuZCP8Se9XPiV% zPaO=rD<+`7_T?JuFle6Mot04P=9JW^bvqeo}9Wn*7h3xN1h`GK@&OO)=gx0wH& z4Q7M#b>;c0Eoq9G3%+?v`m_?zs2|jgb6%FcZRH*eVb8a1ysT*t z6+i!^FOCB1o&meEnETnK_n1pS?|+wphDI=xU> z3PY`Nbp?dzcm7(gZ-vU(2Uc}F1geqBVcE%J7RrkVo~ez05~9fh_=m=f1CwiQem*D` z><9C>13I!r9vh#&O0OdD6uA7T9bFMb?gkwj$KY<0Z_vF?8vdekt=f!EC7DEbxC0UT z(z-50-AA+c8UI4$9X)>_x07mZqENMCsyAQu^iT?q&`8__JV$v_OcRsW_+_<$(iGP{pj z*omVVA6H+XU6Yr*!_L#96_yqrl0es6gW0V!n~w7!{y0j(`Mq2>TVd2sP3DeF3<#^;ksD~R$|@WV+6kt)inEAZ5G}#;MElRSqqR=s_<2EXO0e0oYlvgXT<&;f%0zXeho3GyExH(}4ZLffkBNY}PW} zhR!>zhWq`k;DjdEdpEhscoy=Y3US?}lkc8cJ{X)YH67|SUw|*tT%0}>wkK zONx%0$P%`ndi?Latu8i>%Zri&(L2#8o-jzziA4ExA10JSgex5MlgB4f5VzfD*3O64 zC$v(h`p}?7Dp(0lgsv>GLayHh?&ZAOM-=Yy)%#+Yz$k8B64rGZ=&>^?f=@maZfpQa z8UjPvIMz6mm~)~N`fh*F^_|l>X(T;*4*Ao37B2DWf>|Hi_l*SUP>%*c)dbD!Tvg>y zjAAZ5^+v{rrxyA+=Ro+B2P2Y#h+)J_%oQil*T&c!I5#M(gSZ500kSa09N+CC_{%&| ztqRbnCN3w%ffj*+NlayHM5hF&;;Yojh$seihQ)ELu3?8od2hKbV# zPr%;Aid%-tlD$WM>q%eBg&&Ydp6J^VSOaXR`*38uKK9a6Hv54^ew?OsO+1$nuKsG` z*)m7-oIT;j>+TCLnCc|xA0e|LHWKYyBf!{E0GxfQ^d(&!QT%xn$@Tki!{sika3qq3 zzH_Tzf zg#ISop!ks159|BIdh7_WNX5o4P4)R4KxS7YGDRlgPaFLuk)RwSX_;$A(6^Q+dGLn2 zn)Y`+{?GyKI1gBB@h*_Wq1E*EF#;0F|hRsQPLyR zB%G<0_Y6Wp`nfb3^iL~O=#67~F87^fD^KX<4U7cZ==qT00mBKwzqEdoe@%NPn3~mj z`(hE-`KBv~MC#%8%mM#g-Bm8@zx<~s{P0!97a9*+aBm{XR7sNF;124dLa?4I%NM|) zV6lKSTnwU1G8uCu&!G1CyDbAti``BxILYx(qlbpzstt6HZee1>jLl_TbjmK*=?;H@ zIW-f@cv_jr9+)fs7pqzwM`Z_B-$wQj`&`vM4(T4w!%wvxc{|(rXCJ~yWyDB+*2%=- zv)}D1Ro9av517H%qI}EKe-b@$i=m50ilEuy)LQSQXWL|cWgPrwd$4uCF(eNAUO3k~ zYp(@>Y4D=z>BEB^owU74=Q;+!Yj;v+U;}o4V*gXpW6;XyxGHLDQx;8Y9iMJ%w-z`` znpE;AF;0uy7PKPu(^y+_Rd=bKi^Q;)rRK-|PHW!+I5Hfs0=|cVVEYt8wo7u9%9GLr z%>EP+^RY%yqvVCz#d9iEH47!*ZONwe`drA|KfY}D!T3VTNsHu>o8VM{k6VF-nTn>B zA9Z^#bYy?!Q|#OzVZIYN96}X{VZb(}0uslb@&>|PAJ0<0yx&c)ro9%Y>Yt84>;PNT zaGf=!F=m#rvHg260xI8l8#uVAe#Q!j{?-0-xYBBJQ>;}OZjjZPKQSS&wrQ)LJ1}-& z^YSdX4#| zJ`yjnXluRhsap3f&8CjygTIO;0DqO1kNw5bx#!LfR;qE^Uhu<6vY8h`oFUe}@4f@lHuRXW_-*{Ch+lN+CsVGe_rL&wKh$FBPX>RzM8E@ncO3Um-FH?cxN~U| zVBbe~p|QG|J)E64_E+%l=}tpFu4r}Xo+QEg&Xs9>?4*&*wFEh(6qTk~yw|c@3jc*mT2B&sabMdPqBGB9GN@FO=j1K6Sy&D4i4$_7_eD+hLn4XfC=eu!VT9f@M zCyuRvA6L4;InBvnNW}W-#(0r~>5gL%!vN`s)G{WxJbQo>D-_pMJ-9PcxYON_8BD&n zzvUwLeS(Z3?ULX{kHEkGqSQ^0x}Lih&DTkeY3FLSTBrp=!1>C<#S575|08>j*;5W5Km%DW$S6?T zM4R&O27D9ew_fvCllPU0OhT3(PZ0)5i7ScI4b#K&|(1= zx|7jyLG-7G4juf=E;*Pq^i-Z`sUZ1~O+{OMmh!@V_ie3GPR@Lr5yYN+B%ZG3LFcED zTz>KCK+rfNy>$*o=mu1ARo>gyU)`^NR=Z_-P z`3;$oA=v5@%V{uhoGjA%SVY=G%ECsUjr!_EXU80kPqo`s*ebPGjdbku0D8OEb9 ztTrOInq9!5w<4i6;P{8cDj(~S4*SLz#4XR-3C)tf0jh#+tTmoQ7`u#C033$zy9)NF z6eRUz-sTq8CbFUZ zH)+~qe&O=d8;QV0VD|6-%HI;fNrPY$RRs$J-Etfd^+(=({(S=T`8`m*N`gVlCm}=M z!PBHDp#8>?`xjicmw>M-OXIAwSypW+Gx>+gb>l(_%W>RzxkRvEIl2NmgwH*8E$Q1$ zp&CIr`D4BMa2%A3*0v%bloZ(tloziGj2)PqCSI20u+xhieY=35y#@sEMFLF@k?)Kw zVP7m}=;PM`y^~)`n|j2lopK27S8c?#l}U~t0Nr&XiA}9*05*QB+ZY*jUggYAo$=Ha zbJRx)zGP5D*>&uo{d2e;)C}#T*8zSa0+C`hdhj2OTXjS6m53#N`Gf2|P2}l@UTK=Y zQ`_E)xw92~V83hlF7Qb)_o$l<5KQ44@r7dL4O=uho58B3{NYXI=G{~=-5?KlH*2PB4CsnYtQy!E=&>Ph1Cp=Ej7?k#^q#MU4k{7*q|CbwD<4r zs?MqkKx?lR-)G%yZ^qWg5dZ~qOse^NJW2dHd>7<4c+y2gE%uqf1kH5e!w z>o2g>qUXN0M_B120^H-+_C)X0Q;^nIK6d3v=t8B{lFhJMbQo(JIEGPL30@JdM_C)* z0kU4CADmRLOET>JttmRj($tkfdu@RYKo`M|-r&vAAuWKJiI7Cn_(H{ z_J-#-VG4$MX<7Pny!Bvx&6)a`c$%N?o6M}Xex^V?fE}iLA7#};(&xJ{f*OfuIo5vL z)Aty&G?fc_p}DW@sf7YdJ?vW!<&p;8#i7Z6VhZLX7fbhV@O15MO1@Uk$=}@-ZyW!r zABX0znnbRqmJO8H-kzW&OfUOw zhzL~+mps+$?=to|mUCHWqC~D4jj7=GmE>1)<16U7m7kb=evG|M^8FbJ76-ul^aD35 zo(|MLoY=|_hpIG3Q|^b z9~Ay?;eC(%Gj;9CtuayWi$C5$CQekPIczI$SZBk~UTPp{n7hDz3uS}@vW7Wg#nH@Jt zVvl*P1T0U1VgI=q>82>4zE;JKf%KuwBxIoLWpmu4#_0$I``z_;xww8P)(XDuCTzYP zJGy;Du_GV(uF9A~yNrwQ!DFPD`(qfD>vUuF+^!8b3bv2yuS97# zu(%W_FbTi1#vz3 zhh}G5aA%5NiN}Nx7o+OV-b>r*0D)>w6x00C)0o}wixey1P5sDwh^~y2`i@bSu`dyODM#r%9+4|VYCj39~ z6(`Ay8F-k`O(mFosEf0;&H5|*wO<{6ag8G`@W#^+NmRW_1u#8Bc?8%0TMPgCslS^9 zGH5_)!X!8r&R=r9@ocVMbT$-kxu(U2wEgjuWN*rZ6*JtV!NGz*IdGVBs>8T`yXX4M zkYgQkQRdX~_}=uq%F#OXbK~=dN{4uLF~kG{0p8+3Hnh{0x;1($-zDdV7hBH?=MI={ zSt$qXJf|XvNu(73dHRkihuEYb)C));LS6&_^uX&Pb;39(fKE(_JAaB_tLV5+v{+jF zVPW*62_KvN%LGq5OZTaDa}1k=MyifhkF}~ZkatAyr~)y)f1Fd`kH(GztF$l((Y4IIHy=BWu1t%2S@lIh;HU4Cj_)e}A&7;aiaQU7~Ay?-=%7q)EJnzd&? zyf4l_96G7uqx~|yXrQMdt3!sIEtRyXG3|bwKZC2+KGl>iXWdzYQcso_Mit~q!(jRVtc!1F$l$TbH0ca1xN#NLt-;O@S>RoQ|a5M#;naG-Y z4>}Yg04rgpq15wWA@s-!6NhW;kdYCv;~shbl+I_rxgef#Om??;niYMiF>@)}@7rA} z_mv0>P)JBO9Lvi(qoV7XcrxKM%xpR)&A^UF!7%N7Ea3lyqm87Z6yFrsx@&fYk)vTL zeXU_CpZ62%x06rSs{OK{NY~i8tj8DXA^&0o!{lsOgdp^cHNW9RnXpS%`~4PwAegfT zh0`nAg;4X{e~>ch@e1%I4u|K0T99k=d<5%n-)yWvu3&NX2Om-z!;aS+9zdYi6NvUn zei6M}UNHkAaCovZs*w$(Sw7?Uh zvzSz2q2Ufc1XMQL&!;<>SM*jhy1%3~ToiybiFs^cbXvFFs?48;J2uW}+=5kYrML)8 z8m3gg_dokT7vqZF^%@x%9_reBTXJEiH6*pC;{GuJf%M+{r_h_YcJya?rVnTM%d^H4 zprYFSI7Th$mG>1aHqMK@cPyShyp))}IjU$7+r&g$oJ58o{{K9zf4{#2WX`AYjsHY7 z^djL8h-952Bn?gAo;n_(Gt_EsU|W-Yw2C_XB2niPFGM>U3AH)nOX%XSG^!xz!f2S1 z8ABSJ!cbFeM81Ev;xn5CCP7pQXd(Q>yCq!5w};Xc!nBh96q^R3hRWrFoPiyFpo8K& z@W)6TM3^^#M`s6We#>vVVDI6kLoE!jI3P39dw5AR<$UUuOMfDs#_|yUA-x&m1v)Yh zwhjF4PyelFoI1ffeadHWvu;6&$%*ZcVoB@2CE;X%XUm+8u#P6mzrNytug?l^g%m{Y*qHt}ZnnkaS zd|wN6_(;_Nf%;Y+uZ+*L>u-g!{455);BoO734fY|o=D4va#5PS6?8I-t7FQ06cxh6 z%8%KRAwifF6N~VUr-D}>&(+V}e{}ra>sT8NfGrgj$`^$nyU%M|dG`_jR5oyv5}gZW zG_B>gOkZ8qg=?X)9rry)=>TdRM1P>?Io0GYt+8v#x{Jn(w1w}=ImVlwS2^s~2tVqU zduf%~rf2nv>|Vzr<#7JVHO0S|LIFCSp*~p{K?yK1lea0~4345zCy}7(A@;ND$kQo@ zU=QWdn+O3_Nf&u`QRNP3d2^v}v)0`k@D7FlZRzkxkO0s&WEuf-VMCU^at9nB()pqx zQg^jws7cztOnHusFks}qmEJ9rd>v;k%aJTk^&R%Aq%jOrTQb!w6svLMT>nW-J7=e_ z$r_NmpMLTWGRO6Cven?wE;tdvb{pS-GPFYK#KxuKmv0*sl|2r zOcM#081cSFJ?QTKY0=!{ymJOBr&Yi#9FE$XwSc7QfMZ<3M&t6FA>`3p_j4IYzI~vV z_WXW*{;zEx>=^MDo94O?HDV%>Z)|;nhOzITPlQ1D+7YV?kivm`)=2kL)tuhTK>61? z6|uKjYLsY%OM%M2jZXfLxOwG$=qiS+5(FXjnZM|wQ!ojivdMh(exS-7&HqkOzkekG9vWWJg?Ue+e7{?8MEXmsNUv% z32`6Bca(WHe8Rd`r|IZmnd6|c^8y2vY#c(&~kyL4=$Ovj<+8AGQBhxlz5CB_1K5= z21aPF^3HEmizDUrb98St50Un4+V~uiMq+&PV7 zi~#C)Hk`M&W4f&HA9f=1{>xhjlmAU6-kVtD_$G-XY1YZmtFsOG?D^_D3f8Ue{XF@I$*>!lo+upRiMkl{XJb5_4$lG&Yo92rPs7 zWi+>-4?l8XreAGF>Je`pcD$tdjFEM(eNGjpUX*)=SwFc0m{`GI!NpZa2b3@7wSW;+ zlxOp)p4s~B7jTS_9Rt|$Y1mbp=kL=ggTSdDfF3{G6k!)2XI-rJSuj<7k{scIaZSdj z$tv!IG1{_I-qd8)j(nVixC3G2w z?&tzDW7Ja_LR~fGdiZ#ae?kID-a?C8$I4AF;_d}6(unn;=E}*j^ttB6mF3DM`)vW6 zUFBO~DE+ZmgWHUt(VO%~Ebl*DVI5S!^ujN|f8k6zV<6h~VWz!j&U`;TA!^;TCvil# zJi>osj2WGy2ZRkaRo=7^3&=`q1$__FMg^cihd(ss;n^beHtRq{AJ#9Dh~iSg@a|YT zRMf0-AEo@b&o|1j%D#eG#`{SSMwQJhGLYJZ){T%MEKYG%T<&?tdxwx`0q>zzF zvyWSj?lgUais7#6Jyse)(ak3A(R7??R78&BOB+Ju0MVIABV}b8&`C5K3Y2YeeG%+? zac?9O(9BKlT2M0%X#6n!x%~@wdk`C)^Vkr+XnWr{*dc|}?Q6#kx+No0kVw`N_FbN% zzp_v@Nszs1V$&6&Qij}5vHUAIbvn3nC?`$hGjI*Z15?lULv6hV($R4h)OANegPqM4 zG$RHY3WeIGT@tRk)Q49$=nq0azbih2!dy_gInvDe5l9C$KsqN&A>p((Jw9iJ<`9)C z4AsLxP81+i3HyqIYqH%;>X%NfwLNe2do#!#_PRTlgL!&JtNvq1=%_kKsEVNv>Y(CB zQ$gWD<~H=|`WF`GVfE|TT|T856G~pyZ%DZ4+Q?8o{tAOh_LQ2Vzle;+J?dCmDDh6+ z^xsq9bPwEg&e_+<897AVucF+4)Ft zS8bQK_H3t9^^KpX|4t&t?M*>WA#dFH5*LH_(MR}Ht9@rbPbjfB1v55_e$xa3&!Qwl zR#{UcJxkQB7)Q(R3lT~FD=&~c7bAn#|k`3sY;C#KPSvSC^Y}}HJbG4vR*eWkEJPF(uidBU^U$L*9RGQWA=KQqFO_12XC zoE3#zX_=ImaksgFGGv6}al96WStaEl;X|}upsc;U4Ds0&M_>ki|8!x|E0IlhyuUf? zj?K<6`4iXWlsgowj*EF5k8$vnIUr^bV z{S4=R1&v+J7e%LT*Wd5pqpN)O|}I9`J{ zPveb(e({ZW5APKA%{`+GkhAvpHjsp=&zwUF-|oA`k3S8!#w!P=U0xOZr)Bq@vF~1+ zFfXZdBGA{(P3iAWi(8ay;Gq#IHd?Ci;KT zF+CwQnhiWPa*?&arnEC|r7oZPW$;8j-5q!`Jr6syo-@DaA}{z#?^U$=WSQHonQwV@ z`cG%V%xRE4;Y_`&)*N&djif?(hdr?uKAapar*1W!B8F+B`MKd>n=Sc$)A$lX?pvMG=6dIur9fP7Th3T(*yf`e{&ID@hU|K&{>TW1U7Ft zZ2Ht00^~;RiSV{V*hi55;C&hN7^3#6$}Ur6kAXWj(%G=x-aZwD*DK;zfY}LTlCxOP zD}8X^nmZ_me8ZN&u&7H_unlz`+PgEvZmSm zFk|k_xoTCyk!)y8%AYo$$+%=EHQTJuPGO_Bi%t=bL@vm_1UWQfwzyIni4@Y0_^8ZY zg4x-jTnrbf&d_Pm1~DTE=v}sS+^XUqNSdLu-re%oL!MA(|SHvvno*BcB<*Gxr4A=hS z`g3>>TQ2)s9;EnXNk(C)7It<20iN65-oTz>Z{Y3uop-nI-@k)!4SdoC-_BuI%}p5= zQj--7-w#F#29&<5^&n#?3IqvZ~Jq@ zx7RVq{Q4;0W%;C%x*GzoHAeH+oreDR7^i?oyJi@5j95mQ2%62!y{B)+KdzQ#v$lvry0 z;6SS~F|`k*GD8obJanLe`Am|QSSORIW9djl28|SZ1gUOGMeOEATyAwj0!(gemmG*% zhbeEfn|*f}+DY{w=0XyN3d1ieH>Wz4IyzG+KEMCnF7lL@IHPe|AL4?0xW&mw!GuPm z2H+;VPqJ#q>fOO%6uMY$@}sF-A`_ly)yf!TeNmoM)lktH%~VxnFIo02=w3!cjBn)P-aR{lU!h z>A+Wn$dfN2*B;2rvRjW$(yQvL;9%%;$40r08x*(Ay@cYSab?|5)lC_^?BPxh&b;N| z1)CM#Lnw+6&z-p|;M)--9uNKkLFdn_!FE`BD&zUBUB7oEeSk|sbZ_1=)Y5Ep9Ou73 z9yta+*2PI3)Wm@PwKUzm<4Dr)>(4#RmF;;Kw6B=&@vU)v8X2EhCLURqy-0HcoCX$Smu4ELrXlksxRMD?9tqZ(vAvh4}z+kI*JmVUjh1?>XR(;1eH)Z>PhV^XlXWO#&6k`fubcF6c* zM!{Jn+12xKR!g1I&JVRrVIg}mpHbvZ{pl;o;I_ghM%r{%!iF99_Nta8xM>3yXf`Z< z>1H#32DJRGZ1c-@t8cY{Oi32kJ9@szz+@I8Zoxi8*Wgv(DETDizKmNbJO7z>-#CpN z0}@GLS*mAyWLZeNK&?wLM6cEtpy77j;LjEB#&OnrFGb7qEC|XsDZgy_Q|kmQT56rv z9ZAp>LGAGUY>sF}7HILjgF2=C3%^96^X9VU<*gV@o-xd)y?-N3gWRPuv4#;!s*oU4 zS@`%{O@(A|l{&gryi4|_lmg5T!KjVnC%0T|W%)Vju4#e!gyfHUD6Z|TU)`XF!2soi z4!?nmM@0#*#(kqmV9pTB2KrGKkj2P)asnp{0l87}l>yrmHk9_<3RSAGQo0V5lk*GR z{~Xc3dBv9-eAE|&pbP`mf(LLd)Rw(SX+AWM;5Bd{?6vibg!GI!G;-Rgxwx*OChNht zXEg8P9P|`J9;`VFhcHM5O}gOnh5%B9CdRv546eC3jA(#fX{RV(F1!jOqv;vCBH~k{ zS=$rzeV)70MQ+J@Lc7$p6uYadP;((BfGM0H4P7z5BL>L>2yvs>Qccvv?MYn=zIQj~Y4N75dVP_WC}jgFJk_pNxK& z2j&WuU<{SbT<;e1_Br0RM3FynxEHDexpaiIkIvd!a3ts5m^`ld-(}oA4Q?i<4?7Ej z4mEa&x2?S?qFjX!zJuk^iSqRm%F(g_r~HHD12rxpem2Dz^)+j*E~n)S$qtOBKM#r3 zK?oXF)Cd}Pr93#V3Wi=Q(9u-W_P3X}4d)_u1*dT&+>zwo5ADc=Bv(VIK!AFu%blj>byooA z)~P+Hx@VElP7=ycw&}D79AD=ur(CPYv~+vPe%*RvN3PhrtEEmewv#+A)2E zmgXKG!J3$L;kji~H64NUU!6?CUd!R`Pj)J|cPsqYl0Qbe39nbw=UB1fnKbUG5Moom z6?ZFhueKN0HhgK2Fbn!Dj65RN`Omktv*xt$!5j-(GnbY${SPqn=dX-<#z2Pwzp)uO zU-H;axe07Jt?h$U8o2>Fc`Lr;D zAQUShji83~x~jC29SC1&P~ez^zr-6zA_sn8;lC>Z92+Ub0S) zF=$#mJAW9DM`T)|o`n;`Na=NWZ%g&gkFW*m-S=@?B>fGppqO{3 zZ=cDfuc1TZ&2L|;1ty~&fLGPq?qcTq^Lfisw0COfGe%FoVuCA&f?V46A+duW&c`0{Q^Rb?>M$tP2f!iGb?p1B-Q zb%v}L{&gM%5}@K^pTxg0FSLU`fC+&9o{aj;wxv>X`1YR}@-yVvgarHR3{Psi9tj4} z0hS+XvORAdJq)Zhpr($it+W63vmg@)(rHKNJuI920$CVRE;C;!8CL`;xN~BPN?c{0$r%cYQ;{CnERH5D-Oj)r1tdi}ut?{!3 zRN5BRq{j21>Y{QvIZOBQoW;ia!|@Q@zoTATEwx83o&lL^g!4y)s%f*?GD_+G5vIeX0$kMJK^1zG@(hVwt6_QiyUOCl```9sTvWL#g?OKFiIogJS^P5cQ{zQeGF5)8kk{ZVZXlj2+0 zhhzSMzXs~&1-l;hoQ>ILyT60R7|XiIztX!d|JGsx#+089mDppThsq%V7idQd%-ijeKUSOV5Iv{ z*sgk!e-olYDC&9^e{g49TExX5+>ca4Gf;ED9F_GC!Rl4n8KJig`3?K5RNCM71H5zv z{{6r1Bb5!fnK`$fw~dc3J>%Jr?vICBx8aYdo@W$#KEPVo#Jv?l@1I}hJ`t6&VhMMi zMhe&Z$opJ0lGe@Vhsv!-sVN=iL^%Bp4iCJXTYiF@H==$L)rc(? zja!(yA(@@K9kL$1z0p9b@u#sLqU|-&6~{us$;2A_6P9bXi_2s6lRn5Tp+YjbsGTT_ z8Y5CTok8#k<))@ZFKJ8qeWL;8ltZ zY%|GNY7z+LSy|>himjQ1hKG8+%a+?*zb=d=y=hgD_y-?dPtW?Q`SvHW8%!YEBNO1) zlKtZ+96-1}MDHA`@p30X`I8HG#*oY7Vde?npm-bABmdC~my5D*RDe{SlhB30`HpZUjjcEu5h_B=DrhSobqkM@j`SW!Cy|bQI$3D z8$ZrePt2z2yBYA@p|;d)a~b0JweIFcbbb#t7BEkt38;WnPj|%mDh2o>O1#&p}NNntib# zlafg?FXGwZ^R35w&pIu=S0%r@lSjTYLr$eenYc7Fh#@GzA%kHriCe8Q&54W|34D%X zxc|@*X>v#15cv#~4Z`v;e~%bgoaK$dIV@`Nn~X;>_DRCKaA4;ll;gXNR>0Bh1X%k> z@|#rWB{~6yndUwt9Dba$y9CXj>ta49!26mr-T=Jz{sNw=A0GL}f}w+r2yJ^GdJVrS z#IezoG;p9Lz>uLRM=Xao)1($?IG%QZZ-xFr%uye1ZF_daGE=|oqEgUt_M8gNO$OZd zoz64}pM2iU3kn^1)ME>4Vq`ZsO~=>=E%;5+bgQ=8zS}T+t>{_;C&+Dk4I6GlYm+(= zy;ziw;TTCAl=~1)>s(vrm`^89pDFDrp;S6%aBh(Vr`!D-APHf$x8dt;<=WYx`q()V zsA{YYl-jTEbgfD^O&E9d;;rqb2kVd<5Kw;-@(9z?R z%O}Aiq}!xxE6LKrU|$a2pO%%8U~)9eP)QkLY3`YI91Sh{+{&v;yF_u|D4*_HUFXqj zN&i68FzLgA(v~{E{D|6SP5r6N({sn76TQ2;?{Ow9w`orAl_W$C5Od}sQMgamvPWK+ zx3jl=>qmc59YNCFfD6F3dVDl8$NOg*t%2G$HFsVQV!aLw9=aO99{zkD7O?R&l=Phl7s?cVE} zRWI;kw}~oo@DBBEw2XJB+5bExX^1)NFDxGQe*jfMs=kpQOdwv^n>efj8@c zc#HBn9PCiQtc@^?D!cWeR@}G8D(-IdUa&hqy&rZR5Lz|+;2DNJWF8>Su8h&T(-wDT zJtG@jx-xRo;0`N%?!EzACaF#YRrP%4iy@ceOKP@`zJ&^ukUiue9ZPm@v(^( z37HTYK^qNY(SI*5gJykuxP-%jx}!b6fbVEbwa;Jv*}Dn1R&O=d>m&m@7f1`jcjjEk z+Nj#Wk|?ANXM@cl$Zd?@oM0r*eV_WIB%l1EC`(Yz@-X~H!@u(mtqnpuUg2_WOuDjo zDDZTG^4e(gx+v&d+fFhM<*m#vIR-{`{tzywsTSr^S*0^uBLa?ft(%}9Q6{l1j_*>C z+fc7b&^GavV7qZ;mA6%CPf^e6pcm51+gTC5_A_VvtB&DX5z?M!+;Ob39RvttkDgD( z=mPm2G8Gf_R+nE9y67Xj8mx{bSIWOonp{}s)1^P;qn4VEoTB}6zUt5PDBrp0Xa3s` z0GDUVv|H(bqw&9%ku%Q|{6KsJBAM%x~XjbUbb~&GXqn@?J0I+010NeThc3c`$TTE>}mF)oFk?8g) zz|GU`EdXCaYB2yvWl(3S`gMSh9zE*Zd2;^w$3Oltw;ceOS`2_@0G(FNebPD;rj+qBtPNLtt997+cr4e7v@j!X_)A#y0!xaF7J8!rb6GJAd@Vv1FZ!)l zqxZN7IO}$`iztnK8yCe3DO-w1S=P7>HsUcDNj6~vfb2kCF4yBJJ^Gb(Ozt&RgV0G$ z_@0yDvRU0aF=VkN7|RA(`f9tS%f>I8I^SvETUPKmP>l%}TE{?OFv3~4Z*LrR*yNFw zlh_R~9LpF)M|bFM1`)lsFdTimWx$x$2Bj@CUhEW5QjZB1jT69;2c7bk_m_VDZqV@b z<%`GJ4Z^6rCKqF3BZB$#cn~y~FMt*Xj7@jS3LTUuc`ZahG-*IB%g3h!pKvCc$#Ni^E3>-n`rZ^uo(ZX+N%>N6MTzyR_Q{5s26;uj!?@Zi!9)#IqyV|qj%6J89qvS z-T8^>+%T1s$)JQD*|2P?XiO9~e!CR$GS9&(`oPVJQhES5mFFH&&q zRr4`^_4!1<(!WysoY!^mibvAGLTLgq!GDg|Ds1+ymZb%s&^j$`L7Lme$(Gvx<2=6T zc^=Vmh`kT|DjEsfCFueUTG|(NwgQ9M|E2GprJTQ1U+7yd1Y4D@G+U&;``Lm3w#fgd z#nJwveQ#H$pZq7!{HKvO*O^Q0+?N@fuQfYQ%?d4iidHezwO2loDx7~iMlBbI8t!q^XJIUauxy~3g{4ZtybY}6m$P=Kujsz8@Ah?nj?kJT!Cv@hWY`1$3cH~oo){5Msa_< z3?ecPyf%;xH?d!>NSzaEl2dq_ie$EeAVvjA zDQ(h%PACJ5K1LW;w4Ufmw6?EG{Z$rFKI(g;(R2kM;zSEtRC>_drqM?B=!aF`%7Pv% z*s=ZEY{H!=_v519_^AF;`4ayX9iUCmdeC9DIQD&$*AG5^Oph<4Lj-_Wv9ihkhVt() z2+&3*#791M;_a#+ebVBj$X>YrOa%PX;@|(*vGQ+DM^l9Sl3w*EK&utqq|lmaIsT_4 zR0QaJeSMJF7I|m^%St)be7tzS{t1e|e8>0re1+>O$-(;-E=SLhmr}n7O-2>eAxH9$ z-+A#I`ax?rRUU2v>);!{>QENFyotSo4d7WJC`yaS5JWMu>` z8gy-y_%%0L6|>uyqnyn4Kk8h@-DePE3KceU8Y>KDS?D>#wH*P_SZ6&~^MOv204)e$ z_l?>u07jj53qbRs+HUI8g6iIUDqU<0KTN8F#y{375VB{zbftS z%9a`vUtC;B+X2vm05+a|@x>SWyT?^y+1am&tPlM%o!ur-2>#44MQ16Ll!jAZcg+d z+>~(@9Tj#Km;?~-ul9Ra*s8MaZ#S%WAS@8Pz|Yffq=uh5e0IgvwBnSzhr>qfJmG^# z8QttWz0+F<3+rO9KO^9I#qhB{CX13!*l3KyLNH-b1~7(TfG|jnRlmV7j5sK-y0c{T z-ziq6o3VRIzE!qO4#;lxY5j_Cx;xw9Wsl+E6ATOQ`oX;|@{nzL4!ItmlD8OY<{jjT zGkWe6wD0#%j{p7V?r0QqN`?s16~U9rBPfHAP)=pFhuhv`yG9RdhjZOPPD;u~`M#P3 zj3Zr@8CL`aXadzs1$HAV>Kb@A={AaIrjM3oC}?5#H&4bMWj@EIysvlxgVA$e)M4$d z`nt&fWZ)wV$On?^L+6%gt^boOQ%;`0yhxKIfIIdpBb<`!Oj=9xCw^9$N7$(FX{t;n zvM(pis_v__Z?gE{`Dgl$oF=Du)Cr?~cl|DsXtr1Rr{Fu|Berq~jOs>=gwpa{oE(bg z{NJ&ae=X8h{(t57-=OzCeoW$5lU>mE(#zreW3s^yi9@9W1R5a99foCm94OD~yAIPL zkJpC^l4h9gL6QG7IMSl5&{`Q%fpPVG%3qWUFY?kAb=aqlS5wqqV{#eD`xsyLScJh~ex03Qkd#Rz@%ZL=;tL=47J1=_&&xXtblw&{PreUpAoLys zprsZApnbN$>CO4Ka_wd{iviG%0StJUZ{q;mEZyz^xLN9AZ#Mw6*{Rb^6`xl3(-DA{ zYzIJ_1Zb&E614L!Z5vFR1ZY73B@HMxQkUN-a9o8K9CC)y+!Tj_>}PYk79a~7GOjXf zj)bjnhhl46{n?!Nmhbf2g1lK!5uZ4ymJN+}Em>stfEzUrYRC=%;I6euj!7)VYv-i5 zHLs7E63-_iV6@k9=zF}$1NxzE_qC5rooa?QIJU$On&9egIKw`U!vRd~C9PZHL*fqW z+@6F}MKRDC{WG1&8?`M*eGIM|fOnevK#$dwJG`>ww? zn;9RnW=Ay!Era)Cp2Y@O=wnuRPqO*K-F#=ZDBpPeAEK~D!O#WrhQtUSMF{FW_mzv} zNL4X(nnT~MCIzO3pWU`Uip^#j~C8J5b*j1LCts_ihmOE6YJX2KIS zQ8&$SEx)h&8K1-T7&ys?u*D?$+&2@O8Gr7ybo5xo=@1A7yLyf49s6<`} z2wHj2zeSmq{M*Pj$t{gB`>Xdg+CK&SfBNUAmH(6T|G}r1?sU+dXNL2?UCaXR1Yke_ zvoKAHhY%=bFfId!eL>~o@3aiI2ggowUO=u6G*pxhGcEVPdwD7_F5s&H7~BeA?6JtO zgP>L%l2Sw*Xoe9Pnt(?Bow8800=s19M+G|(lW3{Prfh)QqKcF)DWg)~5|19I)Mo=Sujp0g&SGaES z-h1yQW_t6@H~Hj4wVMF?^V0-?=nVi8q`xW@^ldtqZYKb4kgf_qp+^APHGn<1Mf*EF zZrfe9wiCc+zgjxYi1o_uxiUgU1&RVjd2?h(5pl=gp{mX?n_~zjLD!jZHhmYbZ{!%~ z6?d@8xbJHwhpGRo`N#OG=Ze6RW`~*FDYJW@lP6a03|mje6RM=RY?Hu@BY*jN8;@*pX~(G|8!s~&F`Xch-p3*I7z0U+zg2ef_L zrfC@W{@9}Oz|Fc%H1OZ(i!>IqcU!T+1e`IYose(KA7kGZ1C8euN;V&o#s}hviGV?A zCVNH#Mx3PIkv`&N3BK5}F=F*^fRE9lPl-t!HxR>th-}vjNKm4c5cHo6nXAV&$atSZ zE?AkQ57fK$DfMR$?p@H~gng-eO;^JudK)aY&I$wOt7%m(tKDg`!rmP+7zfL^&Aroc{}W{%Il^rr zKTn(z68cDN%%!+0PjPo&&h?5-+Vg3`Z=+v+bl>rO_L(i!RVN5m?SuMt+-etxzrsns zCi0x%e)0KO`M1=Z|L-*CzfDZo*vBK_A6?uzCJH{Yf##ayKe?ks>pGJY2j8c`Oqs3@ zCeY(efMeOyF0_a9w#`Z+g$D4ZaZJmiMSgM^*7=f z_`(r@z5}4eK~vk6TY&U75pZ!43m(mfYP+f1f@%u_c$x%Ajiq=fx9N$~?F7ILlIRpz zn}s^fOtn@2{`-61`(9((z6+q;0&sHtNw2o(lJLO?AGBiv{rpRt1ZY73PZI#r1w%lP zRB-cym9P!%ImUzt*pt{IstJccgPh)%iCkOM-;`hh0V3zf0IV(3!I+h|8Jgh}5W(PhEp zUnNT4-FtRR_S2_d)OZa7W(9m>o+b-S4_Fz5A5#QHv?(@DG(uyK327d?LGC`w$q4!M zb0M1Afr&qfzOwpqH$a;_^UqMd4DlRd5(&r>I;zNs)&ATwpeIk6KK*=GyBBu5Xi!cL z;ELo(qH~{6+u~S@_y0tBaom04X}8@qTAQ{Xx_6Yi`%ISYPfl80ZQx4b>z-yi;<2mJGgrx`q7`L}0@aj|niV2kV)WlT8!CnS<` zt?zBr5elN0JlKZiqXL7&yeNnDp@8^zZ=m2+geVDAaJo~e(!`X<%Bf9^FGR~Rrqo9O zJHjTQ@Ew1?y6l9bEV5(Wpa>ahxFQndG2)1nKBIYHa}OPUiZ&J)jX6 z*r~Kxzq>;`ZSXdU(WF~;o0x>|N;IYg zUQ9FI7|!QV*tpB`QbN2B$1yRu3{+-Zsqt%$y=~)e&c7;*_F}`G1==jbq3$m3u&m^cRE9tyD;7!D zbf!qlAePZoz0Z`KMw*Fdh8R+V3miBR(H-KB3-#Gi;p`@|<|ER4s@zAwM6?J4DnrW+ zEiEt5rKZBt(MY|b#RdSjrEwn#2n^U!bB-iq?UC{Xg^`Lo9h|&bNt0qZ6n>b)Hc-T* z_Gs7eOi}dHK%JAL!XvPxrCsvCDhaY&Q6q`nB4E+7doJi~8{90acGR3PHazQ#n4l8B zp3PUwERP<6Fn*FEuS~VhjLq1&BZ)RP=^|?Qs|e1E37j>A#rP0f^r%qSUB)J!Q4(>Y zJ=j_-;(rz^VeEzxM{L^y-(i>RSuQy>>M-=9B4E>c&r8PNAl*EV1}9@vA$ar1?vxq3 zjfelgpF@V&;T|+?xEi{5=+=?n>e`f6 z!3U)8Md>O|6ajj%=Tmf%Zzy)~IQ(9Nco$(`F-LuA6^JBsAPu?LHrxq>qz-zp2c#vP z{MpqZA9zLIQI;zSeD&3Eh=t;+P|@i{~;`>qwE5XHiYn7yg_U z&nKjS!MuP>U*~!jb;{y->d2ZO+POycRsW}y=q6_>;oRrgZ!T!1LL3kLJ43ZAI>IM1 z^aL8zlXQn<`dgk=U#C3K-js<^nJmheXF`Ps$?IhR2X`Mj>A=<&A8do=)uq?2(3-4k zP!7=kcL!ep1sJ!8vfW3fGZEsNj-HQQ0P6F|^Upsowvc-Aje3E44PZ+x27p}yXxIPU zuKeFT-A({}dC7MGU~02iEuEOUUjz8=yYDvP>2U&DnfCqe-MehtVy>SS!UfKR{Tn(K zj2R-rfFl@F#FWHtMm7&6aVg;Vn1WGjyKisjaF5|wc-D3Hj}7=l*;2z#Dg_yIujVn6 z-LfD>P&rIvztzRCwVovnsA;Dc)MEysM_1QYSsf#rFbVxGP+{b6m2EbEqOkPuEWUDP zlLGrji5RRjFe5&XQ{u)qU%(kM3ONHS{&uaK0J&+fDEDf3aqkV3Uj8l%>An_Gw<3ramDkIF4 zCpc`v(Ohe%pv#HhVnF8HgF&OEcDVbvgSiKDjJ^=6tF+{DYw}2n*WiUM;YR^il{+Fo z2IPdcm>M8UnIA^Gqs$)daL5Ka>3y+z-(4OyhZXy5q>baf)86uPIHtbaM_g#f2L)X? z;VQw118KsbvW}a56`hy>ygTfavL{D&^p*B61#i{i!Gd=ZV&7=DMIO?+eYcPIHwEoU zoo#y-fEM}ZaV*81(gD}T#@Ce8kq}Of$D1*s%t5D}v;0##8Zh|d#k*tW|Cb-#OLaVc zEcEeD9w(WOz@dT?q+Nr(XgF86^ee*?&=ZY@FMajd4x6P0^Pm0si1yzC{#p6PQ3pfEq zVwwj^z9xM5>=5=Vo_Sdl=<=+>XL*byysV69wasRNkqZyeOmn2siU$@=d*13`@*=M( zwd>GJXrjkz!Hy~G7MmB{6rQ1mEb_2s)PTz|g&G8Nd%>>t)Nwn&!aYc;6%$Hk-+}Js z)X@t>*FsXy>^J|X-2%{_H{ZxoJ2u_6|388_Y8C`g1FoC>cqEOt=^E*F0^o+poEVEt z*;2c%qHSAg+gDm@w*c6-mX;dRwjhA*dkX;Aw*R+Tu_sM+MovJxjBj8?5yk3Dt;p;; zi8{9-HZ#j>)upA167%N%)#9Gi1WHi&c}VB06oQ5QNizVhk3V{q8k-P$?hSu=FU zO#(3kZqLoJ#9ad&O^DWO&fNfe&*QpSeKDBfecO>YWXPOUUv*A6Qt8`~H!X@dzVXbi z+A`9TPmCaZQE#FV5R)l-Dq=y1x9M+_<1bK#e2}+%&L{YtVgkxOMETn^j++J^w9?r_ z`%x%qE1(_YLsq9u5WhlqLmmZPDBGeyH>W2UHGSs<6=pY>B-E1Wyp2Ofu>MUa>QH~! zBniruOQ>DjMB%XZyy}P=pP2)#KnIP8YZ<0xXK1lA8pFyt89eziqp$^pUCH71!UY{cE>xIb?5?vH;IKCufP`!U`z z9t8r#?K2X)PONDuPOr-s1nRXj{HRA7f1C6FSAOmu;Vy#5mqdU0!RKBV8udGcochY0 zwig-`jwkV6pMC)>+HY!S5B#P$r0u;S@UG-s(A* z&-xvo@#4Fz;0sxr>P*V(=pD^4S6bGx6Z~hGkFW7u4%$bxB7r!L%`P(i#~2uW%we5E zhd|G}PlgT!wpl(VU(90Us{*KvySz!7K=%o48u~r-GOcautCPTDrvvf+`|tM{0QUPw zKl)MsY?A<|{O#IwZaV-5T3`V@B@nl1q}vIA8>EQnJ(%#sp#7Z6x4!kQ{<|FkXsI!C zy9MAc{^BpV9RaW%0B!qAI|tKt0JMBhItd^}5!yX!Htz%b@ zkf_oTS03&V*vx>Qku-gVV?I$f62n-MGlL*a?|3nwqx}17F19I@Yyn4CBuyZP!pq~i zPmBPF9=OdEHXH5&Mmc+9wnAzHda_Ltu(lD7@*fF$V21|AI^gw-(Yr`Lq7EhE5K`fDU&Wzh(=T<{3zu&aPT~Q zKen(#2FkQ`+DN9I(_Lbv-(WQmY~Zk65gua^+BZkr%JzIjer;knJIYbJ=$~%yhDHT= z0sOy7$4sySJR4`Zv)@Uy82;Qaqe8)monmcuUfET@DIViS6-hAW8ps_`($6h4tm?Bt z*o{K}+N464Im_dB#6e&}3A!3i8^I14A<%)N&;?t3S8Y#XcR+g2x%Op_Z!6PyMwne@;KEW>YHeqG5I_6unFBx`P=#`#!^<*6$3^ z&4gv1#pIfa&CfY4es)M&41gD2c!BIzfYV~By!P5_^7!#%uf8pqe*4?suG~+z#{h1Y zZYKb4kZkqelI;R$%=*R~Z;0&xI643Q1^~O`(t-fCiGU^qZ3h57WwIGW7gPZ!9gPhI z)1ft+(W2I?K*wz_qCRZA*sVS$H{!b@X=T(XGG#Li5mQT)K56xPrA-zCF~fIj!u7fs z-l6EsC=_c@ajS57elBAy7(%_QW#;ixKt&ECj49o(3KiLRH?DACVO7wEkOOAOhP7t1 z!oFhNk7uyr7U%Fs@f}os7{UD)tXSd-WY9V$YhoZW_%-;N8kly)p0(j6I64h=b+s|P zD#sbIWM_RzH~b`qaaxf(v!ZfkgDcyl ziV)$7rYPMJ52KU!*g``K;>;QMqwx^?55(B(T1~FC6uy+Wd=Uj5Ew97A`t8|};*uL` zpEjA;kHG|;yw7(KJzA&-!;8yr{oMEXZL-#{G9^lrLT(6^y4`tHLSvs}yJ%RAJgOti z(Wf}xFeV9zYHSGtejM$qoatw19V!zPOeD4|O51~3GISW-d1fL!zTpxtD3@v&Qt&nU zwz$g&SGYMdK>8BLBJ63vfQ=)3S)Ysl`ECJ;6)Hn6cKDF*qOgXo%#LK2=+7?yJIKG% zwXXPwULc2s37VqVxnz9Z1OEMk*Zs`Dq4fCF*gGG7p}|!p)C~j51hIOBJh_dosu=yIaz19kpa`lgCD9sI^rg?aT%N*(9k*Sxg& z%?J6COPZWyGd(18EOTZFMP4 zhRzeO(`=og$7O+1=wMKNPn7HyfOZX_1p#b}p(mfH9gnt~()g{n-s;UXAL@JG`(FS4 z$}6vk`d9-ERBX5DsnYEPzzq{_L1{Muw9oH;_q*+b+YW%Xg$0iQG$z*|fPKd6Bm^x6 zKo^Q}3jkJ5S0>+uKtn)b11i`@*&spZcvui&PTEy~zO)QRjagn8!CbUpH%2T%v2Hyw zgT?b{-dNcJJdXy5#XyW(V7(@$WcV|@RFHru3W^4iB8pFREO{Dyl-4{9B%>+2lbjI_ zBXm?;c2&mif@E-xf=&*zcu!w;hOtQd$$H-$OagxBMm}+@=DN2h3D41XtXv1u;KWj1 zJ#tjE%5AHbC#1#rR!JKzMzUBEIF_cdm}k4d=%6Tj0UwJKdZPhW_{XDg3anwSh(R~| zWSL|hGowG~tShO=1cF<)4aR79KavR|ss@k%|B@8?x(>)iqs{Uh2#&NgM-1k4Xz-pm ze(0zXAuXd-T#07|T9luiwy@pWch;C}xV!~Iw!+=B>;adZTi-Yc<+@M_oR77Of7Y$= zwl$IsE`mNM@qV^$vp=JcxZaFOx0pZ>l(1079KRh$gAoMSn zIu+T)e$H))Ggtd>Lq?+Do1}NJ4uKsn-gg}1jOE_doOK;WI$=V@#oNU(r%$M;!ZaEW zm~1s&(wMYi{k@G~elEB%2w1x#$K?VPq6gO6C66as*NgY=&_DZ~;ryd+{Nl2${D0w- z4nin8t27zPBN;@@5 zG&xhNe00ULT80ZOeDKc7>~ua!`Q(FoU(L$}J}!UPO{ix0 z_}!KLderV!FxP}Ucf@OAZ zwgvQo__&SrnmoInBZ~1(3M|nonHH5J+|MMv1%N*tK>+(rXl=pt#y<@b{F)uiNx=>2?C(OG+&;g$1c-5i2bQfNf*ZBLE)hvL(@Jb`yr4 zP!ZL1=2?wc-SvPOjrty)7Mm#?52O!<{e5%d{ott@O%mDqil9ye^qEC12gkrkO^7fk z1r8>+i=Y!QbjYT-vG$nh%L66#3T2WVy95%ea zg#6-lYp-cLHe1{1x*3wa9?>&jTI2#B8b(o=w#;L8icMSF6B@||Y$$|Pu6yvBe9U9Up3D91gd}O;` zu*?8s&oV>^zx7BwC#8|>fU|BZ_TxH80Mej$On$aIfh$DlunD%0`O3&`gEvXoydWC> z+Y*m^Jfk*{+t3*b1K@_v@L;BZhk;l@)51^+tOXw>&>Jy%MR~Q=P;(#zU?wFh*>W@o>H~XI&fGOCM`} zgBM}~WEwO?T$$M9tHE!R4W`eqpBMu_ibO01;|bl5Z@Sav?3C}TC+ELy`)>jN%(-u= zZ~Oo7b9Mel+>i)h^@pQ&q=PiT#^l;5>JUchx!H`AJi zNA#)n$)XNyhtJfpQyw5{zWRHkWB4k6&;dLMgFRpM)qchARey8Id&E!Y_~NQbqN6%0 zKC9l6Zwyi8ZqGe<1hYug}JMX;H&b#zH?HWLf0U&1aV67`fSXv*BCTjgyjr31qa5$`N z7$wcI+}kQyH)KF#se-p{>Fv!<0cOw1!(kE&*3}IjN(v4?3CbtrRs$B&LEk03B#cUe z-(%H_y{tQ03_BAnKpr%M%F~TW24kyTS9WQ*OR|i6R&#K87{{nZT~X;)dCS`h8@ami zu1Jh&1hsa1879=yeL{evC;WbTCP%>fXSA!lVXy<;+CQ5*sLzbJ7tj%G|FY=-7qB>2p4vwFl$0;}5@k96O!kJ>|=7}gkX5i1V_q)U>pL{oVUKUAMR@x%ubXhFo-kjpq_FNWo+?8Il!Yw zq;%~4yy+w-g^}jl-d$mm`u`y?-i~!@x@iIARDrh@D4PV79m-P3Oy60Pyw>1zg^mP{ zTXd1zln$yNV^;=@bR0)FVpk1J90W^+J|m#N(*q_r^^Wa+d&*9#jY zUu|4e$Jmnx_wUd@{p}I(4^vzD|BDYkcOEd=7+t2cCeCBHV;$%qA%#No#e`+(%Le;{ z=KR}jK3d=RPtN~$e(#Nb=Km|tD4$(ybnlf{=<~;FGG4VMn#=Q*ET79CteNZJMcJBf zzS1Lp*LIFll5_oSV|s-H^EiVp>NB@`uN54&{Ff?Jf z;AAo%z*PGfZKqX&Hkb5X;dj($1nn^$_j7%>s`DJYE7-ixhEU6jx4P~pRX*fr@?1yg zb~>?$(F^c=F-ofmyFS3{rXN$XsnJvl5(tc2ockO5<%sU5)OI>I9b`wJEt3Cx@4ZLu zm~>k#ZE@2cJ$f{8ZkqsTe__YS?Iger((Mj_8zhWIX^h!Y+X0{{4aqIQMGFGRaKNVB z0)SOc3UQS{c~mnn!?&)7r|Lw{#j-9tYh9Nr)4n>Qw(g!=?ZzQvaI;}R*{T&U2N}@X zRb%n`nLu9IOLcCP5&3~gEilewYX!Sx=U;I` zMYiLi&VqB{sWhbdy9hMKDF`7~gGPcjo1I~2*tTr&2_+}n`9|x*Nt0p=1XVwVmQ0iL zoqSLkV@^BskIuiL-&X$r^8GJVuZhzDB+F&ic{&CcN{mc#w8H9lg(c+t*`Bwn{+_vj z$tG&s{y(N)`~5$o_dj_YGIe5{yC>&=d-mC&7w4v_;Gh2L`6qM7!|FUZ6Z6uC1I}sOv45&aL@t1M|3CO^~~)E0HziLpe>fRMbox>y6vJqEv9nw zsZI;5-rIWf+I6Xan-0?L1i%fF%|5l&e^M52#{jAd+oKJ_mx*(;dTU| z-F0c(U7mmb`Tnj6L)#YPw*XvcusnE#Gk9j?R4MTQeL}H#)iUYK;MmE^UeTzZ#}uK5 zi5@N6oyoo;15t|^U_wB{iI7>L)&zg(O;u<3HLK zDP@#JcX+QpXNoaUCo{Zl-`=ixFy+ZJHph7L{6+u|nwLC0o6{P-AyT+CdoEi!-19d9CV>s5n<3P`?{&_-Y=0?h$!8| z2z2sSLU<&oue3jZTKWI2*YnE14ClYC{9oz}tjL%&@t}T`>y|42KAABxvjw$8UXVOt z&~{iod|^2M$h+Tv^Aq~c@3(+|m%+!UFZW*k8eKH!zatZPM+Z~V&FMWpW1=ETIbZ3P zR97v-~S|ye(J{(J@VEu44%kE#O%F=EWzUsn_s; zMF|kGjO)3!R`6F?YS~)nidMXMhHcQI?iGGS>&X#;cT89F2hs|j^`9ocRt(w}frT{- z7;8#L>oOaFb?20gO{AZ_C~RG`A-ZQ##VRu6G4&-NR_(2vucXzpQ_>)S?TWvC3xLG{ zIQdHb^R2hul1Gmoak~bv{XY3tg4eB|z8}sKZ5vb3~ilaUfY;m2&Wr@&vtOoy7|4!LhGrIT) zVB1dF4d}iS*bHektlO>)+j2{UJ28|$oNnyV=||4s89&Qy`2|QH1^lQ%Op1&zes)-b zCwslUKZI7RWZoyGkI~mleTRKr>f=(LB+kRRlj<493%iHBVeD6d_5T?NFiLGcNM`G$ zA6L-r&(=@gdraUk*>M9791?>1MR^WsFji72JLy)pEXH4@5B6c-i3#+|J9x$OvKw;Z z-_d~*fO)e?76MrZArz=ze8Nb2#PPoCM8M0=J2M}mEi227^J6@r6J#36{C9PD~z!!Z_Ey*GPl zJ0#)=%Vu;X9?t)1<^T1cyO-v-`nLb~KX;zQ%5gj+BDkF=%1`3x& z+xBn$)SUlc`~4B{4=0@3w*L(S{vEBJFU08Z9gcUd+-aRw&w25DHDH{pueN&*kE8N* zMH#u`H#~D4)xPg%%J4OxVR@#j(>YjS{6B14l^2djDSs_1SF}~1)4{W=^3xS<9`V6B zxaxZxOwZx6;F+FfB?F)jY^P^Go_j&b{u$Md>1v#eXcO{dL$8)qW$%j>YC~EZ7)%^g zH=$i1u+VhFZTBtkdA|Ye{{8zc4nX&z+Fv^&ZH=53Px;QBJG3fK)b5Kp0yhQ+Go23pnbL-09LNedXdVQ?f{^tNq7!s3?Nw^ z+>~;s+_p5wxxknb)CqpE-|EbmC(x}OH5@h%+C2<2rZ_+DRAK)}t4XA*=jR5lLwrL4 zroY@`Hn;DE8rze0^D4}-jM=Al-2jZV&b0^~@^k*SyYQjl_M(Py>M?5YL#n>W* zZ(1N{V-6J7YhEn94-}+3Y2(bjI$ z2_7%M`~0fA*yi&>b07x+90Gj}oF;BC<~)6>!dY=Ca+EE&te=u7bUnVOo3>J62p#*L z{ee5UG611exe_WCMga6_C&c0eV=C%K<7fgwC6s^3^VLdAnVB5~8OGlRVMr4>wjfSk z9F<@jI2--hCl}M+ot^NAIUP!^2q7&LQHB>T=UHi536q9Ly}f=v8eoK0Jki}yx;45MVyBS_dr1-qg_qqpV?zm{{P+|{%|P&1f#t2np{2q{6vhD z!4}WtB(I*7GkLP4cPPUMwG%J82iJt>RVdd#wIx3oLge^(sZ^m&$aQU6&# z&c^blalVOeZ1HRb(_NC@;hEi#ca`s^_gokMwkeNQfI@^=^-;;|uDkDBuDzQUSwpk7 znD~bwGC$?J>9Nahq({SPV4y~*{<1vZG5JPk2dmwH))e@53qbRVhCbE2rEv>DOCC?H zr;8Cl5d#1lr}B`VIz1Qw?vW6MvJqlC2EgtqNbLwf3uw^-TQm=Vb_Af^c{!y%A^J6d zPngCe)DU`;*Q8JvXEJ37y*u29Jg02A?-o3YgwPZ^HMl_+Kn#yu{I+ONTyG#4vblqD z`h?7V-u=jOP_WH~>tmZTm1X515*XhC=ECEPkRL$wg0|VT2#!pf7Z^t-$ROZnvw9G~ zof@4M2KL(sV~AHWlw1vE7X3(lBhTkXy>_x9x>0HO;~jXV6eMtu1z=Fk?(l`7ArxK> zc$ZCO783fi4g}tVqRNI0UZ9lfJt)MCFNoXRexXYy5G*uVlgqmY2Ze<*DY^>lVjbP&wiaPk=m~x}tJSLFHk873Xh{s}+aG23< z*h-x*9{7|ODA%_d;i>((vKez-lacUTgklN+pumPQE9v^pLLBDoOvg-u=|b8lbqk&Z zehD&Hnz&sl55;_EP8HrBz`soIfUn@=mi&8D73O<6W+p>u&0Tw7630wnARciHHH;-e zOO{4J6jw=8283;k-&S}Vk2#N7d;ZFc&&t30y>H3idF!P@2W{v7{mah(^|j^gE0#tH zndUcmEqHdJ#lYe;|0Vek2JKf!`A6Mj=f9o#zjjxIL@nE_rQH?ymV)_i1gW>I%9Apa-}>(U#}smtQst0;o^x1yFY;)CEuy zzqFpURnj-&jHE+W*XXRH?I(4;aZiQ=VI@OYcaidB7uT6o{slUr-}Fe*wStB5jIQ>Cq83WvL?5B7VJAE+mer4nnv5}LxW*@p2&18K7Tani1XH-( zbKfmV3U2&_=1Mo94_$Bo8rT?DlVob)ks{z22}68p)RBhD6g0zR9B%o}4cxeyHxJ}^ z?9LiP;Pg4%h0-`)WIo-FAt z_21V1((=TUK~Oep@`dsqB4HvZLekyOdoe zU1u4jp>c~3;(LtXe>gf5?fx@?ZdyS8cCbSGS+E`+7F*&1HY`ehIBe_83l0C2ygtM5Pm`Oo`zBHrc!Ankn1 zqeqYQ)mLBbdEma%&cigT*wc6b9GVY77n2l|9a4@)?jZ-cG(myRdXAk}a_Le}7gcgI zs2c+|->U18@iko)LwvD?9AF}M<{ecQE9JEa)%?!tf=l_LE<9t|*9Fv&sdc@WQ5UNf z)WEQ_9GEVPb>rW3UPcsGBcOL@v^z2Q9UX-5OoA+2_aV>@*itAjz=sq#032ts6TZ>3 zMN=Fv0*cm7?cf>rZoGh3!qoQ|{}gOz#R|Z(f&^FU@OH86l9ANQv>}UrMNh0Tz`eY8 z$iqk#%1YG7?z5@LMSl?_3$R8$;0a0!(WvGTgxdSW6O>q_9e7J>blm1dF#av6t_&QR z-z%OY#=W{;#IA27*qy7;|wqD|6U*ZfTyq7Qc1C z_>8*H`FN2!j)ctYDLtEMHu{h_3c4ql1J7)L_1DQuk|8KtUXf4f96iyx%}oK$o{^)o zF(aV)@0D5>95~YSAPbsD7OyM7+qL8xH)ja#f;-Jw9xWJX8$#^npS>Phl9cBEumcR? zZX;fo_%oq_h&thgmVCiSiFts^R5nLmO#{(Nynl0iVGM$V0Eva^wLg3G;xqEEzSorh z7t1((eoX=Y8~|gD-rER6hGCx8eudG`vX=pmnefx0{6F87|3HHd<^TWu2k*#FKY85q z?zqw772o+M8hhe&pR)I@YtFCo7oTo}k!Tw~xy&r1{1>6qJjuBJRiVYZrn`>c#PcP8 z(s%r~0JQuUi`Jr*@TjwMuCl+e)cB_`BdkzV@r$i&kHJ@x@#; zFR29q^cVnr)3hZVqyFx9zuS&j_h-%1n&O`QmoQuY!qS5Q;7dx)6`;ANwC`3Q01ck=_@gEGDl; z@DPI#w`eD>{^$acjeDsfIFiuRf{RL_Ppob2UCSBw@pCwx{bUhY@GFKJChqJXyJb4!1Pw!S2@p;`tSAu zFKri?At162)ZVawnL=$MfzO+=(!E;(6G{LeH7k-0E25!~h{QrNe&=r3P<$-P?vi*A zQdpqC?kOGD;djCaD>#|U^WNJST|Z;T_AlCz6p8sU=pOr^z^zJg>BCrvj~#HVbr-Xh zyY@xhqDAp#|2SvLn$42{&n@wWJnW9nW61f^=pmJdND^*(8?m=Zj@9*E_b|)x5tXtt zj(X4zGQzuL6FbmdnfR7C7~C)0f_}@#Mq*s(d*U$#o0>4+v;I-m4R{nk1!*JAR^z)! z8m>&3L1cHR{>!iZde8>y8ZT+*9v(n(WGG=tC6TYF*t|){e3}2?BODup(5;njn8X7| zV}QvE3z!4#kgI#}GL=sAE3XdaACKGTAHO@U`uq7OUj*Ok29#G{Pq+X798xgtzg!TAe9DWW z?9B0h&bDZ`i-Ll)ppvZauyB_9N; zxokxCm*lnC)L5m%7+`j2zpmj{6lwZLQr)5aT7?5#%Q9TNnrDUPJ@ku6@Nw)SeS}kZ z-&olg=lM6OLT~h8%Sh2fS=$1tZA*nAU7ZOA!H$(<(a2B{)?z8`=4vD*pqDZ3m$agx zM39V5?%N5MlBU8+ZW=+@%I*I;;H8fS_w!wZu1_1~NwJ>s&{TwSZG@3B!-~+}|Hkt@ zgW*Y?F9~b?48xK?Xy+_+t%296v?^xhly3(o5!@$sd(3YR+Lq!VSMG)&kOZhra zuU!bac4JL?86++tJP$?5kD(BsgJSHnNOCsAEpiYg&(((a*m0g%7mPc27q5AcoZry? zuE#t;?v1{CugH+V{6s^krl4R`+u5{MFif&u$5|?mIqz{4BxjDu%xgl+cWrrOAgO^qRhVFe75^|uX@#fd*=S+HjSzsFclArTfWq;rId6u+ zgyyi-U9wkSx|09j@450%sk#0C`A461K9_Sdjb><@PZm)(0-{xL_%aj8@X>(%T2ub7 zv=|$j^8fcQ%KwL#oqq&Q?PGlx<=^i3?8{8|sXvGDFBJ~(mwD-)^XQ8Ad>ODK-PDIK zvz@1oE*PQHH$Db_Ao(@hZ=)qi_Dt}U2?MUbCZu8C)hubZ-0BV&=;b zrKaQ1MyGx9$tU6g(Ypsgi<7o(qbHY*)6Vi1#|FHc(YuHAl zg!@YK0BGs;*I!pJ)Td-4{+3>N;f3~h^Z+=Ub>&%?L_&$-efOL-8nU>Of`dIRY%+zI z+8Ig}X1hAmTr%4Z|8B7h#Z1N!RB4~Ab0owp7n(aROw8ZrVufk?i=iNBFu!<50l|di zbDPQzS(kPNEd|}V@xVEq%a0(5lcJG%v;APPszpic|6ikdjotc`JV}}L-ALY5V5Y7c z;bkXSP4eow=p&HqL9pE78te?&A79Z zsT6``Dleh@+i^-JX<3Q%uLW!?bEtn%9EU#NVEl19EQ+%zokgsGW3HBS@Zxn4+)Q)o zlP&RO5$!$kH;e^{f-htYX=(TQWdQ>zh$<4MguoB#)i7@K-v)6?C6DH4nIa-N=SCe; z6?n$=UVnqm1J6d0xeIkF)mH)(^^fUi@)0ux}G&emvOZJ4nIq4JRy{Ue?;r&@zo8VZ^l_{@f zcAbj%Ppq3$IdYge;#f|8%M-qz+qFA(Z%sQ@Djv7imQt$$gh;OGdQHMnO)_M ziSW_9pPLb&-F((6X>rh+2S5vq-aG)Br}TU8y%)0q$Ed&m{qGAO0T^BL1?nL^b$T!W z+#?|ZV7r$R&p@QjZG~e1z^c`50cclVv={)5_}dYHmYN5^p#hyfd!xtK;Swm=RU!c* z1dJ-2_uN*ijl1AovTOftgEM3~Y!j2@F$7%cE|t5#DCh7e#SG8%Hs(1k21VAen-^K^ z?xZ{FII^H&?nDqP8CPsi%s+)w@rbGJ1RPQ{@!grH>-irc{MOlJUbJD2w`&{bWDW3qS(^>{& zgGi}!v}Xbjj@_*VW$h$h`{=Us|1W-TDF4~9an;|SH|2lF@dpu(wZQynl{gOw1~$cT z3Yq4=Dk=ZbpK<2@zyBu}<^SWy!DIU0qqg(^a>-liIQw$|ZuQ-!^7H$%WYZ_t#ozVh z-5G2*J)7G(tM8`zsa*0cD#ElnowFS7WGh-agZU-B9mY-W6Us z-;BV5XUj5YuyGyp7~NE6#>tBAWKo|jp568L4T)tK$SUc5M8t+Ke8Ww@F_w=aIxn;I zR^qh>zy*(-;DGTu)-Qn!YHK=KjWy-_?6c4Mo3`oMbf1qu{w zpdSI?o7TKvPk`BnG^Ymx!2ME>M)|$(ea}Fc7eeg>-P~3{ye&1$Rx<+l5dg!v7fKfY z76xQp8q(1aV2mm7k;h9c;X zi?Tl}B$D7SQgWptNQWXi@nOpfHQGvqrEqM8>GQf_S-s~`Nrg-c$aMj?eBf5q!zl=t zBC)%LXQA|ad)-)palwGG=Ym-NAZ8z(+N~(TMOfd2j0_kfD~iN5-6IWJ!8zA}+50;@ z3r212jO#Ei)WJMk4^`@pSC#KAb!7sU*FfVjl_OojNTEV>fako6ANWf=&a%Wf$4}?! zEe$dpF9LIr-Mu5;Kpzaxg{JqZ5A5qJQWj7qOW4hQD?=-L^?h;+_G*W-ClUGyV zUvgga#E_=TlofnM|0Iv^C43i%t3ejegZ1*ZIYT5B~X2 ze>s9_+JLoNGbD3EcicVmjfa zG&BQz0yr~Fnd)QOnAD>0qu~ zv&v%JR^#I7`RAXHx3~eV9RX+_0PP3>HcDH1_uY4UUfifQ zdjJgB^@i3S(rxL%0C2w)_ff(Ub+KMq+ud(O`zL?$C&;JozyH2@zINxO;(PmSK>(XY zEGLIgQC@g$;`Gi0uxGZ5<@qa7B|$-Bp%?;(Wq(YBwz7p4m;Q3M3>>yg1e#O7jvy2S zHQL1+*Q3|pF0UHI}~k6#VV*lY21_+G{7bz*oj7_ zPV-yhi+3FZhe~wJw`dr-SWmPZYkTRF_%Rs^8^gX=`b(VP9G=ykWz@q0gU%?lXj2$Z zq2!YFUn-B-jmlcq7fNWH)!!vzCMalI4hm(SKejl_%zP+d?Z45e<#-Xl=%DS@z%aWj zg~7$=LyK*JKx#V~jhf=OiIwq%GC5?89P?0grH*XQzwFc48E$p$q1-7=XmfX}ZL3OT zM5-6yER7PlLJ;v;Qn-?!7tG5P09~WeMl-?w|Tf1t5_eEzs8|DVg_-Ds@Aw}tqZ5!~cy<^4CpjRoTpS`jU2 z_JaI39@S|7tz6sr{~y}U|0iEWr#o-HDE|WGU#S2iv3%#2SI>fR^VFH@o~t*x&-#CO z&UGyp_8W@x5bI1#_@YvfYnXo{lddYppleQ`po5Z~<`e2)dC=)hrTjA z495gZ$V`&u@vRWVs33bp9#9UK`t>$=zWZ91Wx~%a){|b;k8W+o#&DH+WVM{RvS=&C z-El0;jMqDFEdcFz^8ondlTXSK07SdIrPZuaH3hQd!ts>_ zcL>B{U@W8_MHFclKwa<(mv=tX?}DwG5d*Su?UmmRr?GnsrDMRQldQ1#A$7$d!Boi| zRN!Q6)Gy`|o`atE-@b`ep%i)@=ltyVld@<_=mwg{f zj7h+uyogwZ!7L72B)TN~ha(3f5_Jl2wMEnY!7iii4$;m#ljEOad{>EU3$Z&zCj%1u zhJ~jLLDXy9#%j?P3FfYnf&XH>fP2X`nBC8zNPuqAAm9s^j4R1H?kReI7>hjb*b&yn zJn~7+bZ3blP(9-e3ur9UID1F*MdqF<7$wP(p&TT|h6g!kwp^2$UacToNZioi87fIX zQIN)w`xvt^<{NrKz<^dP`;pVYcWgB=kk|Jmz}VHm_<_bZ5(EH(CdmHWh+e!ew#k)} z0*>Z1%Wy?TF7Vq1cA0Q9R>2GQJqJT|OQ5CzOxOk7jcdyKM!!kvrG8N_Ls7>+fkUO! zTU5n3H@^pck6@P)MgkTh@hj*9ZHQElDe}%j@44Pwhcx?)IqJ*?Yb$V+o)en1?mJgI zBhA}MGIYE~TpP>v5;0KRI&kuFYZ7#~ixZBj$T$jobW?8g9 z(Sg|!{$*Wr`8tL%X2@w19f*i1=jC^drxpGe-)%K!M>4Hx@bEaY*N@pcuei+n&OfHj zmHu2XA;I&*<$9vVJi`cs=a54PzT)A!jXC=M~+BQX7n?~0FYP&`4o8SDV z;o9`y`JLZsH?8$uf3vX~>)AQehjgd(-~n)t1c9Y}vRg{Kvl7bxkAC!{{)uxfj~+eh zGr=QY_U~=?zolUrJ7Xe3&%gjp(tS+hm4&cqg}3(xHFxL7^+qNTrUx@2cWE1K$VLKo z>u=vO-o|&hg~oZ=@jiq(;d7kH@bc4YpGx0tdgKBW3+$yHA;Gq`Oe1?4mpRJnQFJd6k2DgdK%$kck}k0@O0-((t z+a%09mk#p{4aLYvySqha0kj?bEee>>tsRLq!dUieyj7on=5a~jX|NZgLGl#f)`+K~ zmu#jQ&vBLAY>bVy$i%NT^Z^max9+%)T$$suU-zR2IeAbo!o)z>hCTz?MC^YNkPwq=3bABVq zuX?)+<-dLFJO3Bu|HDrnhjFEsY0CeLXVLzRK5hNVXL+UanHum+<+z^Db9(^T2>s=kU+zZ$ zT70yYpewa2)SCyu4}S0iDQId|16^+?KBOm04+emHq;x6OVgP6nD_go)uR0O8YXIMW z|NZXX(mVi~MXPxLH20Tw4yHxKY?C4<#@!i881{pa8wujM>z)&QD?%NFpS%e`g(UIu z%(9IP!j!Q9hH~o6gfC>4WH8iR7;)ED&lQu69xhpXvPXw8@+d95lQNuL>_!Zu3Y8i_ z|J5_FvlO%NQIEv&2{jYG-=6cUBO-e02(d0WHvH|GA6l0S?m5Pq%9AA>4&EG`IRxLG z;L+%#@1O~W%a44}wR~}|S1sCTFohKwU<3+`a;Fi115dJij$83)*`I5Lz7{+ygHubUK zYD!B^;ZxJs>~j9P)I(k0o!)V4fLPK=uK(F*#uLvYI)+`~!YpdW5bWM>qNScaj0Tqc z!f_5G5sPKWeZ8V9fiWbB$7GK(yMM<~37nZvMGHI(^DO=eZc^RkjyjmZwUE@eo4F%Nfd5UO6eZDu41^Zz{w2 zR4N>|)O%wB?IZ|F%>?UK%CDrn@jNN~p1`~jU&*^xuM(=e^i$==v|3zr`e8S z&qJj*Je#Ut{?J?CIZwLyR)5}wM$YEI4e!9G^t`>wON59`NTBkcX8GC|V({KL@~Y}Q zo4GwLjlIq_o%s@0*4qhid4l=ht9$9Cms%h|^B{ow#v5-~iv!SZPP=TL_JWsPf4%5S z*1W5mo<+y5MeaUp76TG+AVdxUl-g6N*M$fRP};8o6bOxNk-O|b#5GMli!&j!BFF$> zFsB>W@RR4dc%_TK%v+gHpams0K=!PPkK%R-FNYb((G@5Sjv<%62UE4;8V~EMfs=Mn zvh2n_y26Yc{M-eJ@M6#+*uqV|*QHt(kF44i9UY}iGPqY4dD~*KLC_!YjUX|aH~^9y zrVwf!&`@}FxRRBq<&rS55ujX)Wf>r@zwK->AT8#B@x9 z8E9-MS}dFxoef9M6qIe6yNwon54+Rc9yF<;jtd!;;8UfnJ(Iy|NrnGKlAHSv#L%XRBiEAn8(EbQRl&a8ZYNQ_p|-Ao&Q&#muIesJ6yiL z{ip5B|8V;kzQp&duZn*46*HL$tj@xqmtSve|4Gtf&3@u~r!g}*kzH(E zI7G5p6p}$#yvEDHARxy=H$H#DPMsxHd9w01)u&UI+s5CHRok(;+hKar_jf6(H&k;I z0oyvuB%8!zR_dMMD#z(ED!=a#EW2!Ou|qs~yB&C1uPGH5r6Y z8ScjsxQbnu%@%8XKDlzuVRJzdcYh;=AgU0LsTzkFeAMp3*cZ>!lD@{&Va=cgGS4`Z zu%=q=CX)ED&EgCc9%ua)@eX>?=r_Tl$0bigk#}KRtD6_3MI#9?;KRS^mND+P792H5 ziLw^ED?q!Jp2{@=&3b!;? zOrAXEEX=pRaxGTOi|WZBLOb=lgklrxrIEXLS=cbz7Wm{h!)Iz-rsLt-RFcleM?aVy{~Ntnc`#k zu_bsvDAnJ2!EWJopg#8LO@bNgJ_4X)f{%CIu`9LHd=O0@<3DMpv(3#?Q8~^Z(qlT6DGM_W$?(peg@fxFLEQW7(DeSEmYPo#y8%wtp&!-X{kR5OPeE=lL&Bm!7uVZIzsj*RAbY&3{(l zrtx?Z8hFa2cY0~Zem@Dm7mb)y`Wl}{WScV!7-?e@!mWkyv@)%mLb2dd{hi$QIaqJ5 z>6y#hWLSNT4DS|uGJ2ry`iCEW82OslbUQxXHc{KTe@gAfHHDn| za0|fw(t`ouo{0$1F3NxZ-aG&wq!R6J=m#ZA6@xveqd41x-8y2fz8X+-R|J$7r8A)ST+ay@qN(_F2e&RDZSLuUM z#<^|?s$CdYcG|WglRzmSF58w$eOcr!&tYkFS0Jme;fAp5#mEJ#3)(vbVI>8~aW4`= zta{7_7DoEnTN-!lxZ_+u1p3&a(n(HsCK(}j9J~+Jz)zj= z(V4v*cz8FeH*g_Rlt%ocze;-2p9B777JHmflwp-^fJ1Qe~9&?Zu1 zDM*W`z6D$vqdM8}rtz z{GNk8rapwTfruGDAXKBh?+ zG4?%%Dri6;=*DF!M)g>sJEgy%!FJq=#vaFBzz2EazVcFw_Wv7W=btJZZvR91k2t!6 zSpC>kdSx-~54ui|gz;RZP9>vnxo$Rt)SFHDpRfA+(-!dWkGt|Oj-O7;P4R#E6*(l8 zbt?1y0LppNJ3hP1yW5gIVVzIYR%LUsCKC(rc}mYkat^PWHp-`ygl4p+sN4**#Xol& zn^Nv6-|Hf;$r?_(V;i^SL;d!Yb)419pYoJ->hyVAd-M0{vDsNOSli-3Jlo*zCXnB( zf~8S=*?{RyZMiaWJ1J}M=1G+`BI8r0<^j--Jxf^?Mtc4A*ZXEE(!1}z8}H~Ez?4Yt z0mnmnxCP+eDTCd00_`m8VgP7A`@?pZ<(qH5NlS)Evvyq!0NP>zeEjjpaRi{b$FNHu z^OlvJONA8!2;}~zOUfwQCi5oBJN=SMa75-72;-Z;m|&?bgn-m8iT}!Tn!?v*JMpUd z23!v&v0o1*==$>c?3GrCuWCnLdQNL+ZSmbGub?RBNC+bAk5q<;7jPzq{c6TONk;=Ia^F%$v!uu%I3l(#y#e$53$krF@BPIii)st1Th~RiomZ(suLJZ zv%MG@TA!PO5eoIy4E4Yk+2I5`=ZKo#ab;&ccDi=R8fyAEW)o3Tu*0n79oK+9mF+~U z7Tk@#Y#|7>GS@a@4fFuvxn<4{P+pG~Ifve8D;#*HbO{gzl;v!&;*G|;)1wJe*NWy0?4szwUGCT~>g7|LDc z_&>TR|Nrwp{I-1i8#Qp==Y8k@m&1qxo;S6R&yA`E{bFt1Dz_6v-yVjnYOuZP%Kul& zng8~@Mf?8;|MYG7^q1F{aUHF-14&Z1ehWzC9ar1kXb3tP!w@J#*HyVS|; z7lOa#`-+BcNsnIIY7yd-x2Bm^>H6517gIJ?utFwd-l1z;G5_pvJH8uz<@*U~R$GsC z7mY?qn*gkcoTf>Au)-BRo6ElP!d71BYHQIJZJyM>di7*4PF_v)_0m^rgY8(Dap7cC zYuM(YDKBns|Jg|%ZoDdw++JjuXD`3EtA6B1^&(?m{u+OJ;raG^SOEGh0B%9m#=9ybD|QHGI{K9{=hAInajlgRKUDFf z0J-aRz1t+(RNhzS?&|xTS*!9NkEJr8xlK91U{r=zVok=+nhQ0c@!Q!T#XcZ8I|cHM z))Cq^FhYph4EMlo^wowzW#q9CjAKy}iLr@SMrX<`ch$x~X?~F4+IOXR3`r|ucp13S z8xNo+Sw?xS*(#GcEDn~{mLO)vg0z)6h8@$L7GITPxuIlLiAA|he~?#XNulf5HAP** z^DL91ua^1dUB7~Wsc$U}LxYVVVgw)yjX8%CXCg*dZj(pKx52e{@D9c`4%@yZsi%6nx)A zWBhkX9-OdC7>n9?{_1OW=fCCb%Ksm}EkFPCanMA2-j)AHkK}ZLe9~k${yaW7WSH95 z#WVhHQ(k_4R=3E38Je8bEqAN~>xdJ4YGb>})O^P5Vz3?MH! zSxM$u7zRpvHWkywv%91laC~bux-MX6aG0Fav(+&=ZQ~3KUfkpawwXrd4%MI0y{CN| zUpAz`(32=Ozp~q10k%9UV19c*(47oE7co=F(5UkfGw@X+!C_0l+M#7mEW2n7cTKGP zx73aRv><@5z4n^5^Z)PwXfXiVXH)tSSe+Bggb(TI(t`oue#x-Y`uo5C`-&idPOOD8 z8)4%JfO`P+?=1$vC8@i_L^|PxYak?K)FC)2S?b{GLtGSMd??kl(Tfi#3Blt$?~XP+ zqfyvr#TumUo+L*e9Z;ODRkrGw)Rj_ljg&?G^MVQ)kbjSiWDKx$S)UjC+-${`gdB>+lo9P}XY1!TUxl0+~`8rX?a0^T2uD#8mSVOReYcPIq(PvG! z?GSEE_zXW3YFzy{tQ>AlhH=4h02tVwVkd%RC&PWc#vjR}5<)Kvg#&#tg4@!#v(J^Q z92Rq5Lz7Mxu&9(ZGs>qCEXSswV@J7(wl-3#`)^uY*(%RC*eCF1f;S@QTPhX>@XnNiYMZ&3~cl{@f)Jo=*r12*D+562FbYd64Dqu#`46Vg%p{ zBcQ#qf-a07!ysotCrazw?gnS9cP(?jSptHt&tBUr z7{uy=hc`TZ^@XAQf9o4BMvm6(XP;lozyFUO?LQEY>m-w2nTIgh8qv7X1ZI9><@?yd z8_Iv(W&PoweSA^=|5!fy#TP{oZi;_b{+VG-yzJIgr=lzuamh98ko1^$S^sU{Z2^zU zdA)l4ZmV{0!o}1d@D8Q6lh*S0p}3_N4(3+ycF#vPf@mvao?s3WA`ZBwv)-r4=)AuI909mriVy%${(t9pe#e>@z{QHy;sEq(058ga zw`?^JfOZQ&vv#>K)(r?y{^@?qV?(C^jJMc%>jFbeRy*=R+KC#1nbH08nRm#s?xNcs znuQ?P^H}b1#MyNezNQ@;DZD%s;@n~K7dHtUQ82UW^eL<2{t~;ZLx$f*RR8vRuVs>F zYjVII1dP-MtjiP3+$R_th|hZd31aFa6oX-mu`2vZ9tRMNvq3IUQh254P#L^1-T(U| z{{n%;BD%H`SQo#n+n7BB_9B>q@$z@oDgZn>?fZytAAo#r(t@~V`Z z1fskyXpj|KtpzmvcP$JY0T+>c6;?17?kZ2XE;uM1)l^U!2Uh#06T$B%LIl2m1`=#5 zv}ty1M~wX)Mji0BFbBedkhC0=N${LEaqDKvKx;x-2Sc5mb!sLy>AmHBOXRl$*4E3^Fupk zWv(X;WWGU8HjWn2e1(x}1kD_IH;m0*kMjV$&Lf{eOn~$d!MqOKIzG!eds-NfcY`sc z%n_AWzS5NcZ(Vl&U*zV;ng0(y>&kz5p(1REjbZcmd*D1k7&sM4PrX2-5N~ni|Mj8# z8|8WXqWu4Mzv}O?f9$;mr>5+{Wf|RtjHGqur)k)8b4jUU^vI*UXQN^F_yZF z+diX<#aNf@D|(opPhj)I^3hEYta_&J_%j@6Gv3%G;6# zTN&^A8trQXg03PUVA7|?Qm3&(m{=76kB2H4Xo4tk0rfRzdz@TSAf5LHqhxBym!2od2)FM(|h|n5Q zBM4w~X=$JB{7SQUU0+{!qLw~y$1>z+Ui$pKSi=m*0UlpJ*^C-fsWJyVNoj(GX3O0g z!2;wn89Ojg?pvgH7zui|o$`6r-3|6yKK-m+g>@}G5I_sCbos8A{GUIbgt;k7-Y1_; z!j#B@IeOnFhK)u25NY3}>JOHx?Jm1B!m$W`{JCXY`w&)vn2xfBgX!$PdFKy{nb0EN z>e}d;0T#;K*4-%!X=gmL+ zLV}o$`)_D9=>&!*?DTWrM)vEXBw@F`^R6uiXaB-s)o~89%f#5hR*4%^Mw`R%(G@#) zb+Jo%z>T@3$z+okkpTk+CXUg;G#j+R!{o>Cj%0F*Y~ z#dz2yO7U~(1TXag?OQyT;2nrR!G?-y0{WcXy&a8p2RCUr%7m4UPCxF}(&+K?#};!0 z#_(=H*_o@k1d zwI|kzZfM{&NdpaRjEqitYGd_Zy`DS&$n*BQAIsnWCzqZ7Pans)_xE3YRUSY4ihS~m z{m2-Y5UBe%KA%!+|EHhqbsW#q+_u~i9)5QK;0|>Vteighgsj13&fL0<|;J3l{YR#W{vuQ9jUyH7tKV;FGHeO%#ZhW+qc<#1+^;Y0qMob>yqdb9sXAN_Ja zmbonzW_3%R_7_+G$T|JqLff`iC+Lqq+iN>#?XO@KIi;bq_P?0r{pt5FKD!p&ZQIvh z?SZyN?4=ezU>l3mFZ+$-!y*OVXIP_J1zQHPh!|CxYb6MmHwX%!6s2`F`(;luzP-*t zfNj&Wc|X7O(o0<_Y90XX2tW%0_`wGs^t^5Jw59KS=Q|NJ9R`4h^yQ?7BLMeH%>osK z*@6JJNR=Gnzoo0ItLD~1>wmumpqIy07+K?4OY3)q#{{4D-5;SnU4t8Jx{(e6Z3suG z0}Bychjz&b$6XOdFhFy`3z6kABq5RNvm;}5_>Smp&va~Hld;cGY0?99M5 zl%r4pLul4GTN{drBpfaCwi(e!M?~}+F8`@0T0y23ZO+@_L9ee1%$#D3%;?;GU0`N8 zCBeuGCpm~2`U!gB9m7EOXd4--2rbIl1gYqvqZuowLFw4X{rL%-$Rk-oLh{1q%t>#e|SW>{{L3LOx;TPaY zvwtzaRg2J3Xv+IFP(@x(j0mmAB0BHd`IrR8U>m#KP5Ixn23d^ywcxkAnLE9Jw+_RC z2)p&CWrU9R#C$ZzIUmQ#OwpemyYn{qfN1cs;e`ODTuU7R$CfVid5x3gF$Dhy?)c*x zPbCIMLmYB)!WXwBC<%)j4H@%yJllt&8<&j`KkiwT_-|a@DZyeeuHIUlq0gxP{?7Zn z5iT)q5M*C{=}P{^_dMFaCBJG{{r!7a{-f7UJUi%#=cWixCQ|SR;6aPbchrCTn77@q z|BBrH(RNq!$&kEN5XGh#Z zkYd9C&Gkc_t1&&avv?+Q;N9ihlcNGkQF0YfdZrIHOrR$xFX^I1HcQ zgWOjin^@JECTy&;*Fv<_c=0wWWHJyKg2l=j4L-&20NJTe zHs61}SicIp=;vc*X2^`{z$mTk3g%UNTJnWB=E6z>pJ!x4*Cob-n&OHk=RC%%*XFEY zlZ*i%;x6mCs06dHBj1lS_jkp(XWURFicT4|4a3B=@Zv`(r8XfMLb6FT6n$&Y=^%FR z8~w(tQhJ`swT93a%pTAi>htjutKJ8sq;GKJ)jZ!GLWxw@aO|v=MFw!UalNkn=S3lQ zF;zm)6%tZHp%5zqH~J?;6M-LJxYAvj$|?1q#u4;Wl}!WTXJ3gP;30u$`@y)cQ3n)M z7=I*|M@)9N>&!-qL^6X7fRm1-}s^ooZz+#Lsb*ZiLH47HY$J})CfrCG%)jk z7*pZ8ERkt0FsPO>f_pg!M`OIA9VqWmG-m@w0FQYK9B*lyV0uuVhbE#ay@bFM=j~hG zeU~sxsVnIl{WW~gTS*Sf=7zJFx1J{g+G#bu^eFmfbZkT-M#|<2ck?*lp2yXxy+0Ml zUP0zn34D(D1*0u!=hjh+8zpGhIN!PJ!h z-)uYoA3u({-waUOD~~S9|Et;7{JHv5k+Q~G>4q@kCZ|1GNT;@BYEu^F?1nu2Oc#0f z8_Mb;pG^5!@R+}!;b6{cX>3=Kx-RJCa@}FEB4>m$r;DbH>J>TSi-DQT&48M$X<#mc z@B8#(g{!%a`P``7v7Hr-a$9F(yXw14^{?nsPhh!;PUR%8E$W){&TXI3EA`8$3^!jk zs15`o8RJU^KXG5t+7vdsygt-5vHy^sFg+Lm?wR=PW-|bM>s#N7so(Cfgd0msxCNkj z09>qIJI=o}cNnJ_5Nl{XwZ+Dr(CY9OwvmwkU)0}mQ@!SR5E3Rj}jG$D``JkLcU0{ZznqHWX z8FcWqy3B@`Ju!Uqci5?ea8RuM)Ml?|N6Z3=-SsjiHg^Aqo4ZC~o9HI+ZWh95Fn`}A z+~PVkDLd2yCX3NaV}TwPxUtdUyN_l?*$st7SAz<;&1Ls&o0EE<@gfZZyo+XuZ;_(E z&hFN{V-LK=u8a43zs}Zi?msQ+l1d!WVvrZkYD=X{^aJj|5$&7cPkP)3eb2OnIw^?L z7``egmT#(czDQOyD@X}O4j5d1khUIbz^Pn5>tY7=%t@5CXpjK|9`Xj*o@nJU%sOVZN~eb%t`^j|L1JvzI^`T(&Zw2L4QvKiN1QWw~2D z$|XiD+VgSp$<>N&Ft}jMH?4xMkwL(!B871p@ET8*0gvO!+yIX2{YKPlqGgm19y!M7 z)fb_#{DM>c+$WYd<$ct<W4=ua1L==2V7+ajM#&$+o+B$DT2e)BCCnk(-}+XSQ3wIrU2OzY$V7F+x!G1fe& z)K2OVsrcIX#gunn7I3{-(?lec4SP%5DDUw&WGq@DMD zz5!ssk=BOSUw^%SZ=0rV^YpE^-qLmpKnntR(XXuOSMAs}>0Krd>8aC$0pK19N_!*5 zru_R~5Oa$G(1^GtTy62%Yp?asi`A=73%7!GkAMgQco(J@dBzkjOrzH*sR)UL(3f*E zU1ejp(1kVCWDFtX4~-cl#4~0LK(OGHEUBYeK zO5Xuv^f#n%$+6%?(S;Tf3#Fd37->D}4nL3;JJ)EK5t5Mh#mGq_7PkNkh5{PDvsoW<9xoGbgz?r&1ACdXegajFF?3VNm{9QACc)k(+0!J7ZM6Vx0 zuY@88qy?-R|Aa9p9!c^d35C{j=b`^Qwu058*$;taNRCQUlJJ1goQT8lG8q>{Lx|-o zKykHT%n$G=voQW(t_1%!3tR}%h|!p|w;N)1$e``M^H0h@Qd9nad{O?}b(SsYAA$vr zBTDY+;q|l8DCUibusJKMwxCa*c34Z_e4VcPbM&R#{}+x2H;{bQmH*lRRhmsAU|o4O z12@+p5{e3jvvg9WE_7#Y%k=xEXZ&3k`R4CRp9in3MZKG>VYZVps65FHPZGSncBtnw z@a;5ov7s1$Q4g_-gCT&+oIO{$8HfCC*?*nNTCIc2$)fxUmK6>1C(q0k!_X+MJB9?n@BG>IFh0v6*3+m-cRCu0 zHQ+kwY$sW3(5R9TQ6$^Gjhm6S|$gCBrHO~tBK>}x-_}D;ZA8^B)R|`3Tt9B$=%eBHiQ~L;QGk?P?_w~DfkOck=$j_ntlR?!;br1=?39lM zgZ6ccoz?8u*yUBCX-2#x?+74L!|f=hFHJ}oQRJ( zjvBbM!$Q^Y?ihnG(5w!trGbhol#0Kxi|&s=kD3M!HbfYZ?J(y&)&Qs&hJ38y9RefR z9yF9nCh)2RX7v9mUdOxbFz47HkN`_Tw7xiug6S^!T$MXZtM=x4RYFb^Sxs9_?>osgW~^C*H}lacaoG#J z5yll>?|bo0NIp|qKSw=9zL{twWd2!ZT;Xq#$O}OICbV`lntu4Vxus|MXx0xL-QV*YAJ-`{uU**hTqo#{l|^%g(KB+lX8K>Z`BzAb@lP zpyw|h08g59I)4@nL1Ye=k;3uF;hS2b;3|F%6x`kw+mSXFw)X!XyE3DeE_7Nwhq{`d z%I_A;xCm_7g(B$k_w1B2LuX7z^(_}#|J15k#tWl0u-9$tL1B0cBL{PjZrTEvY6ga& zIml!nXedQm4HPC^tH7J1k5^YTlyEYRaO|-|mWH7?Bi|Q|4RP8>UGNxzA}Kj`{riTU z{M~!P?*CG(+G0j$&vL+_bdooG5t^|e#m0fZ-|2i>D2=shhd~QWP^vBRS{@59$Hy*t zU>T9nEnVVJbccZkyMI0=w&xrecC+D?5ohhq=ObA+dfnc+j4G~S2%sKCpA!Lu8_7TJ z2Flp<$>mufjh)sIP>f_zX&(;j#*az zX;@|A3+34=FXxx3?CQ5=zYgz+R!+-v;{5Zo`H$9NIpOuEec^XUR(f8i-BcKyKudn+ zsoym(qq+Ub|BKlZl2Fpd$7TkDN*b1X{#;4RKJOYC2sP`8vP$8mQxWEVKt~~Ia zzD8w{ws@91YZ^knWMqF6$$*X)k+_Zf6&I%GxLvvMzr}gvF-8!CTh86~VBF?|+pb3J zii1GeQaalU433Vqdaty(#cC>j{v2g-Ttq$M`Cb-iOPq^Txq^TASnN&^pbHB;j(o;T z6!KsJ3qSfC^q?gL-XvV`?K<&0b|SR|bmKI3I(k3=n9Rp9PY8QG znmfN-Hu@$~7WD!f2956u`+=0!oZd|^KhRh2Rf7>;E-|K_&#(Kl znNRr-7#kcKkDDT~+nfB0^3sti9{(Zm(K&L>9mn9);ydgVIPhxIRIg??J`O{%w1?Ac&0`6 z0X{qeBuNN!3ano2c!{gb#n&c`=9(H5C6W)@~Xu&j@7`aYuE}q%c-WiNj z_fE?n;9ERfwJ#G4{d3H#!3calV1p&Ri)xor#Dd|R#(VAygXQ#GHbfXUg5gldO?}ss zey?zLhRZ`>Bb_=e6;`GN%D#l@3>IVv<#M8J<9CblN@dRK?)h|0`}60jyy>C30_Tdx zO5U1P7g_r|eNH`5nXVfA5(Kun|A)Aw6+= z@BsJ{((nKN?{{~U3xPHwZN%Dw0c!IA_|cDkWY^c%-Lmz@8*lU}`Rc19Vs9f{oP%j8 zJOE0v#djC8VopuxxECBgl?AP}sa75xJl};fl`IB31dHngH{QJO#zshw*OoYoNt~X`*MEwFbXjv%v1KFB-d3 zrOAPF6G?9kkJ^pVQMc6klL(~dHMcz1UAYHr3FB^bXpM|P5Ii*QEJSa1hs%<(ymQ_C zUX0pds`QSy02S`Cj+9v;Wd(M|7sZ$q4ypwb#Nya}5J31OCk$|X*BND1>u-^CXWz4} z5V+wPK-h_1lL86q+h|d247v+1fZRnM z`6$ z(XV+|I^egH;`D9-W_f7TR`lKZLpi#(GU&-L1aHYV3+e-p&S60BDu=F4oK^}GDJY$B zWb|F6Oi;>}JX_Y!Z~UaOHEK5*Tjnq8lvOyQJoP8&QIC019|Ww`m>=*XNBR%pZ_3Yo z5j&@iV}+HuujnwwVye%qjL}hU&-$>=smCxW%{wuIXJr>OKr8s*sVi=L28n5QDvl^7 z7}K;dFj%5XP4AG04}@#YW2#2p4t%r#7}Dpo2njX&Ai_x59wa%!2ocN1Ooit z_r3>fRKKh8V$teWD`b1`z4z?$*S!F^d?Wrg30e$*w)=0!_l=1h7;kwdAxL9!$XzI! za%vO*-{o+x4=rY?0PVq4@=UVlwcHKq0$6WsNWPo@4vYDs2ZFZn#_PwPOWcR7$5N zQEwaMaz*G4HZa_028kZral#6{W2ap!()Tb@IW=;pa%B#@57TwBNuSkri9UQZnf zfHNoo5w-0A4ZclSH}7#Jg7OvRazV@tsl3s$uINuH52?t~s);uCL?p&B6m+jO=2gs3 zf};K2;QB2=6x(=AMk0&4S)mC0S~dTUnP6)I{Ae*<@pDIMPxxOAEZSKEE(na40pfJwC8iSce65vazxF}@_wcm!q4 zAb>r(Lu1z3Bfb&S%v@>pS6f8P^S+~X6~9?QW9J`G!;LZW z2YE%GI-lJF=E#Z(U=};F<;2Hoxd-~Hs583@)3fivwCACy`PnZXO9|H4qW!n4{#FPzlfszhcR{#T^Oo#W z9o4!cRe_n?q16g>v|Nk0O{(iqKjoS87uG{WTrfTLfuHI8UF5W1tE$C!_#N)-sm1Xx z=2!>3%82(c=1!@YXr5u4;hFlj$|q9$q%>)PK%+WlIykt!-2@Q7(`mfuIX^DXm^Q5T zv9xb;gh3ZzS*_csjX4Wwy9~6-k(L&8#N%rGNqG*i&Gl-brIK?(nfbBY{d!M6;;{F1 zpQoO$5|F103%~=djSa|lNh7Bbl*uppZ;kD?sb4ERwv@QySZ9~b&w||7UVE(!{AB~x z{2D-Oo2pH>YPuGJ0h(EzKo9AO(}MxvOG=1H(L4ZfXC+dzW(iHXk3RaSf3_n4QymK~ z6>k@xPXEM%*mZNv5)#4%?m)>n`$R60w%hya{vUz2BzME(Og!8r54$A3!z#DUPz}cE z%}BWsQQ0k(+;wGMEKH0J?WbTpF=-h)nxp7W>y;5Wz^R3hCxA_8JyrD51pr@EG+>bM zlwgG$#+2diYG~HMFxolq2u}RCQnV#@WT!=Ea}6=hD~D^BNk;b{@D$~|u=}Q5?9@-q zv4t>U8f}OxlsXIh27xyf*U&=@bdn23szM^+F_2YN+!$cC5-id9&u9tqFLAD&a`Kgs z>9(GRFkB_ZyV-#&Uf*cFBxc(i;I7FSkvp_e-)4@EBM>x`#`|3m9ecjQgmy zxSo3%n%F)zNpAtaS;@we+mds{c*Bzb_#Bnx-06MsD*ExvqiW`iK>fRa>wZ_$Vh8gTQ@*O4AA0At#^_B}2x(SA!`}lx|Y!opS zEnyJ}g84#4U>-kR_fBb`Xy3{YW=R`_jtHn(AQ0veS~22i^Km=35k!XNS%h9wmr zbDH}hB83)oDxWLxD(z+1_oTB;!@a*4hJ)`*H}D4c2rth8hr(hTXfWr+DgSF6KRfmo zye->4p@)cqU35jprPy`^p#A>JSH9BA)EEFW zd9Ht;4<+RniF1vE^f~AiDfK7c7Ys_<(wAynY zP(Y3M^0H3|pg3dzi*x>Bb;n;^c+koEK0I&DnY!f;YxJ#s4(P&*z$AKr@itoMLa=sR z=6Lu{?nGyi!)YRi+k{=1dmna-{$bZOo=K%%jbc{LqVHs^U?tcBA99cZjRiZ+86cew zx2`Hv_wwmVJu4XqQ>t#~h1% zF6`5Eq%H@JfFH4NNHHV42WhfVgWjq4-XErC%4obPPjsuzpc9BH>TDIQmD z5E*CMH9bQ#kMD@nSr|MBI7HqLH})Og0|Ok4%|MSv06mNG9T`U)1qoV*0Ev81ZqS#c z1JEPW;AmmrQ!y$!U+|j|Q>4SW?}FWI#0wa-q%nRWZ8i@lO%D+C4RhC`O&jqVT)8s$ zi14YCT=??OqnDqNfA){Q-FNij z3tDf=|9^c^{&D6XxNFh=f3v&&KTaBGRlV|BzwR%U8$vd|Rz_Ig=ah7~2#H*7u7}o< z+7}*hS-`?&ZfT=@XF%s7w#a{n6a+lArzcH=Fb?he90-ojJj9YNR1UV5oD(Y5=v|Eg zn73N+ON6wtq7!_zPb(VX{w!z|6`bJ=M7-HV7h1D1PniOI@W|~?8eT22VKA{n# z{I|6+*TIYJT(00qj_~PXPN)*vtjx<(l5D)Nd1MAZ9ECa=G`wDA+dZhO=H^$I=bgun zVHUlfe!Z16A8AVb{>Dy_fyJZ06@c&(Ew``SF7Tfw#o+HOR9<&{_Z?+-rsAo8|r z0Nb%>@}|ZO07B>g~L-GlI3}z^NN$%y%_ykF~KI4t$rrxq-#5omt#@&Szi;UnT&1MTwV?0b*_RMhF#g zR@dT5Dy1T%{F9-Hw1&{dXtxmKzzZJV24D-k#BcLx>wAv$lw&E6w6oC#9qJ3K2VrZ9 z$cP0%0HB_ocYv~QII|owwfRDcE9}r$(4k6?(ZEo*XPd(zR_lv8A_95BWs5n*I|hMw zIerFpQYB$@p`DuHR)~Q?1*ycw4mtWRa@cIyXBsrA%9Qz4mJFqru_9=&Kx6?QN&$4{ zH!uchR+@Ze-@Seu4*+of%m*%dX(HuD2^;mZfxrk)^;#x;wYWVYd+SEUO-sJO-)_Z& zN8P==J?F^w2&RXtMN@J1xk>U{%1g`(jBb(exn()F;RR)&i#(=c6?HLA?3#~TOh6M_ z;P5&@lR5&-LblBDOH9WNB@XD=nRWiFW28Z2uUvNi|JgtMmVE0QX$3RiSK;>0kUv4v z#djs(Zc1mb=W_NmmE1S)O=W|-oL9L|WrNvFjFtJB*7sNoR2EJ9UqyL(wj>|UwN&U? zu>eKg1S6QJ%mwA{Xtep$j?ZHq12W8UM~l&25_fn7pxqJZr=164>mod%ZC&iNDSe9e z%*y=k)o8vtOR+fup1u3J9+txtt|-P&wlo^-V}QPa14O&e)qfmv$_8x=2{xn9@5jM2Lr&Dl>A&upMUMV z3MW4TAnlIJcGu;F*gMs>8vr~8K(mPHItbwHNlEF9XU^OTUnfRx5Pp%DDS;F}6H@NL zhV*8G)8+$@{-*ZfI$W7wN zLnyF1Aub0n1lOQybi~4KK974O&UG5_PA7X+<@p?~)a;2fOL{QEbpUG^1A1rCk@(%$ zy)73yCXCQ;_f#P2BB~+i#Z_SbjuVVCh&(Pnw@9Mv|MvMnfy^TI1G1Qw{1{`M1w1Xo zQQryIFR8>>Ud1-cyTJo6d%T}}+yg3!H#Z{XIaUuQ>EA<97WX9b%7Ol(2&!LEiC+85 z7<;kmS?c2eC6~v0cUlXhUI#!$WA>;UbA})kyU1JOIgzJ?Xfh@eqDOxQpo*c!+4*Y; zkM$7nykGGA3YUEF)m!k-5T zgy#)l>NuxxGUzXO#cqk0PUqL)2M{7jcnca$FRh4`A~|g%-iR`eV9?Hf;5f-wU$~P0 zrA7OH>!qX%8E5|gZBzdDq4HmYk6DtMAGu8fEX^GQtP`&SZkW~$<8i^`-*_XHf0S)! z{@c!fi}oJ|?Uw%)zv}O%6ina_X_`l;d2ahXKU2BAp4*;3N%=d~Z8zu96(V@>>tiLh ztW?j$-i6o6*jN!MN`A>FQkGxUBS@!7?~rfN#nXJJ?bvaQmvmvr_h)UNjpNxf{OJwv z?viez?^WGc`?!ty`>NiX+MNVn=IL`^dh_P%s1T3eTqbm5O!A&&TCq3JIHL1-Fe<~q z&alGto$w^DbqT>`)AjVfiOxvJ=>gDj3);m9ppPCslI8)>0;WS}YUx|w`d0H2=mFN- zMk^fwcu4n54@Us*k>JkKCK8D9op;{R_uqfte(-}Iv@0x1{zljrBH#SF3winFm#qne z7b8HO`ZHs)#drJ`OngjFcY{}UuPjiDGN;kuLf#lf>?H9*X+xOoS8H`;E`tMh7o&FO z)vVkA0LvmPN`+C_)EEEF3dx~NDVEN7C7<)G*a2gyOsbI9;cNN!39Xs}q)=T&K5y^+ zeElxz`Jm2NBLJdW5faPEx-Er?P%;abN1MJ=t&+m;ZgkXQ2*!-OFa!t|4+{xH&5H7! zh9WIW#He_<*_vRPapeUEBFL%}g0iIG+v{~V-M}&T!;WJ<`c!v-WtJ_>4snVs3kU7T zPa#8>iMz2UorXf8nhJRUD8q82?A<^uf-c~K?24w8yooBk7|i;dabv+S;7A~%2TsFv zb0)G+lYk9JGU3iJj*OKR0gDv6%=(BJWhj}uj~{lR(dnQe1CHHT&LhR7@ z{(^RrCnW_{OMfc(N|TsG6LdM|rATlM+OiKir5&wN#&>6fiEKH43Xx`;(E`w?68)|M z3x;|u%aFyT(NqNGQ%QUho#*^FVU3w|?HqKrwD@(I zC=1tqyzWIeq4p9Nar|aa{O#tn6C{FN7;k$?Vs-|lDr&GFLO z{^b|f^6&oqmwscy+%K+EI*(r^^dXESlJq-_d{%FUxcu{V+W7|`{Nq3UM1JcJ-uwGSl<&I@VLW z8ID!^Iz2L}1_AmWYmDa;{>{~ajGcv*HKMdVGk-b9`^1|L=_dTG$^5*oct?cE7Pi~! zy#6u1UR}FaZyTJA!Us!{Vvvi zYl$0Ew<{S2-_2JPo5)I28yFjQmTMd6Q-tK{1RQ*?;DbNsKKJ}q-1ZR%t?5$Gi{5+h zy-14c#iknWcrJOJ*I;2zlsvAL!2yGE!jJ@d>nF-3mzlb>`# z$2EX{6hNB?z~%4Qz!_uLW5(c}RzErakOkSTdwj{O(PRkY!4%Y+9pZh@!*?))Q8odN z@97pxMUr9ie{{t-rSkiEEpUBQhLYhN(?)wj^`q`yK93Pk*b-l}G#W+QO72qtn6gF3 zA@Hd)Rl&|AI?2Z$dY?xJ!Ufo*^xb&T@c}|ryKMmn1pRiCMsFi}{$a^8hAI#k^4DQNIr!o+mnJh2qv>oG_j-P54ZtBricB zqq1zLFm#q+8tCSBP58(_!|QNMSHG?iegZVl&~+EGIGU+}i~4z3n*L-^q+OKgeDa)P zq_n#09(~P{{r9-GQv;?BG5DCEzVsM@mxB=A$~e-FdrWPSSPyuNnMbBqfmgio{7kPS zg&{gRk#o=dyU7%EumYGurYrXN<9W5wE@gxFt1mu#+4=wWW#|7zAA>QbP5Ey-|Bv^) za|B1aY~ls%RTudr=hYZ*r%gwR1kTd)t+o60%g+Dv&vEEhksrQ$QU3qnU(3%vc^pA5 z`?$SK0sn|+mBPF@+LY&j!;`%H`(!;nv^UqQ^j=TeJFD~To!yYfPTH^qZ1^BqAz$st0BEUs0JI|jEj15-raSp906nm} zdjNFhKXIftjlx5^B|Ufm+%F*rp!tstw*Y+SJKwPju`423;#^BhxCNkj09+=eP_5ZNDYN5c9jd4 zlVVMz=1X4=>y0y;5SU54hKR;ED#`&VREPGQ3$h}P>kF|mfo5yacHT29GYViBxx^cVeR zXbWAHD-Uzm5BY*FMXQ3zY2KYKi=2euA80fyeJyK@Syh^PpQI=-0BJPKi>Tvc6QLG7 z*xewcI2f|!dv(P}VL+kz6#LgaZ-iiwT+{*IZY&IB8?%6beh;Y99X%92s==u5Ekh3o z=X8i8I!WsiP?pUy%PZYRc}@B!nlShKHXi^3LF$o>^~YN{6pbL7>}6p|n~WFRYek#S ziEybGQh+6fcKk9LqdrMT-aLi@Z-c~O(BS6rPtO0bb}C!IW@gJO|^BxCk8I zrIoqtzWt3iUWlvyklLC5zu%($UzC3#TG1C@p=kd%Bs+O_m}HB*{4D0$E%n<;U3NqM zvo=@nS9#C!+*CIDWlnoqU(PVt4ee9DJj&uUtTlV*k5f5JkvbolmX2$a@VquDe4pRn z`0OV9%=sARv++5jt0}{QJXUnLq9Ku+>EpKk+=V9f0PgK=+}5tj&F!D1#d|v`6YDaq z2YsE3P(s!>-g;_s-j(*4I=B%ayGcBABRKp!)}*9G@?w=~O;TF4&fvdc{*8+7*RjZg zX&u>BAY`~pCE8NQSE&MObijmn_B4xz5PX_8uiz>yzAJ4xjT%lk;GsxPx$$8|xGZOsrPA1-Goz^f5&`AR>Rg1P zhh1rv8n=OWEb~uYxX`${0)Z0e`53%_k1P0*h`k&K01Z+Z6;jg46GVL%pDlVcIW@`- z{30-&k5)|hz=OZDn7Gv8{x#LpFv^4{4XUufW8njm{l`3zpyxC`f>y_PV{VMTZmy~K z@*ZHc-F9JRPNH`j{Sow%ErsafG*^^x5imIJ%7n6ZkGuDIT;VxhmuRLq&vbQ8Ys zn(m70!VJ#K>e)*>`Mja7JEyzgVV>xAQtmc5_C=j{O(%KJz{m5Q_;c6O-NheOsvm{x zAGi|LE3jmC0YliIeKArJ%#lCWFJEs&3qNIq^16JNzF(Ao^&o)JRRjTi?X}n1EdbUw zOIzUd76h;zqi){Rn>h?E)XKe-O??z;r=ybK%Oyf#?wO%b7G04h-&0CKb+ha&*#j>_l4gW>Jf{Wq}L5jOg(gx|SuBEVnA zrtjV}GKWx`LHY(vDTMnDrqHe~wZOc*rE#Se&N}02NtM|9XjN0-mw?>Qc83Dv8K7=m z!KD{Q086-9y58%qysDPqc3sffJd{j7<4b~#PWW>Cv+;y!2tNr8*^X8_L)}47CxsrI z-xAgE!XL_D#>%ilJlvkewU|Z_0q-!Ngj0k9Cziu&V;-s{ko|fzuPYWbP0tbT-QqLxvz-TB$V`mGe-`F0ne~wKNfzTg>^R^myF~o{)DOMrjAcscL&45pa+k~ zkZ7UumV%9<9v=(Qf)k7v_+IdoJ*&VNDNk%03T3-G?%Tiqf_&?5z9irH+H?JnaT{QH zzYx5R6>2>&y7luy_A?!xl;hv%_sl2cq)x>+-63zZL#Pj)CKElLz<21Q-0=LQ|2oyn z0`e;_TwTVjiZs9c;-dUtcK&y!Ps{iU+!V*)tn*8qcZ*EZCGZf&*Gsy((!TSLtNu{r zoquyt{{Qfg<>#M14ldv0fV}w9h1h;Y{#vCapZv>Cw)~~XS5H+fZD;uJOl1xpWQYW0 zrr%Y*vpKSY=|4$g-dm7LFO5NB$wK8XG(9aIo~GPiKv(Rfi38?hP1G=YDi$?KAu2pp zca2MlxWYa%MxJvp1c<~{u_3TXwiTNrL<@(_tUGqOc{;b`9sqswvt0w&K3kyl_UO$w z-_-Zsd#{AeLMt9{9Wem@N^qXPuIa%5aF1k0Gi9Whvw!j@e`0UF^;VyM?L14fXtmS~ z07x&t{IYluz-AG%b{*i0@?;4+VTxG{h{of1kh@A_##*VscU4dZLZM4~ZH^-#w`;popIG+^|lr8pu$!a{-AlvPU~Di=1$QjxoKE=DRzu~E9!5!bRb~D{LqOb!A8p6#65NLYfI9IB14qs*~^F*hisGHQ?YsnpMj;jZlW~H_m z5rik@a4!$T3$+h7bp&kmWv^DO*#{UqRDHp{mH>v8qHy)b9q5AoV8OM513;Q~0QXE_ z@-RuE(WI=$NfY_5;xaP_o>O*92xvj?4kT9++EKb+528_~xs*Y=M+@)7ce*f{&Pk6? zj2Vs?L&5vb>C9QfVa#K2KJV*^V1)PqHIMxB&4qq(!Z~pcx@_+qr-;n?Q zfA^>>l_V7v+EbOaV!TK;=NCCO4zRE`8?_D$QG{qlZcMhS%W-jA-W%bc`ffMCyz2Am zGdY&yz7ksr<(z4`?fn1QfA~f4&|O4U-3JcLDh$age9ZyB^7h&#IM@Z~b%FDPYO+tvZ+~s!m1|~zW<@;ow7TlWEk}9Oy zL4ZcT@Io0*afVMFtYc}kSSSgqBCNpX@9f9ETfmB)>TWa^?AE3?fG|Ex3gd5{0@pj; z9x+-OzneSqUcDW#peezIRyd@VgUs7eU-9&C)1#`@J`YXZ8 z0__k^{oFh6lv8!;oiSH@cw9`=m^jYH`}i51O>_YEo#RJjBbXOCP8Rc1eI6>8a{lHa!P5HOPd%NoI|ME}&xGVoW z7R~Md-pc=sr2kx!-t@4p42NWQsOo9K@p%qDbCc0+p4a7bs!Qi`b7g;-FA?>5;^+IVNEk;5FiG#(;)<6+zd&0pZ8` zQuq`}7yOK;a@T}w09(0s`&o;F=D(wsi=yw1CMqualz#vF-{0Hu>X7T`{X=@X^biB! zo(aNXivi%ue<#*<)}@_a`L$pBHN~Bl`#vu9diB*;d!dW zfF&>>36W4NYFpV#FyDx|&n$YpXA5cw`j$1tT4_?p!7N=!AzV7sp9gHy6cE@;VV9I( zb6rSNKv$i@4|@R8eqQ7HECib)Eg8yH;@3b*zU#%pib)0mbd9CG@oVmQsCObzR<0m4 zYdn#Ny3cv%h}=A$oXRZ^TF1Hz|6Atkb?s6FccpH?#l2VO!aocW+y;W{i7!$OubYQ= zjw3_YCV7t8g{Iw#yMOF}(|j%(Vc5=mo% zYTTI)5P4~~7{d{FBFNNZP>gfywR_Q|SSadY5b0+iYv4Ky0Y$s(;|Nr$LE{bHjcCAp zaEDz;<=21ZIr(S*pT8yl{Qvv6{+?R!4l7a)dXCXxbZ@Dm+p{@c#~b63Kto%#Q*KN!k? zjC;e=i*?dFP?hyCi#pcP4j3klpe;=BLjyyJPt$O@C4J{+Bg}MCK*^kb+*^qi(E?N^-X( zk!_o=RTasY6faKO92y#$zf-77LB5*?q zLNw?Zrc*vnO313KLiH#;(5dtNT@#qy2ryo`GGP)%jluG;->em|eF7Y=R{=|$)R)-z zhpV#b)Zg*@%7w@5ZtjX=3`&0uxw7xO}=p|6%Ymrgi@6A+D^f3fmcHj?bzJY(*es4*t~i^#%_->0OJdT<)2*{)S2#8 za`)KjV$)Fa4ft^Q#!m4ltfWPTBILAUu22Hk8C_nA45S;y9dLNMt3BqHkHJb9#EyI@ zbz*g47B>dbyheV|0kWH|j9!_)pUsb_!}ABbqqr(Gi{~+-j=$D_$@mnr7fqid8iP7; zpkuBij2iPa{6ReGz0p~F!8~${J($u>+;nXpK*4W zgJm+5+K)edeA!XHzWkZ|@-y1S^?yvxQ<=L)M;?S|@`kd&FDu4jeBg*3!@u2 zj3)OT>=s8);PC?57Wo@rYXSeL&db+7zU=(}*6&}G|4*-lVgbstue>bRFHAfCH+7WL zZA8O)?poJv@3>8T*E`npH0jXxNvF@?n&7d!v~vsmO7Th3h&bhu1w0e)Wrc-~1ic226^xZ?kp&`lkFs2gwR{u~S^p*)T_nE+pa%hL zN1xjf03i&2@WBW2=9_OGYHdLPTWaqA?sa|J^6-%EkRA*G_egwpr5yoiUI6d_XwPtm z<=4Odb^Gy;f2{2mfS>&2Cq3Xrvv{>TFcAnNuEw~j!PUZMc_Kc9C#k$WlpK|E?OnGd zLfG9|sP&BQ6VzQDdr-TfY^v9pOtW!61I%~L-7*=jHK+43xbboge&(7_n!(2zzT;O@ar)sy z#BgYRJS+P;4c0ur4)iWW(q2C5oq#IF5QpQjB!6NdmD_9aWCo3yB;U`2O*|9rF0jt< zc-kp8M`b(tAh5!0O6wd|Sxj>shVEbg)f(-;rMC0`+kNN%aYA`1`|MZ0Dqs1PH{_SU zIMX(Sfs)!mnUHvrbWxYyl5a-x+@_q=VYjp)H@u(gFZoPL@ST`&Qi+{E`TdN))w`SE zT_qzL0Il(ypn8?t2F+~w=%!)Rcxi|BPsiX4w<5QX{VM-zq8%nN{r34(T*Av((d4`< zecmN4aDS*9ZVwWV521&Um zAC7f~k)S`u+~ck*k)$4m|E_&+%Ku`cGkVaj0etVh_j-2C0;2z19f8#SL?W&4)_PY9-- z5ez0ZC?A+17Fv{>t~J1ZV#~WTV3tbafyYBp+`$BG1eEjp+Tv{Y$k3VYhWetT1Hjm| z+oc*3jQXsWF7xJY;c9UdtFNIB{BUc|{)K0QCXPaQ-+4?dKV8|>EeSw*QIDP^j-XtI zkwBD`I1AjX9{`6?Zb3=bDRHsb7aX{^;Qrf?dEN zG+tOBJrl0a>BbUcV)VMb-i=_#Tr0E|Zj)Ao%8+L$IG)m~yAzD%`o9&vyuRz5^I4r= zl=#R-Kk8$269DF@YE_1uK>3tOf9w-94KGwiB##Bypyf1<(KwI6O7Dk#067A4Q28M7Jtx}IR@Hl{tL;^mwwmHTo1Jxl*5oAMZ#g=f_cp+RVh?i#cid{OlXs?A`o{Hbh_ zuhwzsyC*&d;BO4aqFcfdfOp@0x776g?|;94Zw3H^_CN1RJ)|c}4+emHB+adrP<)yP zKuhnu^G+k+{;1=*n!<~6?z%-#JFHn?=D?L#%4gf*ReGd>E3U-rk`EhhY0~Sfe#u68EzeA~#tRHj}N}MAzt_-C5 zdXF~HGVmigPYf{%=&a$Mb%evdN|6VJ=G%OOgZiA|`Je&3NLaJ{ukVTo1@V)CTqE3r z{&6iKVEotkW|Xn3dZG%c5uOMIyrSXQUcd8E6(Xgg(XA{V-XN^VF9^ zxm6uyVV3o{PyJ2!bZW;l7Y1+w*Hpy;PFb`sCveR$ujo)0-{-ct?2OZG(Y{ROXJgfr zmkq1Ov3A~R7RNEmrkk0^#DQ0x=FpGVl7}WQ|1}|gqv|<;j}syIp2V;zbtydy$^gtb zKN(lvk%vCif&ez1>9T>^^EF)xM*t|fc%X|J|B&vQ9t;5YNOYb%zI^w) z-!02$ivh4G*8*S2#~**(^R*iQ+7W<$3&5EmfLiVNIKJyK!%8(;7ohO>mz?Id4-&Hrj>ual+9TKRXP!xL8t=*SGTFz0t|I1sOwm z&l}g~2?xrP=zn|IBGd1_aEsFq2V*;1S7Uw(O#%8bp&*{IQ3v0l)QQvuUuOZQ=S^Zs z&jlZ2g8-}D5QOg|$e!~RGDd+?5m%wZl;khG%rK8FGKE?fgGey@uX? z_Y?W;KYV+*{hQa*#_+}A_Rsh^;H=O(y;~(c`9Afze9EG|!T{t5o1E04b|fJFoZBi& zlF76P9G?k4lOx<1bdmM?FN@#PyohHqy`Lx7oIgUGj-{{#{V(-Ej8~?MDhRd2LN18CII~ahS(6iOKMOBr2OouAR z`FIl@t>BG?V46pBK0W!3tlTZ4iJ5k{4QuDPVpJ_R9{PIhg^fCabr72<)yU@Zzrlak zqPaS3Rys8Tr~+6yrd5BBmGu|^NbN{8cJrGD0KBGK9JQ9(5rF1h-FE*)4jl6#J!N_@ z0Nf+RSyfN%`-OPhd6iC_jdr?=bslBXD)MMqykeKQ7t6-m!nfHd+hs5o)I*9hhiR1C%3?)e>Ipv} zMr3<=b5QzYQ%R-lghrQz6o088j4~R^TR^cxAz^o7OJT>)A1m-n3SR5$aHPl`qPpEG zMX@U00cK?fK#Z)l^sb!ypI3<jeY;MG9xzh1Rvwfd0OuL&`sKf^P?@niqYt2U015V?)uM2`{Kd}e)RsQ^66*SL08Ofl;&?cLa{rd*>hqV zrh_qM7_*G#(;y^_kNW2(>187##LuU*@tR%8A+zNiVE&G@O??AP;k%xL2YC+SHj%-I zeuB;<@e=%4p(FS)2PGEC^HVC`fgi?kjM0R5<#$vMvq|t&WA-U&&`iFiK95i~R!(`w zcmBWf+*bPWPLKBgwtRFkBC%4ZFT5;@tNxTbNPu%sY@()_xP&?w?`=_s)%@HZzVjW1 zc5EgRGiW@}sl6BwJ62+g`U*1W=iL5WcJ9NRFJih(Wn>~4Hzu97ms4*vhoe}OFXSJi zxkv0sX?K$!`Ks#5s6KPoExw0NyVRlJ{BBD6(0pT53dlQRtf+i+%q2=laDLUw~NkqmMq) zcCAH=0nnb|7J%*nkkv}%QX+E3$qPOZK?0tn*ZN(^t@0e zHnHTZfUHfzt%8-id>&jcqKJyXG(e!&3T-?91Il#@5lQ99Siv+YkR2-SjLUBWP~Qpf zIpXZG#o|6y=~bZ*!a7efS#3s<5hO9ry?SK&2*Bd~>^r|9bdcMY>+WTIoVl5AZQ;x{ z3}rO=_nX|hll zBozJuzqo9P0DIV(bLxo&hTyP?bcE(XY=7oC@o{~Q@4lOa@)bCDdIhe=xFikW;6lg} zTT*>qPlvk8%APoKyyZ;<11@%!$kAn*1Mc{z9r%G})_BsD&>0#VeP_AiOlE<+G1qaB zeSFl&z7%tF-}3lKN1fCAxIH3iK1ndJopdRd2EsO{+`uWMEE9A-zj{Xb!~e&x%PTMD zl6QS6(_H=^Ut1}|Y(^J2K|*jp1zeUhV~l^&e*4vL)gS>cZ<=7)&<<94PlQCQyUt*!=d+`|L33EV!ds-`_4bE`V%7hue^9s{$D4^w34Ue z5Fip_rSjGsCt-=5duuYin?;EupNRDm6S*?`te@+~0}$fiUXq$IXN<+D!VXxN$@%Rb zK~S7uCLEa7rfdyo;hO=k7v!?&JJU<)pTr!^W?i=0CS0*mLAA`o7M#s?iW@X_V|X|+ zGgyq-oRm90gK*%PSQ(p0N{!_Dr- zc#q@V-KYFOX@9SNJ#&@+6JGp_6^_?sKyEQtX&_Cfj@gW){8l*$@6h9l&$!yf72)e25o>@xnBD5(L&+ z70N}~0#6#C@vasru4p*cec)If=l*;ryzf%#5|TYw05LFEtm#T+dBHNrn^{5UII~av z>(8yPBt7t+4)_8!qsx5tKYe^k?~8 zsQnqP>@j`zRdpwK%=81S$H!QJsB;Tze&kZ7Lyg!DVaVxq@6oGRJVTan{JUkX<=L+# z_!DDnI~jKR|o><$AvpK4FfDcCIjyf_4$;^#$D=~bIK|d z-j;=YgnR?HInHCu$eYP9SAkz1LrKSg%aH%y{`YUl|LHrg2{kAmeDwK6`QOKU5lPx6 z>Kld=q6g#eLcbl$)Ca(_sZt*#=Pl9K7)Iuk<6jtVm}gh!O!LHVF(z5oc}pafmf3dq?6YP z?c8gbU#wTg^6B(&rETZ`#jgA_Zd$bef6(3jubrnmEk664Y}ol{rAVw!bf9Gwpg`q- zw?q?_jj=VU%+~6V1`{e2N(_K_#|$IG!Gwgo!8ELvpZh7bihvsf5Pc^&xo&7gTrV>X z%Z3UyE8(ipjmNl`^pU%}P z3jL=Dc;}VF40(`I7t>6V>ki(v=SEWj#j0(@ z2nEH(Z^GH3FP#r7ZaizL=|IqXKK$^*<|S?I2*CCAbqk>0y{IqwwFOphc`h5Q>Ola- z9=8AQogNGT_eiRJYPC_vBuO&E z1ryY%U%}#RS~e_x$tl@)|8>H3%5BxX zKUt&aakqj{U>%k%i)U+5sm8mWH^SVH2Ya*hZcLkst{j*;#y*CipYzYUj3ad^8I9IgtF42A_c|Ki3~PcL87!Ln!SM_#WjNo#6c9Xa@p|NJj1vJ7?_c{K`!H;!m&r(gB==8N6!KiajS{QuVP z|4=^qog1e5 z&*&8Iqc3)7BI$F6%j;me=CpCl759x{1!x4acB=gXf?Yo~#Y0)Z!C>!y9{p(+! ziB#=)b%jL`z=KD`3q%3HRkCzD9FY%!fK+wRH$vrid$Z_^x86F+()ZI1R+koqF zKk~8VfZBB(m+NZ_BfxNPlrZ8Wu-m}nSh%kDJ!#6&+dW{0fyhkr8o3;}L1Qx9^BMbP zyovOUo(-HPWp$;?NiP+(#PxV?zUawtNf(PD3AcV9C*YnJa$h3D?UU(uqjt>Fp*bz^ zV+_$eW;NXV8tj|n8=zlZ+PSv605e{U@sdQC?Me;uE1b{akFs;!RFC+$?J0Kz$FZEu zspNY7o5!8#c*HFVnr@;tJ==&bK+_%74Y}7Af?&*Yzh*MVD}r`&}0R_W#>|@Wac_{})B)*5@wD|D#FyXS&e27b0bmj)}*EXf;0* z3_Xsu>d?-Vc)ha)e74GO>o&PeAW>?)V05eQ==2@P=d;AC`b5@nn^hR2jMcoHX@*~D zKo_7H7qgsGVG!lC)nQ?pJb*%L#wqNF#PI47SEZ4uQ9EfzYqf{^vh&CB3#5U$>0-Qm zd@1`Wz4H4NT{4_JmLey##q|=Sk(2sYX~yRYma{pvn*WmMGI{{nirK;ls;g04V{TI8 zEk9kkG{|BYmq5ft{?}pR>QgO@TUx~D!B0nJMz9@8b49E9tm!!IXtZB_-Upz0L$~DK z(cK8}=9_P}0P6c&Z@s0LjZ(wafNl5xVgP8L4-NodLVEB3xMyla*p&Zfm1@6R5I}m} z0stB!TDBm7vYsK`1Hi3gT)W%>f`B6yOInCD@>o%{pfHN&9;?N_Ghf|tG#PFx;RA0P{8TAw zEGq=n2<^mR4*v#Z0G{LZ;d43p*E6~DtYkymGb?kI176CtVUzGorEu1j&ELqZt z|3R|e5{Fk;*{PzGE5^)1I2%TiTm*1V46fi9|K2yt-T46n?EumuveVgaR?LbKfSw_s z-n044cAVz9H;ea5B>CDId`;0h!kC5 z&OcyuCm@1PZQ1{r?@Sk5pQI~l%lCi(KYXpQte;kNU}M_j@nVl{W>>ot z=unh3Z@VJe6~~>@*s<$npgwp~^#ITX+%XP9`BYA2&lUUSm~h$7(N%eyXfNtC9EH-r z{k#VBVcRPY<}3JYn&XFYwxsX*rhp(7m4aK$f6S#hmR8JL@P04Xcm98M?ELfG>1Y1` z$=ltFLuC z+5a>`Jf!=i2M>UIB<%jf6MzF#w7?bZ+{(p*6>$Js3;<5;{EMe{3&7+7aAzn0i(sKO zf1bOL8p;+*SZFp{pszVoHs;ym=eS0OCq7HaBACNNl($h=ab zF7Gi(j3K(ha{+uUssJOi5FCwh5`)#TZ8r8z_6Tz4%#;i-*f|Wvj}ak5co@6z zDydMCSAhQ>D9_$^w=X}it((b=7BsbaWcB{sgE$!A=|=@zDfKhJdCi{V&%FS!&>6;` z7QXhg348l>_6?*3*Y7Z%$Z}Alo>}3VjZv%Odl@$@Y+96C1gSAoQWSg~%NWs|i3n{Y zcw<=FL;4fp)tsl(7(WYPuow}z&-e-$gyL@yT#Tc{O-@VxOsL9isj`Qie3vS#MDW8- zFAxHZ_z7_tOW~pY*RQqQ)T0oady{C8I*eGrORtH?Ul`vK!x%fWoL42H>m$BJ@SDru z|M7qOh%1$k+BI!L9zX=YF-|O|YNb;lTE*P<2h69GVHYWS9lq~APm!|klfoZ;uL^WUfvO?p8!jn2TgMgUn$enkR@dR^>A zN*|*sJd;9|5(^n`=up7{qIvzf?i|q`2jD4M ze@L7jJOJ*IK!EK$O8buU|1DzWMfr~z)FN7b?Q37t<^k~9Yp=CCFMGL*<;z+OfQ$04 zZbNt?f=-Kka;V@xnmlV({vG(V@H+zs-wH)vhLERTq0$1FF5wc-gx8yi0VeNEp;H#} zK?Sn@#(nd_=#1(TiG>)(0My7l5sF-UgaCJNRUha1bplPxjuCK_f~ETqC~6hLk;o($ zJ@YbkB6lULw)kwBtXo&b+vokfJ+|GPGa2S&?@DG=7f=@#9BW zt$AD=SGeap@~cn)L!(`t#18~K2$x+bbiCte0t?VNPra{}_$)iBP?$@<>qH8}8jKiw z<_E4v^)$vppEBb+s*ZnmBV&Z)37r`6xgbMg0Htv&RKb(S-p-U<35lX_auenzm$9vGQ6V4bPKjVpc99B1G?vgY_4Iwthm6we`ify`~$WR#<7Y5pT_2av(* z4tV>>s)_Sa^f=V>_;Y`m21M$(DpjacS&`#doYC3*ex~Ua{txAK!DJWtSM}>j-W7bS zbT+>Hd;V^+o%UUpC5;aP#u@aB|Uo4o=nhHaJ;CRt9U$VEoh z_2K!LYl58;%(Wv0G_uXfGxEf)!MCTxB;LQX-5E_R9|{X z$MoO6r1MY(&5T^FH+g@N-t z{kzJv%bH4lXB7T?BVho%$IXucY?oCjg1J(JtClAt;@e@Jz!{^Pi~u?>Zc`sbB#a)Y zvjxA~s84C17_IluT|@b0ODe7)L+()l?J!9$;sM{ptjqecc{>2#>Ul0MWiGt)Shl}@ zjSH@>^E#VCZ<@j91Z#s|FK7ab9*vDyC4{L1aN|~2tZ-E!@1Zs!aCaP)^SYAoF%km4 zjn0z^?UINHJ5IzHS)RRS!Z^e};N}Ja22CFpD72HE&mAE)V0oL};=W5QPtt9igXimr zB&JBz6||$Sn7Y!o^KA}N`;Ml9jt^3F3I!H(tm0@q!}wcy(@Mb5gGp(md{KuZ;OC$( z@3*DEu)FpJ*Td>4?r?ZqgRc8;HO>Lg@7<4FFfNC%tVvTVL^wV-Kf02!GBP~Cx4-eC z1f5=ffBM;VVL5)7#jivn{Aq0pOj6l>5^*`S(k477#Ku^T9UPl@NqYLgb4i^5K-U_y zM{{1-=n0ykpkxlMGTfSZ6Qvq7jAj~4TjAIvja?}0K0zQfnxX`c_a}^VYw{J z=f5k=H_`QqzW62cx+(RI9UUG?u@ABDVNh0I?2LFISU%P^Y%qikejE9WU>bbLsjz>VUvK&dKKrjGb~sJa5YXMuJp- zzE9R$2(CJW zGA|U-kjV(2^TMc8HAe8VVWj`<6)qfMF%L?mw8JHmid4)6^qqvX?hWdzsc+;;WFfi@ zp)dO93K9riB@~JNm>VuT9kC1Jrim-QKANO`FDzZkpTw3(sE_Ci6}U`1glDyeR+up4>Rr zBrV_{yZzsmxWoK8e>eKH>Df(5PkyVM!o&Psxd`*Lsg5*W4FFfoo;7*s&k6^2OGP@p zv#9|+YuIjmbpB2c&GNb`mh*6wRWjPG!1p=n1E8x+B2PB{1$dDRJTmbg%5o@X3pi|D zeR;1_`GamoFVE-{-{-k-mfy~sIQ%}tpWdO)`MaJxzb!51{{Yd_XguX_Hxo5pc1>=m zL5FQ<5gP|0BmT}U%(br~`X??^BA(f_{AknUU|7<$YsLs@b0LEyy z&C_<1+C?|&dEEm*5pdnthNlDMA@%fN0QeG8BSZuNY^faqXl^U-zWZ)}_U4;!YC8ge z7yvi|;HkO8D1u`=X)3}IPi|os)KoqoxNTrIGfy@t3bgTas#{z@M$}~JbEat9CLEz1 zerJVwn#diPsTSt5k@f>P0>(gy3!d|iszLb4-8XS23WX=4;9K4xKk$%(^we5;HefPR zHul)@Hx^#K^Fvv-=wowB$8P2@WF&JQ@0|wNMH}a}S;@!v2n1hZ`W9#kMJxpMJyn8j zQ(9CsD(v0~eBM3ax1d1_KtyJ}6Y!!eXcYJf7vcCl%0ZbtB=3U=?Xvp#wy_SEdy@!A zwzJ?;fzJN;^*Or(XoNRht;a?zSmlS&V9?9B5g`?!P_nF2t>XMB3>BKR62>9*9y%O* z1$)5dIF0~oLb#J@x>>@@K?8xS18Qt|jBp(sh#FOjWK588n+TDQWnZI%qJ=IU+obS; zF1`GgcsCzIC@`I^J?35ZO$jkPPv<#1C%l8Y9g1<_QcKx1B49Gt zwm~;t=@clQ{@vlk94<#wM52A6-+@cw9Z`?xsxHjAV8qPl{5~EjC~7eTGES2(OWbUM zH6-yi(NfTkm9+tN?Kbt*v#3b9$v`FfojATkGTIgc+Q1xq=z%W??806 zDtAM^7&lwz(Z#z%*^|1@e&3d6{LFLljLy!I-SOF3`(<4l|M9WE$fJ0lldr$Nn$`=i zC-`Hmh0fJGvn15Fb(W><4a%+?0pLqbW7OU^>u?L|XI=n73za+o>|px! zUg5ea+fylX4I6H}SfJVwgnh39AL>M3V&`odCr$??r4C&xSy4fLH?GskZKue~F-|-$ z1pOa{q7T43kM%y3?mVlRLL6LwF;L~EuekCs;ppWy8qWy$H0s+eX*bSYs}}h+Dw7n< z`KZCDN1_1w9?B8sr_?gtCEqIEfLM;*AY9H1`=ubmP_R?GI_6RTzE@lYUAK48nIL4u zjTlff`FN7XAMX%@)-pgR;SRXCe6;KTxDPw7zTC$gY`?B|@DVG~{SQ2dK2@~PDjN{@ zg;1i4-)WS}ih)KY0S*OPwHw`rP$r-cve8`BY3}g66J5YW>|1iW1nw}8czPLksAo)G zS-_*jc33tN#BV#6q3K%S?xaR}aQgy43Jzdd_W#e`-*#J;9Oq$R#6Hz;Rn=YH5I{(n zCQ##nEs_8~;lq5zUzm|VN}iWrF=I=lJXl&HY5fjsmMoLjcYnkmfY&ksP_hkcwMZIk zwT0E_Zgf?@)!E^lnejwCk$azeZ`EzUZ#TPdopbiim&nM7$cW6yNMh~&x47}&cm5^o z?`Qu1_($@=lXICayYc_LJO6g!IpbO7X6aIWSLOFq=Nu85qRV$q44U$v!yfdcS&J< zCdsaOb`$!wDdTm`-;^h=DmUZDuE={S&u!9G{4Znf;RROV?CSHPVb)C+@tpvWh`R=7br)ao(TtZSfcS13KZD+PLq8|2 z%3aG5jhlB74)kHc?&!rdO>|UUC}ZRO_`yo;=!?a~YAb14?E`nfLr5y>)Y9%ex0N|0 z`kKlCj*bK8Y+#)n4&>$ecfhV$uez93kvwGKlK}2c$0+wcS{RS*JT&fCH*UibgyRP) zs7i}b%4p)~+Qn;Np~=b{=*4g^c=XR=w=M7%_>*ER7o%Tj9M@FdWB887#`blHPkb7S zJ4QHz@4ot2C-=;CAn2Q(ymP)i9__8Q|E&zi$WsuLGR)(M&5A2FjXWLvXu-q+i7TP% zEIoUSa1->Zl7_a|6#a3SjqxQy<4hQiA-5R6@cLMsJ|Kq{OL78mXaW|Wmqj4ULJOc9 zC#H~1B59n;@a72Kj`qC2Qt20;&mgiiy&M+jC$k9;1T!B87&K@*`kniMaWw;Gs7{fc zTvYm27CYopzWm<31*9%Y9hF5w{7{|iBQa2ALFSEx8kMqpj6XS)_m$60sw{|W{iZbY zI#yZZCzWAW;DAXB(8e) zJp6PMFrKH(RpW3A{^uiJ?El0YLpTy>*rf3i2>OR>pVjHhkN688-6~`a^wT-hA(!`v z7&;_NPoDIy=-`D{ZTG)qwPN(8a!t6A^9`)&|<3j(;Udi8hr@86H-aRlJT%0TX%)u#^EB$(L1ue(F( zDxLYw^I6?>S;-h^M!S>H(LC1?2ol|GyJ&zb!kDt-|xTfoW z$`++|mE=P`pDmc&RpO=wK%ITmSa@*akReo3n$rs%bPw6}0isL4}5X?J*JAS)_ zgX_{E4xR%+H^CqCS)7%k_q@QNm>aYHkZV()mGIhMFNyrwD>9C7+9W&XzHrxN`fl{M zPQPs`FOzUNGU5&%?cm|h>)<@haP<3%_UuA-JiEk$SMixV$2&%w9=tnh`v&~4EQBFL z{SP!T;`WSuD+|v?JJ7+1c#Z1oYE5i%P*M8Vs}h|Qb)HMKJadies^j+;@DCfOZF(a9 zS=$J0M*v#dHc9p0{kwm+EzF**c~3Vl>UN{rcfRu-MG!zf0&tgZm+lq-ZkeEfFk!aT zjsUdOh`4zGY%5yUjsU#>{`;LJUVr`d?(+Zi=~LTQ!>nD65rvQF`bgMMYjb$PleW2V zi1V%_Zz4F?O2R=$tsKlou#={Gpkrhpss4%OMz4Xv+M%OSqV*32`i#ckrs#{5Ebr=#Y?5YzE_!+Gl2#Jf5KpD3mJ*bd|ih zXw8xBa{;3AQ*jtd3xd-b_uAW5jgLgCxWQxbi2>;fcWcYs(`2i7@$>a?M@FxD{=f-< z8Urxfvt=R?2?H!AK$EOYBTx1O@Hs}0<{}!Oj%!4}g<;4OoYoy+pk@h8IgfPY>`Jt# z$8(-}Jz*ewBN6nEl}x_k&0*r(1Gw*jFZ9zGkCoA|m}L`kumjH5F&2hrL&m=jKJ8v`r+b_6|K+{$Pc&7&S7hu5Q7=5_&r9{#g>rJmJK{|eX_;TMoYEhO z@R*Nv0u_Il`c*IR(fp|g?=R&Qo)2V?cYZdHfgC(%`J&UG&~uaB^j(ID>ScXrmK!5~ znJg>RCO|6P1w0Lz;Oitb1HAH=|o&P zm1uo`31=5*!O#Eianm z2$V6=juL*ZT-2|%Y59f%^jbSw+jn@koaZ+Auj5$2dU8Q{>hE7VX((+S2H$D`+z(z^ za?(^1UX!$9eRk~l@a`d@#QO^)Ny*YPZx8h~CBj$2@!9eA zb>R_kKx8JcH)LRbdGiIGGnZbaEw?1BK*)i zW`M;NTmw%7@o7k{PG1NxFqHMh;fghAhyDJ`5{BYx^Sl6j;H#C#`D3MdCcR8lj3!bk zlTjnH*X}XH_!q^fT9j*j>{s>O8@$|T;^mWs@jcpFJo6pz-Cl=M@Y2Z_g@TnDl!rnhP|7bzdOq!$4 z(f(jNlb2swCYe0&cF!NMVpkPCr?(1vJU5b$9R?_3mK7Vxj{!dIh?Bg8JRq?Zt(r{9 ztUhzm0sOUhCreq#GOh8{v(G9um<3Au*`N>~Ck>C51AIZ~C&T`M^tv*JllRWs!SNkFW0m(&WkGT5$(fxzHmaEFj zh5F>0{4w73aRfe<`VMn%%sUf%y?LJ&NC?O30)Q7^PU!;I)5|Bh45LhNT7^Fr(rqeq zo!hbJe={8`N1xUsuMNFi2YtTvV3C*aE%Ey7E2ehSapNYbdWN^jjrRS~YvX2}k3U85 znA1fXDGQ2MHOjb^1Y(a$&3VhH4Uy8wQG1|o$e6jD%`nXPX90(D$};7kKS%G5+L{5T zW*_>zV|F|)SMoN2eI5TF!O+USd?J}Ujb&qj7MDbqQ|Gt#X?p6?t;Z`lokm4%Q>IT0 z%ZS4zuAixT+$cO7`g)&pcV~38z*U&N8_xnFOlJ&iH}Sw=+5d544x&0LDV8 zPfVG;YX%aEud;HRcm!Vi8LZNY*4FBi>2S>-I#5+!i{jN+YAuZRmUG;VKJxbVaWAaj zq23l)97Gst^Ca4@NppM!3R`(h7H#hEz-Txt4mts`@S;~3v+9cn zn9C=nq3R#wCGSq#G+E{@AQ$wpm6}%w$C%7xl9r_DFn%QIr_=Z1d?C5381!frevo+M zVI_@03BJU6-H{x;mqzD+Lj^}WW(_3bRLF!oj8{HP^w`J~?t+Y0P1!IOWQ_1IWp|zi zq@8Y7EEFXtD2Q(%xM|_YNow#W5rr}{ig_Fj&2d{Lt~W9Y&RMhyGMdXm3+gPgW6Bo~ za{ShUZ->vaVY4cRAzL0jcuC&=jn}$cIpBn60wSeHthO3<}#NOE7FyB zAuIfc2DY-Czx!x2rvJzP>8X7BES6Kl`@&Qv8Z}{ov8FEqz31#dI9DR`q z9|-u@jQ{MO%3o~8|M&j*NAk<3=X73bG`}g?_h;iDNI3c~S3GCL&!2(I=cwGxE}^f}8B z+u_&eK;Z8hka?)}Fazb_iU_9AYve-LCpZdhOmA1Dojf^eYy#7cI*WYenH9Kl{3Yh` zJwS2=ut#lNQ3v6(jPDI;&F1;+3j{@@ z*|V4wyF%Y%UVwbQoH}ZDZVaY$>I$#CO1AY#vu9dHlB?$UR?3UZ<-kN*z?!j0>;@ zvZxD6WDT}7GXAIP+TzUr`ERyp|JC?!Xa2wUpZ-{W`SB`jDKGaf82>MtE+M`MI{B5Q zfigOCE|uTokMaXNmQ-06!EAFrN*9UuD1%k{vi<8@rP8KdUtdm2{MBD6;j=FEa?z=p z{B8LOzR@EFo*Fj&OkUt)n5TAj^)Rg5uN}a6S!S!N>1ir{1j~)m zL|1y%`x`XMEy3Lz1K97mSMEox`%^XyovB6`)U~COX8b%A!3)2U_nF53k29=WofGrdM4pU zzY|^+S~e`gSdnNXVee0TF~G!knMbF_D(jHgV^L!)qGXe#a_PYRqLfR;jZG!E0BU+P z#Nv#o8^_tX)n}Lyq|SGs#UiRZ7ByhT#>6BTcdwb0ZD<{7#HTxNbSr3#pz+B|EbZS_ zGJ{PD#VRyG(oC3!tK|Lg{jJ6EU9FzK3H#~`U1pMQ_JGOz6OkRQ^k*2w8UYz?3VxR` z;+}QM`u#n-dZX^bGg^5ZbPrrIUV+Ei!-5SdAv6T-0r#^&@d^M(Ew2==VaNsaYgsBC zW5KQ}z}58~{Q~_BxGLU(M^I)2flG*Dr-BVrmD>N=m`{92ER?FIzGNl$;O(z|>DA~D z*E<{as55wg+Sd|LQFcjXFEdpxJ!JxI}v~0%z19JNxxncZ&_~cCWXbVF1#Tx%t zC6ix6suZMkn%u#GEd|gRFU%`fN$<1bQtLq?VHH2EJW~5rqveRBZ2xI8t4iZ6w&+d{ zitKT7#GV{*QR!JUeZ!9Hh3^*=*KJ2K0dpFS{SE6UcE38W9+b4p8Lmae4Q1s`(u>gB zbG4(#>87sjZHEetr>xwotC2 zyA)@GWWz5a7koX-8+q_&6av;MpJt+#id zJtN811kF9k-&=a}={n)mKZS*%#gi_(6z8Xv`h{x84&rKbew!v&b4viYdGcvDjRQ|O z0?@znh7cJ@#i$EFSFbheiZ2Ai7#E3ouZwh#2M}lep=iV+O!KZ-1X0o3czo!)RX7Vj z9uMGDS7D=XRJX>CXDV^tp0|Ms!9uIPf)=q%Ob3E3tISDaT4UTzER)XF7fMvp9bfz? ziVTCnZ=0lk`QnCgonyE9>8CknODrCh=nf+hvBj+yIG*7<-yeVG#_uv<>oA(^lxQ=e z$EasCkaW5VyC)YMIB|sgxJ|Ew!gc5|UUMla%ZiM+87t968DC!n>iF4Se)_plrxH(y zGr+TTdTpv?u#8%6eEOK4F&1f5%){}?=YhbW$+7s7<5S_YQr@QCgP()X=`HhPL5YK4 zg+7S>w(qZO24y?H%j5IcKmT-sAY5$HZ}3QqHxx?4ys@Ls$y4|BCQC6ZkKlu5#6Mc2(*zVeX|IL0pSjJeKD1 zj=EcPf+_DyFNxDP;2pKT_t9A{CY4`7dVxw0WK+<$UQ@8A7aW)`AkB;6AAR!c}aaJOE*k+3jkk0^0O$`JOEk@fPeFE{!O1cTM&!Q`0ws4pMU;&U)Acy z$)<_6K!6+ZtC7D|V~qRH*|uUiFS(UwnpCvn+>SpiE9^LzE^O0{z<)zrXpaHV|7(Kd zY+-!jym;vNn!A5R_Jd9Ba1Qjcz^CU4Wi5qMoY7XL^P^hwj$P^8tuz=ntXca?$32;n1Gk;R{WZFV02*Od^_plt3Rx8;Czp=w9I3FM(4wIDJDu29J%-PGS*gP@Km= zm)<_n(pV(&9RwWKwrWJ8ek|0Xu3S{X&Rc7D4S56am>8SjZ#HO@xOp05Qg{+S923BV z1D>s*2@{fMCV%zsK9m3J|L4C67s?S-(%YH6LPV;eK>cT9ZL~FHt<4PKKjWlEqB>|j zt`em&eC3|!agUa^P|J1XqE5vaWH839zX@U)H2cPbll;p+{Fc0Nzp58dts@SGNcB7u z@PCyZ5X0E{SEaEKmah&W4Ect#O}_nmf9pX#^RF6L{e94*{il4^<(}wUzp)kk--BwD z6owwwOAPdI9`5}C1v4wd z0X_~DaN=jo%Nb`(o;!W|>8JhHv-Z7he6|<>Ej6#`x88cIKZm#U%%9Uga(Z!0poA5rA7H?Ed@rMyS?;RJ0=i?G}KxdiD0(Z}$uvQQLd(y=N%b zK0*8&LulLmpU%hJFikriVd#_UrdPQ1;1>yuq0p_nNxtU{%LlIhMv!Dao#y*lpd8Hs zv2c)bDwK{3(c^*3(F$pST$`x)6#dklE58*o6(10NW z3wj?BOszfkV9VjMol-mhrC0&up~hRI0o5YpC4A~_x=Ica=>h9drbT#jRfv`l$gM0S zEs6gUoMkb;K2B)iV!)x(>NEZ$b zOkkWRvl9LIq+iw-edmy`-3wmz{u=XtEDm^CEQ%<>L3Aq$d?y`X|6*@k(7A8TaX~P* zH2xiTK}YG%$h4bsp~{D#9Z6ciHGh#by(@)e)u4N)18k02(n{hX;lW}_f3A|UHU~L* z5o72N5TLc!u`;eky{iKU-dG9et?)uZC}cylIqGO*I1I(yz3;~VAADQB{f!4{5N@CE zefU{maM6_7CQN%GQj}8Q!ey>RryL%Oaac4d12vr7_-&mqyrPv#xi?HRYF`8o*H(N@nmcys`LAf`|F@p(!ULNA<8uMes#g81=~Js@94hg- zMf4&8LheWV%*V93go0xRQ7UZmBDS{&0PH2(@n^pUp#T2GFMiQK5ihN6pl*u*F>$rc z)j8cA0k~bdTLAb1Qe&95D%Dn}j)=7F{Np=_yd42}`0$~55Wt?MJ2G$3u86S0@5T?5 zs}v$yCTT8Tf@>WJY$FACG3CE{ajW;M$FYo(O2al(F@KCc#V`^mTjC-DcE1& zAfB0spC=v)EsO>$?I~C3n$D~=8GTWb+;Ns(vwe$p@X*yTUz`|sC~Lf5VfdOvyGBAf zj0%x(k%#65LjlH}35|uN!V(6ENg4?qJ&w6G4b+CyVeBw+KzC#WsZSIZKOCV}h+uvs z<<^Dl_ff>xzybBE-*rn?J@`S(#HUFkZgMPfwob_CBX!K{1f0Iu9(=`7i|ec`#fS&1 zV1W+DK6ZTRC|h^Tp_QRT=vu{m&N4v?elw5lzG$?Ye2*r5p{S9=+1;+uhU#8j2F)<6 z3_8Zn<55iO5qWb6#&I?0&Cr4(d&G2*!M_MFXCAmT`Xrr$L*DP(hM#P=Y`1LN=CW;b z*{)?Q+vc+EwTxxErKg_v`TpMj;e-3Suk$>P5_KPfJ&7td5|*m*xH0z;$3`-KYU;}A z(l7qfc`;De^!m!xmQD1V#Kw`lN*${8%yEbNR>t8b-q?$s&wL1lOUf4ym}9LEhz)`{ z*nNZ_=>yJF(kLp?8AiKaK+q9spnl&|!n@^*$mih}E`ZGX7jCZ3T_Ij!&g~uLKbngk zezv$#k(4;h6mzZmw}-#)cLFMhH$d<`AxnY(4ypIeM&$GCi}8*>>cQ@%*G&-hf0 z^2O)=gA60OeF_R_k}6eInX31E#7QcdQ2H1sg0X;Fwr1U+jsWd!T7P}Xz-_-lP(FUQh485iA^N!C~LkooF;wu%RJ6=F_rF~d+*iiR9A@Yb*hcI zG0?6nz=5ARVPL96ovFFRffjf9XFtVha=QLnS%f=S z!0+biOwMLyEZLX^WsP}Ow`NSO&cf9-pM#nIgu~5{Ph-wz--S_oG zAmbNTogWCss85uz(}fzxzV7+g+E$SihF_u!-&0c=Aca{2rNY$4AT6#hH+&D`QyWkj z_hib26nZ&-D0Ctb=_X?QT|~t(Ry7DCN7$`nxxIB2*tE}+clCzGI%dtV|tXGH`p*B&D1W;+n4Fj!l|v=J1)8rj|dQd4p7{pqs_4s+>p zFZbmt7tg+kY^VD6@dHr{k1f1jKMX!;<`Z{}6=_=Fb2auhPS^Ao0;cpbzR9~BDprh+ z@=ka47}(|q<$vx8wFOC{MR|tEczI44Mb0(9HZEvt4K%Q&qTM7*DHtWdaEg#vLNoBl z@WMF4InOo*Cl~zWc1ZD@7gHz!Bp|fGWsfx8(oRcU$EybobWE#t8yrK$m#6kf6{-?CvKkmrSDSZj6jK%w;F9YZoVOD zlFj>~cA`dbp3$;?nxi{F9Oq`!%5)%aN@uT53z@}P?pRuqM8GNcIb}b95>Qq|t{m$wmT%{jcfg z)LG=;u3vb(SPY8>m3d4IuB*@q0D1)78<56rQkff0Arc5TvNhvmw?&3cynlVT#wQIN zJb1ik6W&PYZ_fZG8pusTRJS+&OjvWd?M14z4R0xl8~{S}dU46#kCuXY<7)X}3RKmF zLGeaD;OLLrc=EyD-%>3SOo325Kb%#6*)jqS9OC5%q-9{jZ%0oDAJA9m+YNECa5?T+ z9lnv)O77C3b5c8WB2Cg=45n-h)r8E?QqWmBPeI8@yTS7xEe zfOd8_ygnyioNoewnc#oI=VH=PSjD_sy~E2d@B2Iu7K9Dv*ih}+KCxD&?%yL|%i?J2 zDDZk>BIg9e|7sDnZo`bNzo|Y$zSwZ5YE7ydb^?PFLbHCwIvQ`)+Id*B9`=uA?`r9p zGSY&wg|&2QE=#X`uY(DWQ~GMJOL4cPMBE2kPWnj>rBT{wGpUNG zHE4u3H;Wt9SN31(BK6MuxBLFp1}q)FHFt*6)WqqRdKL+^2g8a!r2{s%?>k!avF3WI zpS#tnE*%e?X0kCq5)0E4ipOyZBD9W$kHhk-@In5+yNDrfO-_Zdz`(YKvtyJ6@IHvJ zqQV#-nVfn+&U~#dx@|zhsB;;>ah`9g=U@X8*cK=Smq={y zX7x-8s$TDJfG8-do_Bgf(@0)o_aqr}$5gpx5nT3WDe)g2D;rM1-9MeiI7Y79Jj`ou zSiTQBjg(-H+X~6#P6cScDR)LGva{yhMB*Z9GHS*D8{Xc1$3F;W$+CET9bCAP9keBP ziFp1iHt2M(C3@OGPwI9`;mVELdG+0jvGfPTQeZyy6JyayDN(_y=+BcX_ZQ4T*p_+> zLh`$aQG`8r!$DfDTfG$d+iBE_lvWf`vnAZnm3wK30f8K(0lB+2v4U%iq3=rC+!MhZ z(C6+36uYtSkzv1=)*^=>&~VME*R|!xLUHkla7u_dk&Y!BdHG5kJb>1m5Mp@4Ey-Kx z&shV!)t85OIOvkJNr+9H3or)~B_U1Ys!%k;`-Oy`e?2Xw8m{M03B;hS+Tu-45qB{_ zNnXEX;5GTDrHBwH;oRI}1nWX&(3J0uKmT?d>hJpeKzH;M*^UQ+OgTOa?p&$Hqww!Y z_%DIzR2K~HJ;``r50B*VE=TTl*B$6yPMszWc)H8o0V17d>Bs|B*7SCJJL@NSAApLB znbRYEV2V91qvb5C6)dgEh}wKLrJvjg)KpTx`) zWwjmUmpR->S?fL}ul>hQQP|k*1(PIj{B7f&Na;{eVZo5h(#UPrCC(Ve!#}Ym=$)pg z%N2`YT;+rC^ojl!LLJNfsa)D(?yBO*%x>9_6HK+^t0ga&~7Lo@a1pRJy<5_DNz9KRTa#Z z2Y)TEH!u5r!@OYNk7;QlqB`F|mpx=vhb_Fa);2)g#NykL2GuA` zL-a{v>PVtvbb8nBj<8pGdYZ!T#r(%nS8W?r6)nr_xhq&fuPFU|n4(UmFkcM8TZ&Vw zl=~jL?Mii)pXw`bvxto_zc&%JP4!D?@%r<>{6RpD@|KW*?QA8$(m*%K3aFK}yeRn1Qp>wR5U349Hcs1;WvG-ntXVl>Rk|9GW@NS zHxsjF!ifK2T&_HjWu`*wmb4M!Sg?jS=l*if5%oE$4$Tq^YqcyJW7kalYPMA#sHDJhFxy4%yeGJ# zu-lLLnQ8vXBj>qS=$|?L?BCe~ zjP~ZB!6%x$e0qU=T|mH1f+-n#N0G?$^d<0FIgM5kL;b0aTfw&s2|VbVb0!8gx*Pdj zaoOI@Zz$O?k?1Kn_q|%}KAjN!*PZ&e16B`uL7TkWw`(1CaeO*wUW0LO6oX1#c`~*L zaexG!O(wwAyD{j=_}MzzA?9~=E1Xb+8hq!1NEhn*qwLp7a!7D&2bV03qnR75;@|UGAX99%PCfKx211` z6z4qikR%F}Rkg^Lw-m*i4&5C>R`|OIR((AdQrT$_&XvUcc zf@RJ>=3?7aX^@XRa~8{ALbs^tW?1pesL*)^f#2CT21)j8X8>9jy$6})p@HB8G>!Qe zqcS{K&b#JMGhL?0_LJRFw|hv{a@cAnn~fT|95^ynGu&+!?pI0Pc&6!33aMP^@rFaY zH^{etE$74;T&5iAPWv6y!c+Af)i*=>i($WtdiN>}7kC&q<3mwpYI|R!@w|GNkSElH z6V4$U7+@pNW=rv)_62F=g0{OM5NGE`TZXWA)9YC|Hy7EXS)q`n4@y*=Zuf1F5Al28 zG479 zv^b)3Nqk$&Ju^X3Pw0D@Da6=+x-iX;`wiM#@iBEdk1q_=cZk`V$r*;Cqj)gGC~aFa zMAA7uB;Y4V+KJ=E+4ZZ7P29Fvm@^?8m02&uh?~b}nQbG4To!|Lu5c%&HisSA7O_np zd}O6ZH?N+%P3eGD?jqy*!+QF%x!>el{QSwJyo5LEXZJXhb{q zk(I$612-YrHdMZHffieg;Xv=5k%{9CmBc;TW}J*g+e$@1|teYo9qd$@~jzNT{cg`P@(hXIjE6pnRF$=cQPhBl8? z8=0U$JV!^#CI6hod`PZp>2O|mPmd}@=Dn#7pn;c=e)J{#jG~Vr4^#m|Bkb9{+kfQ! z3bP8q>}ny_EJA_rk2ZWR&`=3*+MTWBg0qm6@Lq^^A|Q^Gi8w@Me@puyHD65=d0>m` z8-~a4ZozVd`K%>an)@kXT~&X`%RijEc4xct!Gi2F$rh$aZzNnicp)%4;acw$KCOGI zgOnG>wJ*!sAyGo@k^$X-h|eSq%@L?S(X(Z04MTeudor+sZX0Qe;Gd{1yr<gB~+@W9-3g0t4)zt_Pgun`AL{=ANuewqUfJ6 zfUpPickp-ung(kCp5BK@aIR)RL7>&Z9(}c!XA)w-WzAw3mi*&tcTa!l?ndg}`Sd=OS zC0iJZ$8M6)eh>#Yj8Xrbn*x+lGP~^3g^XSCfkqWQ@fuZ@@`gND6_ad%myur^pO-x1@hZA87a8aH!Na@+})hShxwe z@%v*2XbmR|=B_vEuNvu8&;Z})c1rD=@ExbEk|kU`X->MQCqI9Id#64`>@~kie~=%9tzHs_l!}7xPGK4{+s`1kwFxB2$@Q3 zFAP0W{SO7HYcYE6^B-q{;;b9}+&fpAA#79xcBas83Po~D=(E*?jhuIGJmcx!n26SR zEAmeOxWs2poO_|jU~h`X?$80FQ+6EATYR73!;EAe3Z(8L`oz2y*A?zIty~a_w(^4b zzUtYG>&>Qk=cPR|rH}Dkz&Q!3@EohStgDGRyclB0R^v&Pz4_pPjn7yUqH%3vyO_)h zy62l3y*zfsXo5q$l48mnCq`R7&Cnyfs%}ymomo}W0y}@`Kr}Z!+__5>+p_SR+2B{+ zINVOkGIMCM)?(T^xR3a}g|JB+f4mbQQ&5Xh_;cZO8pN;VZ;hStJ<>nkYn_Mmu(oWEfxD$XneHC)u2D z_&5>qV*-C=0@wttNEUXjejp}6=T=)f47o42iC!iq^)=)juW~W81S=5RqvGXP!V?~1 zB2~|LR~hu(nc#uhiDLl>9?k_HGazFTa50fRo#Uh|!j+Pv!+HA! zq!;%uC{~c^!-C@zbWIAf;rQ%o{?~yIayD#vC^+o`2F@|0IL^$U+=zQ#{3Z!B_?Bc8 z?D^@aq5o3##F3-Pr{lv++D6D9f=r-MeeqR?Wuo>(#i&ZF%g=Ht>_+B5sxv35!ozZ` z>dS<>bS(OZGI*0vrt-bu_35R{AQ%)aEFS>pD=}bD`K3u8@E_vjS~{C$A}aI- z%GmcFbV^MbvEl(6$`_YbNk&2P`x($)+#|Fc0VSukp+*6Jkeu*vD76`9Fr1lb5)QI- z5aSn|x)(rk{B6>%EE{*Y<^-(|ZThHq25r1>d@qA7wihKfkE^b_plI-SM#jyF>DWJ0 z#4fJ@x2xG&Oj!2)#MY1wa4=awrgkKv>AFT@aW3WQi30>W^*+*{eW4u@`Y6qN4WcM0 z&?Z27+}$+oQQ6g~?<86sac=UqnNV>8?pD}`h z=1>3NU0fD(S1&@=>LA)mmBk+j_h@+|vcZz+(%b64USj|D=K@n8+{fITh& zX4MNnL8jrD0$A97A@%`OWJ z*=B38wJ?gbe7oTZaamth>0Ozx^zY=GdiSVqgQJJUf$qq^G!~jR^My@{VDLexFV%TA z(5`A!B;`bD?zouo249?Hb)`O4|6H_#Jr+&ZY= z%6CM5kL|3jD&xjB+J?;w4t2XUsd{W*Q6mGd!twq_*SsdRYYj^*5MLDh2m@pO~Tlm zt~Swip*lQdbo?L1YusCq$WsC?ZlSeQBB zDY%}C8D$#3(J53orgM9@c!)Mo6H%ZmtVskBq{pa8?_z&0M0|}&DOq+pDJ{sG#%L`0 zGxSr+NJI;h1V;J;whnr&#BFq!BGE5_nB0d-%&PU@-@G(PIqDcbp(QlN5EDLa@+epnA!hlXa!+o*&zIJ-0|a#d zRx&Oo9eyO`r(ZL&a2HODlwquk& z9Js^mq=Xu#_7@R>GYOA9?NP7rBGZE{3Xc?~}g>~JC&@Yb5?bhiNJr9C5`j+gyhm7vb(Kz8VicD-NEZoU;$UR!7Z4%}a??|u5C{}yKqESBkW82=BvhJMG;&~u-A$vLfWG^d)>vJ}Yug_WTP zxko*gt~P{?32*vhN%FoOQm`VACv~gMD+$n#%lH;W&TYpMHlxcZ{OCHCcL@8!`76-} z8PJh`q||cn2x%o%u7mlE z8i+B}Rmeghe|0Oadw==e0EW&2JY%d|4RLe<6{KE^55@L(`21&Nh)x20dYoMa$@NTa z7{~NE&vMvCkl+cV+XbydjF`STE;BvE?z4QCIhamf~;D zFAh4}%N{tlo6`HBSCOMRk+*HgPw*o?Trr>0u18#vdRk(8Qqb)md=Yw*y&!pfcHYUH zcP?mm@*|{zyVEfFphxEBxBP3w?ev3Lu=nqz5^vm;CDK6Sk(fEaMTGbk+Me7q3Ta!3 z8m;!HTm-Mu7L@#_v-%#9Ef8B=-FK}*YOGh2q;^B z8Bt|P>6U3!Dcb2BN96}a5IAR}#P+TD+H{(sGDj&SYYSX2VrBe2&zF{fXqN+w&Cw0k zrv_Iwiif%To}}jc>L*8(F7!}jce0_OqK2(~Q7ITXnUpLsjKkmQ1lsT(n(#A~R$lp1 z!sjjF`Rb;!qP}lN{LwNLi)w~iwed$BY$S6lOyIaV^@)pDvPTL*gN6*(cXuA2FLBoc zC-HC9WeV9kSY0-QZU2oP>&`8CC_>9|SxDI&@!{%^owwpdki{ER$I-UoW$Ii)3Z2}A zuSx2PMt$vMGjWZ8j?E8I7DHOwz`hNax%39G(iFaORyU_kL3}Qtv0%k9hW?9|wEitW zigY_JYZ`b%0>N<7ayTsaHb6&wV6l^V2Vk`Vwc%y0n^pvfXkZaFBW`Q5E}e@aKTBp( zW0~k=nK!^K;Ba?0xnREl6u+jhD<8a5=&;UM)|QgbW3>jmRbEFiB4?8@CLY4b`ejbvNpLsYJIE#}3j*MzEpkArO~NfYtUc@jVz+0Q-(Q z4mXoXp+EIQ?~-5?C-C7!d=mQ`La-{jxNz~1pt`}rrrH3n1CagmQCnsvW6Q^AHi))> zmb9%e?|Krvm-=o3q}{Ni$Xb5FV_&$ru<0IKl1-AG*9FZ=K&PL=!OQauHq+^L*?-TL(m=m2M~5Sh z16F#>Zi6)?ItB}JnOJYVrzD?1Q}V*dg(giclQdUL<{d^i`}#iIGoJ7@ABPYuV3E1Q z0JE0&JX}g~x?)|T<$27tz&L7iFF*7)*zKTuU&})=^}hBu(Z~IQXa4$F%V|?+1l7KP z^G~cXrMIA0#kD|-Q*NEb?0`-r+n!9T8=Rc2ICR%rM+O&vVMW_LUaAM<(V z5pNod@qzGb()LQiAEJz?nJ!GRF)!jj-gGW%EqwDBz*zJAa3aOK0Z{TzIhiq&JnC&B zqL0kaY0fyi_+)b)pSkxz6S!?VcmtR#zBEc%tidgoa~EMWGg5zo9=0EN`9c6P97WSk z!a;^TP)O;jvHky4yI}*aew*OU*}n$%4UrcYP5V0;2KA=3k!CWK`9qK*r#SZ<5WE>n z*O+l<0;%l0%6`s~g1Y>{B>q&qTB-M-M?(EUzqY9o3*4Rg$I^=N7Nw9N^MfGhjn2ps4}>NU-lI}pXs za&P+O|D{8BxSs6k-@P*0bb?c2p0H;bY4xDK2f<6GbAI9Xg?V|b~GDcZ0 zql^5@-QbJ@_#+;^p{ET=)SOizw->!27*0Gw<3a&_J%QwPX*7n&tG=_Tyx&!By1sP| z$y_$a`1DPuYXsGAE72QP7RS=ubwmVxm?Z%cMZ&32BI3kRcBv@0#60{Wc*9E|Gz2YK zM<@C-pQ>SN+0NjZSUhQlzg}R(_la|kX<$KtLHUfqGH8`d)`l$1W2cmki3M zOQFN!w!=u6qP$`WT{o)CZ9+dT z?}PM!u}yYvT5ps;fc$CNDFCC=#It%D9N_k(iic%r+B(?`TBc+QEq> zVG}h0ug}eIK_r?KiL5?y3_7#F*to?i_C!2=2L+Uo;Dh4dC$~TST7wSP_du(lf3{%e z$Wf}huD`xA3(5g#r#Bm#9p(WZsn@?kL+02UxLrD;N$)64Qgd_(z+vvE-K~l@yv8~& zwhpK;dhnaLqH0rv9;YRHZVkPr()*iUtI%~N+);TsS6wog@kgk3KK(M*+G~`9WL#m= zb-A1Guc`LGLMCab4qSa#EJuI)ijH_N&!VkPPekV6+madg3>+;{r~cUw@TWo?>xoH)H6W8k_&d z5D+TV)sI>iu_98@qUNAsDbDD$x$~H>)YW>mIs7ydD;YO@D4$num$ zc6JA^*CDBABCmndiL|Lplq!SJ$y~9sxel_d}LkeG(=@Ot_b7rfbNL+U13D z#KRclBU=%1_!~)-Q|b_RD08Suu7VLl@GR~a;W5OX^~~7mG@KLfz>D|pp_B9|MK_6# z50#TPHhXbNluW|};!`7>=tWmcybS^=*=Vsl>|{;(B_@)Gw5muq0c87}=9cOZDD~>a z+@+DmA0wnT+Wi=!_pjOL&zQ#)ATvB?J5iV`v<#94anvmV{p%X&bD& zFxg(iyFy667;3@ge515y(g) zN^bc=nNcJLiIl8_;CZ`&=OLoUT`VF^)&oXN0-v}2 zO)e5-|3W|WLXAn-$ueIlmVTp6Ob}OR`C9X5xhA@LLR12`N@qY)a|nMk4%^kYIrLze z9YvaX%CbN6VAaY`4A6p>7AwWa1)vwP1SX2%Jm&*cKcVkApOBBMy8d?6D|k*nUekSS zyn+z3tUez^@3)brMh4`&!$@2JvX4J{Z8{RV!8u6xi z4p>~TIw^Nu>Pu_BFE-KiOE}(GZ=5J_Y_kIlQROKOk0OPKRu`x zYtd=vjn4iXpfjHlYkp>lMDxqsNp(^=P$*~9FlF3$)GzpFsbAx8saC|Gz6xHum8#z#VNYM zi_;O%loMJ&q#B%-&?>JD&UFw$zil7{;VoU=(1K@$UGV7%=hhjy<+%)e|JjoFTCnxm zmFjhyYip4%q^?;>3D}*TB&iL%RR0nMWeT+9i0Msy$?aTNY!r;7-)!K4{_(RJ~xu z$Mtuuo(3@HIOvf>JC>7blJKBTiUcns89 zUhkx64a0CEKct{nRuH~$Ke?Z8s@cip>mvgk^4s+Rde^hkc7scs6r!Mym%D@fe(*ZC z|7XHeMbKLXgF`(yMzmQbfCj$%{1scgtzdf<8*2sZ0ME|wCJH2@%?%E1{r~lHaBYK# zFdkO4jj8D`YOW(;UK4S7 zoQsuX;Jc#GPHY878@hkfrFaR_Y}nhX9zNnO=Qd3@(fPg3wX?MZ)}Q0`GzKfUG3H1) zt-Su3Of+xpKSJ-O*QL&VeK^o2j*Y%_*CCh5Sz`|kvEQR*0SyHG2y`$Rn4}dJ9TO&G z#*^Xu%9&9F**8Qpg;67jv3poQBekQ_BEpR3yzib$Ju$>-b3JotetA0#Xh=p;3o@DM zi~&vuG0!#z@Fns3F>`>f#EgkZDQ znrN@o5-1La6=)50q4d8-urZ$=)qVdhAT2R^uJ#M*d-<&>UTW8O=Tjk2;x z)nrZo-k)Y)z&`HBE0WuJc0Zoa&1}&8ynUHiao3Mo9NdvhCxAX8=!8N~^Q5^}?PzHp zDDq>~NLcEF>7(-o2(n@Sth;$B*a7}DKPfnYO2#h>M|%sTFEC72IqDR}H{l~|N4jlo zRWI2}B>8O$=R)!kv)sD+#Xdm1IsZ^OkA(<&wm)JI;Xal>AQvqW=h`Iiovhh<0YBpo&@88sp5b?Tfr_^_WT9eQ-F;ARj9c$9p}_#$KC=-+-w%=Z_}UzR_Oyc4MhQ zL)Yuv!usd~pPNu6aiq!8TdgEAbpfBZQ6jCg^-HsT`~+p)kD+Hy5PKPuv<7%#f85XXMiwQvUas#);>CFDxpLON z*>ej;GfZb(=u;N&*_$dDzisKhGh-{>%hTV<8LNlP#~OI0jzmwQt0%twda?UH*3q)o z8!?h-Vt_qkH__?f?r%dk{W0&&-Go)4s-!zu$WlmJJVJAr9zoEJuIlaZc(IyDW-6pL$Y5W!T zPY7@jECqDy(}!)^>7->F2Q!5LXb@jdbu~|!Q!XY#Uags!1Gz9V<0f%u7ArR zzFZ`qFiBP)!#J9|F4S|wrFLcllijoDPWvNN(-TqrDw6u@KKfl@Nr^la3-?|NNXeFm|JJ#h(5o{YB2q!iM^RtqX?k5JTONo zq?;L3(UG*d7yTBx(qTdeh#yYuJjJBL)0|LpYpt-Dv4XB%b=?*j$0pNkmfea*2o-Y5 z-zL1f2bQPyqoZxVxQGYfNlqDFy3~%feuXYk`oI{Pr)v093WE%ZAo>iyP z?=apTh6(r5YpI%sKw0i4<v@lZd7kM_2K`pz%c zh1V|Hebv3h{uxd;;lpO;I{Sl_i4<71_v9=zk#D8!lZrX_ui!SDj`4Zsl&hK1!r7~u z(2;<5R&@&)~CHWN?pHf7=Vl$8(>B*Fjm2_s^O(Tf1QFEofkY2qFhtK4p%bq{!$kVWG$PXsNji?ccjk%QX znl^11@4=59W3~+Xpv$bUB8P;&1w$3m%;{%;N&ClZQcRsy-&H7GzhluEH@qp%uCB#d z_?LW2`uP0ht$R`8dc~ECuwKO+*CO5}rlNdY|hvP_EvdEEx{f zfoH2WTK5w+SC$zUCB7b6Fv}(EtJ$jH*XZEn^CxRUJcqgm-q4ROH)7^D&W8I0q`buA z2TzO2CbQXmycqL@_r;LR7s@TVzhA%9-Tg^Ik~WBr|4cki9LJb%92k`jJC4T58AyO6 zFk;d=MLsCx6n-&Xx0Nw@*J<{qlKM90DLY^q^raqh|DcjB|A0v3)ImG1uu}~mPw{Aq zzsQ{SR|6FezrP7(BE!ox9jQeyb>gUys;JhjKjL>d2M*=lL}qiXR&q-=Fhb&<-DjcT z%;g<)0=ff-9S%bJ35^6*cn-jS36R6)t8w-}(UQ5aqjRw#!j~H6a=qU$(R3t#+e7*% zcyH23=eGm5=Ck>C91({p@2bS%8ATTD zR-vHPuyc#h+56GGf;6#!7YXGq8C4*|@^eLsk9FZS^`ahBE1C##4D~!E93YsFtxvW9MQO3EX%Q>XbeI0 zm+{Da_En%b*+q|9&Xb#mHQFT4sSpLo3w0KmeekpY9b8<##Rz5rFV+4+0B+7Qa+KN} ztC?q~H*g_|b_f&y8uBZ8lK?toGjNrjRgxeIMSy?Neon_aM)vi6{M*d?Ayg@)at%=k z9wqdlT{5$9WA@R=w4?OgR^O);y+3Qcy^xb z|NKEl#S|ZfLXP;_zyZ9H*bYneYV_;EcPY+TZaT9)9W`si&>ziakOmQhK$w1vz!&JD2;S@=yq|F&^L5$NqC~oqhh% zSUtgBTnViGSGKPdT|VMSOeq4tLzL*^@}23RJgf`n=$;vnN+jYAuWe?SSA5V)35nY( zJ0PN$AqWS`DOM+gpt}iVAf@HOD7BjA%W-z+`$M2II);nI9Ab!@{9G}MxDG$u6`pUu z-yZeTlM4R?n=*2K(NSt1R%>?;wo7D7K?$$$^-JV@)JB9)m)*-;r4MP-lr@KeV2PQ~ zOLI6g{Bz^dw|d3AJA_1nDUczp=S@JM%M#wuwZs|twjUvnx3$O; zMAE%-C1i#yS`?*vE#G|vefCs`AQ_0*Mc~IJ#2kzpu?l-q?#X(|Q>Rd2xLgn%m+&(B_<6s!D>FH=PQP8M21L?OVZVm|TcQJUl-JKyDp z--GGT?w*!ZLfwByH8C^!J?-as4AhsU8eq?hKV{?}4Qjk7;YF6;4J%(SDYE*LP`s|O z9}1qcaYJMYG=)7o6W$PxCp;;IehZ*14Mit~oVj_L9b0dR^*62!vqrj7>?5gZp@+EN z=tNf|c3&Q<41#T`zG7iiMyWWm9$g#Q^8+HCR_d~-lE!*530+!C?b!E(K7U=+FyV?N zvHUH{F(WWQS<|^%$BSX$+4#RFKIlUXKeZzDZa4C>M}A2hzaY(b5RIx|>m2SO8~tkz zP>AaQ4B$tQx=-!58w&!vTDqpKle!x%e}U2)rta?*_yFBF(ZV#$yCC70+?rt^m5lg_ z`a6Fw)KXej#`IZV>=3%lN9XU3w<_TiMujEnaT8GzY~3jihI_~(e6w^YUGSH?a-__E z^&=mK2&um-Z(H<_Kleu>IS2Vzd6%-dQMzb_fKBQ@iO3Pe?2%lAq@Pj|#{#4rlQ#zL zXWf=__eK(`H*rx*s?byESC>z`b~0#FI6Yrcx|JmOWGtW~W*ciR-+f2Sm*4GQb`Q&e z^Yf3Lb=xiYf#Xj0CCE5cy-!x6m2- zxv$K%|HslfuvPkgZ8+O*(q!AVHQ9F4WbABBJG&;=)MQQOWZSlF?sxzG$NM4H@jUlh z*L9vfPBViC8(!_tonT?hpA|tsbnN`oR$zDccUg!8Qqh3QiG%-blfbK{h(sQrW=~6n zMB|Egyrue+S46-NwVUXFGi!QQfql$$4LSJ%Ffqqp2-B{ud$JF%2^$vv)3Hh}g>XqL)9jcKsgr5G%i#^7;VZu#%xi zCCr;DX}8$99h!Y;Z-@Kfw(RzM#p>fMH*NF?WC{@FEpussxn|=flRBM7Ewwc&IEfSD znJbjn%HHgHx79lEI)C`4ympHC?=}h8llz?r{KWMg-F-^-WWs)l^vN;!KNb;HZ#OUy zPR-z#borJzgN#cZw}o#9&7nQd>Gu>YdOHUIR1&cQNguBD6Fji*j$Aa*@-g*8(cSKC z)q-D7MxD|Gw=kE2w4*RGYz@hgyrK9hsXMzaeDan~%}HO`ddSf!v#&X5yGWosW()`; zYKQ%lLuZhn`4l8yfq*ZJ=80`bPteSMbmBz#|My<{ucUgRIFb z8_g-skf!)MZJMHE%XR@92Ln30WiN4)WNoD$%S z7Rd?;%terNbf3OWyaYzLPl0@P-dvc|&5~Y$gS3aOq57>p4-4%r+KUw-9Sh+$6B>;h zM}x+ygVzeml)`}6!H}AFY|Ofl5=9Ho6o$Y~FrjP0@|0(4u2gl;N)T%L(1{7kxmU-; z|8HOu#Myrr20ZAVccjPm``!QcNO;k(52Bw#pcc?F%0~c-slne_PgqkokP|6H_Dy&4 zESdkkTFr0R{<0W|^o*1Ggb~DJ1eHnA{ue+KLI-SwSh-ha+3)4=P{r^R7x;#OBDtn7 znAIT}4*swlU3jhX8uE0XpJ9habQJ}|>XpH1GPR8Zp^6J5fu*&Dlym)SU3*zP1d;EK z1U{`8b=8_CI#5h&&Y_m$PPP_N510;0=6kdrfh8hMHHn(3BIR6`kW00a{J9{#OiQ(qmnA{9#^!m$md)ItzVm6B$M27n50QG3q@ zQi1y?`aKLm!XmzQMgSIC(E5&%c>7=BX}j!Vz=I&3leyN2Zt5M#jU%V@2`oCj!x75 zqFE$F-)zNt=N&Glez{eY14^J=YYsRBseT#;yzCRVoVmN{@Ao=62!dFR`0lzDJ^Q>o zl{4A#sqoGtJd74DAtj9sKHL0!47 z6BD=?5GpcGFDl-lRZo03^=TZXe+S!lD#$ws2I8S}4y5#L2b%@4*M zI}PTkbeH0Mlz+sS3ycYh8J-EOaxalEB`|9@*xNb#xCB2{@3%^`+>I*(?5f`c2)Y2D z=p=?uRooxwZ5GFR8%@nE)=gwXJJB6FNiMx<@-%zTas7tX{i6Do-c$p+NpM9JI(fZY zd*C#cW6RT}FyK0$1Ud@H4A*nwe(IyG_;k6^a7fs>qIIwiF7+q$-D!HA{64uv=wVKZ zozFy6qvw_Ec9Uzz%*VX?kMsrGXv+@4v#Z?=SDWW+*S|$!*2KuJPaK5#bx#1Yu-@k1 zXjD0WLB_RQJYS??0K?^nCiv2pD@`c@h9TR(0iEOTOoWUI;;a^HdVns@`X?MtAYuktGiRQ=zu4r2K2FKs{eAko7DKH-=uii;AsieigUCLs=E?T%pc9v@ZT@e6Qk)Yy`hW z2*F9ujq)vBRNqR>pFJ*7H*!9O#p+PU7~o=YAh}ELI}t+BJCx7TPa`R>SOuwFl&7c= z1}C9qAV`#8=JQTBdU)LuUHKywhbacCu?AEvu3t|S{9y$>dfcwdwbHzFxlslSXKaFy_{kq|rh%8s|0d-G& zB9NIwdr@2TkFyrelXL3EWomaDJ-3-lOX9I)w{4)jOh#=pR$BQn1F>QuGx z+A${hcJB!q^QJ0(MaF_6fjn+fjR{_)c&9`#ZD-ivRixxLK+>sj%C2ZZ%_nQ`5`=PY zcW;Jpjwz-bxbhUSqSX9;q_x_b`X3|xbyDz3Dne!*ycR72!&opOXXrZ^GWJe22^;&! ztG`CvQYXr;EW1%N8oE(WLB{Fq*z%7KDe=-2b&ZnYRkmRE{Oh<-sFIYkW5AUZlUHeZ zwwHj5+z*RxoqEHZiGemwPI2*z7?H;D?2{u5&SoQS9V@n==)mB>!(ghG0?L!tz7^Z0 z{Xn_bYYBP6!&iQm*!DSe4)sj8&AX08Wl`3-L)lG_n8LW!9wgc_>#zDwAs~c6!SI$3 zt3(kr_nl55ZkNgHYZ{*3u?th!GsMxP&1_*pVdkD>?$<%dWUgqEsbYRdp={}rGT!5F zx0{~x@Xa4Dx-2PMB}L8A0qcC~L@a{ovjM2^ z%zYZf}ATOYb%#qSCY00@q#w|C;ZDOfvJaw(GC#mBj9rs7aXi6K<)&kN?du-C_hZWd^O!v_6l+w>qicoJrd?mV{W-0; zS1cCZ*7Q^rN!YV5bmQ=c?&xL~1VQQ8j*zz5xfe)1cnF;<63joE68~-=uQ_(-s?hc^ zLrkPe>=Hn*BJ~-Kx_iNFBg=7;@8Sh{MwY-s&3kS6>vX*zuwISw(Aa8?FIlX2TzooJ z3njB;)GyKCQcvYDqNpOB8&i4MpNV)K?N`}&O{JMpxkLY8R_~f*)ZaO5?Xc9iBnpgc zLQVYLc=@<@L5T!P#BuH{zf&Fab^a#4OKmLAR(|F5hNM99D}o0qf*Y+G8xp>Sb0 zQ9(>ex}=iVDVtaG!wyuAcotmO6r(ix-~_Z-8w~;8_I|Y&0c*r(6eGLBGugAD_;+E? z9(@#gX(fH-T!he&6zOR-f(DKQTE5sq7;{&RA@lv@jodQ?i4(y{5^5e24K;~G#^1uE zeez>42BUtK;)@d;ZH`VlkQx*<6A^msVbWiMOwfs}wzXrB4Abm0M%$@eD0j)^UWr z8U06WHo{gJc=Sl=(wE%M)3a^*dP)ect6ietKbF9{i+7O9+6%47_d!s%qs`}3S|?|L zG(r-hEm32kfVX}^rKY*}bylCx71iw($lC4A1nKH8C#V}V)b|`2IHa3l@Hz<^sQBzk zu#7ZuO6eAw`%ZcnPsDv6PR;Y){=S6qMlVTR9Da}y&+J8hQn)x)J($2;lHG43^tk7R zsi{ZLISH&+e^S2jHv3hr2+X^hC;o;&G}!K+Jm zIF9R2=-9!(=BH;SRaLCpzL2HQXpS*<6%#0X^FF_B8aZiFfsd+@C@q4F{9{zN>G_cj zFZRYctM>l_ueFkd^3x~&zqsXx|7I^M!J1yMKZYsK|1s0=^X2GthWV{yZQWQuzvmEc z4iA!N5KtfuVXdpH8mbd*!Q8zkRIfa~X;M?{z_AyTbZ*4c2kKCZ+m-41HW?Yy@=$hT zG{Q%#G!r2Q_QhS#y<5uq-{saNax6kHrMS5L;CF<{f7Mps>3g)cTD&D*(-kViw*H`& zbY?lNi()dz%2d2xz}&;>FW?_iiaD{}u#Rx+D zauQRlSKzX7>6rx#UzEyj z`?A?4fS0J*(LFywppbL8cslhii|gcL**lGJt}yk5v^_6>uZQ}YdEq%8T}zY#;#JZ( zuS_{i(=I6Oz4E;f4mBkoe$ebN78WyrwvjHBh_9m}<|*_BV=2(5JqEj@b*8;qJ!Btq z6vpPI&Z}2x%ZTVhfA*m9*|9ag)K^!^RIYECj#H29=m)dxXCUaDB#`IX{kgDjTZSG!q&-j%qk@s1(edffz|eD84k%p} zcsTJK$k5$=@n7|k@Fpe>w$&u_#!2V1qf4p4n*N_@bI8Q()Z;)Ps{Bd(FpFuqqTv@% znuZfa>+v7Gv^yKIT?z=Ns4YZ3!Q(I^t!o;Dg+IXcvR~>v#?Po`tS5+E0rZ_@PWTH9 zs=qz;E?m`8aS`?!P{iIPQ9a%i0=T+cSU!C%3i;QtsupvQR z^cq@io%G(Msok&b!{kciM00z_5@)~2mb%p|)4A4+0$3$J$SEf7+R3LdE!SwC?`umJ z@&6(-*Hc^*|5@R?cHeZ!v*!J40Wrf=4Jnj2b%EsZ-DTd``vCWU=Jh3LbI9$<=WhQt z@J~$4ymqDGA9d06!YIgXSqKWJ|2;@2CQ5R=>;^?Q|3U;2SsYKqL0JB56~jod)6}zc z82*Nu8@u6v#S^tJQeBmu+k7Uw&ISQO9|$;qO+B9f^dIIOTjA)}))MLm=U6p=va9PF zo~e8m@{9LeH&Fy?a2w}q>dUC$^QNu!4b)qoW7}&qN}Ak>yqH90fqP(weqvOVyXFP3 zHKuH-BP4vN_pwkUTR76B$au?z{B}t9U6fa$s}?j4wRsy0q7=@oy7H63taI|2>)4ZX zBX)4L23jvNM7z%ht;60 zYrD`%G{%rJehy~4VuxD6@(FOgW{@(vSPTf%eTIeB0jO1KENas=Mr#5dsBpg>@!}k{ z34Y?o3=F5KWLZSjA<{_t!J1_1lgN*@aF1oP`pnen7aw;g1_N&jRy1k-F_4|WNCzC@ z(coAk-4@qDb7TP9UVwXU(JT8Py0O9V^Hh__i#zx-r3mxhkf4}PiNEyFyR=m_n>_N`H~ywcVlTeo5RiV@{Z+Avu!GR&X2cV&wGW zJsB!F2im4q%&8f`v>HX2HF0|O9eFU9E3Hy*WhknrA&yYzJd<6}_kN{%^NwSIMGjjk zf%e-7J5T8*riev2lJM@C3bWw&2-^NNiibj`?I-!!EybGt3@X1}@)yP6;u`k7obqji%Ts#skVoZ;9gh4W5w`IADRjjOZM$4n&0;PRrco0K=UaB|pEPuD>L04Zx z8F&Ks1b(F4Vg{ux8-Lm0XcdHWe*5oM3qI>GOxlEE)nQDN`rl=5Imq}2ZcR2hui(L8 z*qG?wgT8x#;;nPO^$#=qh|!F@NZK`ITw6r0pB)3MsHnb)aCO}jwl_KYj@D_c*H`s1 zXZL=Ocv(i6gYFgif+S8wZ<-&}pkS8d&lPVRNg{hLGVn`-278koPDH8pOI5)!WqeF0 zT&@{B(wftk7*rXkH6=ua=#6;m&c_YLrRB&1Q!a-GKfF~GO^@cI0>piin&{LW2Ucp1 z0N=LfpQt``1f`B&?aqrs90z?(5S#eZBruQ(pNmA>_NCUwnga5etJf8mm}2~_!=Yq4 zY3lZlY~#e7hEY_Zu}K*VUL9aMF%`3V$|^2_6>Ln5$`SSBeFl*wFH`ae$ zVsoucg()6#lAr@%9H|C77uY9VD~H<=2q)BWBIXcUOq z#mps?fwOmEEbOjoIp(zrcLe+tL*o+APkEKy+YN&F0WB1hXojWG^?1woxE&Gjsj^-+ zT>Or5#kdXDa=E{u`#G-UIf8RLr(2(3>n*%mkpOdx9xR>L2emVC)$Q}(v)u6EHuW zdr6m#?hlIkpnC*JpZ5S#5TBceGPhycXx|xp%%Sdd17Zh>!u7!I$g_Nq?XKv4wvy2n z>ZO??e!!F+jjjaHNDJuFCc6)C6>I+$%!NX(N4!UBlmTdKoVexyMQ(%R4fJ_C6XPI_ z*|Tf!gpj(zqz~UJy&#`{`r8vO%SHjga%`n_V3FkG5l2Te{4K{-5$m^JH{K(T*jBb4 z&J7PidbHPdE^ByyL5c5c=MFsRAz-rS^S5l~d$5e%74_o|+!d&6%KRxElJ~w(%iNU} zUhU64uvzkbHV3|k84GOvGHHja#kBF=41qvO^lOLBud@GmKN7v_Ui&9b`5b#Kc+(U_ zQ1=!nH97t*T%O#fJh*tSTjnPn0pBy055__jx$^+(T;;NPT0_wHo6(KO*jMwRm@suE z_pEO?1+!aLw4Bexhz?%C%AqzLx-n46ST?_gmdelvMYmZ1m#Hla($_UMA@im^2KLgZ zxp${+CBNBgUsss^Fn(GqdM}1I$SZ+85&4WjJC_0{e|Cz?^vFavype5ZiD5#I+MURJ zuezwv^OQ%Hhf_gm?N`M2#~VJ2>DWPqpDN>)LPVs8wXsHhzxZ1W70+G1s;`7Nb{F(S zuROKTl1j-Py!ukU!goPA(G0k9B3dQ9(0^K@lPwWe@8ny#Vos5m(kGWzX;|rZdh13) zBXV9ow@5J|ZTnt>5@`9z3p9h(hn$tDJLN2AhituChb(m)(8Cz()}!%G9pRpu_?qVQ zQbu)*FpMSn&{bKQi=$4mHiaM?bZ0o*U9Va$Z31*qEzQ)>;HvFOyV>MP@o!+OFt9J< zP3a4{WTXo}2?HzXzU;v470j!QEr6A#N1$o1PjUD)QB_gz#aK`S@(H&oRRAqn~3Kr|AHg16!l!i zL=(aoaj&c5>2f@NdG)Ss)G4v!`YYaeLQZK+2bfBwt=Pa-u0?g1{wwbwP2@{WO*$N9 zNc!uYMECD^*K`eK+Ind8T7!L)ce9S>aro;=IFQD#^zeMR3>ENG(tu4x?}I&i!QTYO z2yKG-J3;)J68x{V802XY(ch4361U?o%g$f&-UMcfnu{XeS@A_^KLz_Mru$d6GhBYX zJHeEbatB|LDggk4Rvw4`VqZ^OIwovz(;*pe;*G@4#zE`kYq4JL2@t9O@FSn0MSuL% zyo0!Yw)qgaKg9j`e7o{eJpq4RR+OB&Kbo2>=6_+pLu4!Yc%f};|8LPhVmFm_vlUfe zr3B^+ZJkwUfx{5s`#?36LuS|OLd~NpcN0sXZDB1+Fb6h8o8gsRk0N&P}c z@5dA3gkJ-p2S$U0nlfQ2`93>g8E@?uU{h{yc#y)w54W;>szURusG;?pc4I1?)DcY$ zJ?(0pZ66jRf@=8s}C<#O#3mT(jPpYIY0bNmQHsES|;6oV{x@5C8b6%UDNO6lCWGB ze6rY zZjE-8r!c4pJ9zhl2hhz)ACUObbC&&;Vx-iD?FA@07O1cj=6*i>${WfEr7zr!_#Sp3W?4`kVN+cPDrJR&XK(lgN(I@g_4k& z*|2j7P~GPdJ1R4L*S{Ca4_h%wblhxHfeHyhTYzta&wI-+L(BEVDt=z9Upi>Btn&Hf zh`0I+liGDIwrFTRAD1>R$bKxdeS(b9pLs36#`(B^`W6v_(6RqKLkCM;JS)@&=e?P# z_m;(sMkd0OoA+M9(!a0$ZYn~Y?iIlNJr;)p@s|m?B6Fnl91-~mx8Dg{NFz1ZhM+v= zcs|n5xw-zC%YX`&JBvmv@Y0P82;W~wU;FgwgGjk!v|Un%$;ijs6Rw)vU#AoX6y3e! z2(WtiR!m^W^}Ec%#hV6}b(7h?D}#~=6f$^plV%P~?f0ks#1}j*T|`>eV&6~2xy@ln zupJ(nrZdUU=;SmC9p2 zm6HE9sZbcC;O>p@NgulCIfi3)u^O{OX__-kkHaPwzrzK~2HXF#r5q-~_KEZ{mbTTP z9}ngJ;B3V@l(R_Q8-Z7Yx&xK}%ZuH0e4Tv3|~ILsMUIbrc^4IgvrjMmTH=p0xkHMF*Mq zkQ_uC1ezqq1QB5Z)@I)c1uI31w%YhcJUb%XZc3Pg%9q3DuLKjN9*(doX#o6A14M7< z_`BE0Gl89j@DKYvfJAqI+Av_CA4PmKwf-_pxqW+ov`TR{X^Gua#6il+iKXuYJA*h= zd;Z6tvST5WTGt6nq*r5D)Ylg-tNOC)G-EY0OiC}%#=B5T@WZdszMk}wx^9Jn$P8Ot z05rgR{OhBS7IY!rGiLL5rm>a~_En6SXzr;c+6{WbA*-8F%ThtYS1n(?0O*%AI@NQ2 zU^Gh%4-y)enN#=FCRxvh(J88qussPGH0enHgESPABa@VTr*a5lgy5DFkVkI{waD;U z4#l*L4fe;J6M(Dn=!pBFFRFvdqYk~Yq&-|tMP959f@(nn3i)@!NG}c7qGDx(9!X5N zxkmm~_PY1|H5KSZ^ttK%(Mg2Beec5m9UQa+9kBWaNepTLp`C5-)HtH~3&$Q=X!8N~ zv&H&ALOi{!8xYz1;hF!DXj|>`B#3OUTojdXZq|jB$GXg#`QfcEDlS=L3A@N^d06V=_zf#RSr!+<+=2hm^6FBBZU9aJVt%Ms9vU8Br=Zu#eZpK znLFFLR}|Yxw~6C7uJchN0w$Z_OuU(tw2LVdbadfO3vAd;W=u&AG*jsy1w=}ky(Zc* z4wr|RWU=DKD0`Gryigf+p0%KxcLh3toZz6)LrKIZO9?tg!XAkj$%Y#E`cAad)8HMrJ6W0|4e z53(eL2jT?*qUX=ZdJ*9L`IZ>`bXFH;7?7>{&8vHk(KF*jS`H zAL(mpFif0`NFOee*snU)5RnL20uZIoahyttu|0@DU-gjT?4(x5DSph=E4e66A=>Lj z=r?aycCe_yuMSY5DAM3Sb}IFsU({A>LlagR4m|XAxBI)*g$u(VG5z!IE27IHFO}1B```osQo)7-52ircbyt3)Ub$G-tAv; zI@hm_r$FX2wvcoqeR1^RsR%BmH{EA8?DJLgGDUoJODPs6TRlsH8@i=QXhp49sI3k_ zv9zE` z?NZuD?rqo%lod!(5~h6M)#d%%UB}C--LID|&rkT3_!}_04qS&j;XI2gRW2~O;-g-F3vx)L@By%JH>2n8jm5?(=r;~-%$ z;y`Ga@UZcU_ujB6;`|4a9e9pdRF{ennf_(pai}mDT0~%M;XAKc=20An>}79uE*VB~ z{z>ss#`j-|D#-;&R<4GMdu(q%-rA_AWJi z1;}NPfEH$xa`~q4CKQV(2^oq$Qi)Vsnp}w&d3KUEME+{b&cFef#76yao*){f!Hw=w z5^zWW<(Z`cIAUz~=N@CzfWocn<=0!pR$HLRw*p^nv<>o#NEgzM{_yi!PW88*_bH+3 zsUeWL5b@Lm2#CV?i528S$-MpnGzo#f<3ofF!XmU# z;>JIfut}NM@GMIh`?I11=FJC)0NBju{jPiA|3?UmQ*faBwx9h_3C z_=h@JV6X#!io4-xjoG#3Ji1Z{mSe6nI#h!N%kfW|>aA18pDTcM?2XYD@ntXQsUVG* zGY(`YH*xwbxG-J`tBo>r$ng-w5Cirp#H&ha8(lu1R>y?Q?WR{}PFAb8p>JSve?T?i z(~FuUljkofV1FEKw=8!Bd2sbV$Fx2x9dTjGz?#0WX}naFbU%HRe4_(Rx?}`%i;zj` z!Ro@RM>cK%zCZ2KR^_r5S=Q?*+b)9mbVUB`3?6G-&vFK~g#-cPX|f5yP}*S0Y=4;^ zPlJIK+Pu9!o*LK8rB-hY#R->ZpeDjplBL3ZRGUwr|GTP)ndcW8IF)#0<`_<0T?91U zu#|X28=2dloltgu&neG47w(jjTOY(Z%>Ghx+1hQk$(AEMFCL_XRkcuQ+UF0l+JlwZ zC=^Jjc$AuoIDUrVIs=+eDFRx}CYTy`+n|cWtnLtFTIp{&Q+7^lg9ICYak&(YxwP%D zwA6bjB29Yc&B=$JV2=0)P{IJd-q z&^NxPYhoA2#J_RDy7YFhFN2`(j_;IzZ9zYdz_ zYR8=^dSAa=CaDUHCc^))wOcuU!(@_%z`Uo*)3g>lJF~;8gj1<1D=TX(%2k623A|f@0gB)OJSa8$xZ_q_^-Z0 zg1S;lG=7#HFDPX{q-6Xu!e!6MFY98E)`U~-H$V(^b*aJ%6G8q89b&bCV zN;%Q6_Jh={ZTM(W@=v@%&ZsbN;-r-Hq*-LM#h_6X5zKUBLub;1}@UV=1h)%G4vo?{epIn$tJHYYd%ildt5*n(a=mVZZ2^bxZWf{{x>Quz+ zp(S&3LY9xLJ19)8+=nI-wflfyVppxuCW{7GYdChIK12%G`leYdq%mn;$u_Mg?_OeZ z$nv9&Tns}W4=~ca)0Dd1;+P|_7#1aC@sm=tAK2|BWn_bO!$C&o9d@@5KmWxVN8U!= z=+nJ+A0WXhwnb#nn1mE3p{)*ywDf<3oCOz_aIi@B`(UHtBsD z2N>L|Cl#-QX$4NLH&gDn_~3z3jkxKq_9pX* zJc;cle?67_Bg3Co?FW@r0Q@Usw(9wb8PG7 zCJ5tzro?hynuAi!KP(jK3CIsL`TQpoL~qk!WO3u4dmzTt8nj^NVQl|K26co2y6r^tKnA?*`Dr7X~wl+2oD4=|jdA$0XYIffjRC==P#IN+U8z!`h5Skj+ zCLqP4D3S5RKZz;_VBKz>$oLY3uj*Zsjw_wQzCGlZ<&b=<0Qsv7h2~_ZTIjV_!a2rA zi82=WU5TPGknOOgOLFzjz0;lmkrCtk5~lAf7g(wi_Jw&4C__8pWk0Ap@Di}PyK_=P zx0P|*$nfi4CV#nr^TT4n)+SgShw?PyO`@GY%Ly_NMR*6HjCU+rWQ&Mi=5yTz%~mZ9 zpBf-dlwmlNkVH<4710i3qBlsJkDhE+8@^Mf@3|yq!Dmgxg+Tfe zVT60l3?i>Lm4i+3of@rgrB=>-29kQeTvHFLnU-#6j`6}{M2VGV3SlsXP3A>iPa|>J zA6;N~0DsC&025`CwWZSnctd10jSet#mlT-dmiF&UHiJQQ2)-G-Nqz?c|G}m0P0xDd z;M29#ln%TsS<%7KTA;N!)UW59@qOD>)@M_iyzgQFg0@n(K3_k!6KMvW7q*V3!2C&M z+M;Vb`4ROOhOkWtev07+Vk4cQ4~~?XbROz^CnqrOgY+8R{SKSpzxjzLl6xf(esv`P zxlSwcn2^T;jH7)iNj8f+&*es@HX5J_HAjh3;eP|@)k@BB;EFW_ZDY2ZIi_@j@q~9u z4AyQE5iCXyA3cTTuD%cx>e-$;AVcyGs@yT`A8-y<#X$6TeH#(N=u&A1!Z`b<9cHyDAy`qdu{q%v7k$BFwN0^H3W62fKkV5iUB*C7TG0S3@7#(Z+`$n)-h$`Zcf z(eP8oN5*h%6SZ%E3P(GgBW8=170^A6hB+DGOD+8Bao$sh#T1E*CxJ~CHmQ&dAC#xn z=8_h08o&4Z>gj?D4!a57$6wN1;5;KGqMowuTTd@4ySFY3OAJe`b9%olOL4}K0-H|% zEj3C_1_3keUukUK9g0r#`f$dlrgs03L_17;F)A;^I-=k%%HKh4O~F%;4c?sIX(ZU& z5{Y+r-nqDgMyGWE=Y-ua98Ty*+sj6)8EhYBnPm?DqN8d_obt&M*~&6_B+PDm_`YDN zQ5P*K&YQuw)vQ#`XXZl6H|!`73Ir|WXeYZ;_Kg07x`ADdbenR#MQtPfF%%LZuf`Rm zW8n7GU293OS9JBqUeCTnDxPgTxcS-g^Qm;_mE;J9?XhBfboJ+_ZQDmWBSg6Ed?q&B z)#-2L8dT&Jcni_(ISgbeFB!-K7b?jO?EGEcn`p70MdK^# z!AzIUXa>L>Fv=+p)OYw8C~6Nrirt=Azjxm$zMSio+xx>W9Vp!|-7tx&?o_4?2| z794jHfkzC<({Hq~JdgF%boJ|W%!1#h*QXabYN@Pn{$+_OAgm~$D4hQvv&!(ZjorUf$FTP01A!Pj0SU+FlvUvOGn zf;Egyd%Os7q9xo`ljNI0z!2Mh$Jb=032$b1CPLVm_MVIj*&VuzdC6 z9L$EQKm6>jt_ZmJZgQ4gicsA3qud@D>NvY{H4ZYvXzA6cjpaX}CWrUepSi1;K{Ca< zRrV)0dqZFoo`IqwQKFZ*lQ=~7Sxo8Ska?qkXGWZK?m$>&@^W-eyLucf{DY(+-H_$) zmuyc;j}lx}Ng~1w#rf1#Wy(nQlo&X8s6N;F>T3XD3)yU#+V8*BfXV~@m|Z@aUg3-F zhJ^IvJnsUQbL|l#Ohff*3NACm4JJucar2>++&ztg=8W+(GpQm-;u2X=VwQeY+vFa5 z?=(Gs*#%l>Ft<3i)^*!=Ui8%=Sn+(8T}8^S;3&uuF8Y~D%FURU&B9#a3&#}t>`%9O zipKn)Hm*U~2r85{kHVOGwjeXM)5rrAZKv_?YtvV6}qI%aQAtcdmTb^MB3 ztJ`?$^egvY+vCP-A7p*i)JI4*-#6jeVpb>>B62lLS?$y1f1b@46Bj%a2U#*q#REmr zR>6P=aDGkvjlu3K^5Je`RYp>9sQwcso5ca8EH%GZ*+t z-sJXP&a0kw(rB^XTnP{ZcPVh5)Sz`xyEFejoogxRz|T2#sxt_0e$XhSUdjTCy?;?}&Y>EZj8S z*`42Ph?IS5HAJi-bk*h!+<7`|ym)Q?zVPO?WyuX=#LJo5e*fO~|_1 zaOx1mxkMK5@dt&MP-&E$PbKO=wou8Hc&L37UNcNCx33kOtWHwtbsl`4w+qk)%!Gic zcBo~`zXD#&Hy(6wGJCZw|Gt;*T~hOo328%I;XK8$Y7dReyrHTVtq%*Z&G_}LtF~oo zY(Da_2w}9o{`EH-m*~Ax>tcc;FrR_z9g*2gU7bHJtwJ__a*4KmZ3Djg`K|s#H-a=i zZkqYGf*c`1EUD{7WPUogb1?=xLg{Wil20Huxyey zfiJm(P(NQ%Q;`z~>1u^VW7&zXRQ~Pp&0=va-8ScZTG>JFuEP(yJl-m12^AAMCk%Vy zdx)kIp|-L=2PO(}a11umoWE06KVd}?H69^#Pbyh(-}LM(_pho1L&$5>>xsUPCFO@M|`}c&#gj z68d2y13t1c;C{RD1g}-@?xb@dHjLq|zGn8|<*Wv%%C!F{?Yr&n_vB`DV|g>s3uiK~ ziQowE--cH}{O7TFK|(9dQ0n6SaR8}39h3%wEVAlmnL6XA`}{-xz+Y!l?-#1pmOtBp zJ%0}H1h{ZNg%mC{e9^DaJGyqAGdPer5YYCz^rZ%rNy)!!(ItieL16Ph^WkiE4XB+;Vq{S*Zk zgCki>h7JKGVHBxLWR5heJT>;&oDWnjc-wz}quXc84mmA&Tpv2mT`UO<;nY9BY)T7T zr^Y>r1U{bSgz{D$v!u3QX+Lf* zkF%>_*$V&yqRboe`r^CS$;%u#+;EX}aA{E+3r7F_`#6UTY9s_P!--+A5rmc>MI3wK zDzjrIbHMZ|%O|3E-4AmcF29Ac;aHvDX3vyYw{4S*QkJ`W3(aOZ7Jcw5x8Pki{WaP6 zY+#s-$60cj7v4ycTuImL`Il1{1NlL5&KwTa7H0qEwBzsXzIUg~FtHNdS9h zMA>}y^z5s#m|a3d!NIpPf*6sS$^kw8K`j#e!zhE17VP^J515gglcSr07ON-=B*$jL zh@(V%nC!qwBtjwDz2y1!F1AJ+h9R5 z%;l2>rJWtM%$2JPB{@4nxK4(`Usp@tZqo6ba<%>FL-1-nOC5sckfRoo_Sy0q&&S#6 z;Qpi-rrD16QeY=DXQPS^1VeG#X+h_rui9R3HoV)kss=sXX7A{#WXO8_r7Wl9x14g) zM}ZKQ@L^#_pvRfz&yp&)?vL0dBh1v}rS8`X+FQ_Tsb~^MyJE+1t$oV`^MGFn5zKVK(f9|d?o)ZJobwwj=%Q)aOk31AI-^|e2 zHZUgV1zdbrN(XwyzKT&x*Q_Y>^c1DpOyrQ|PF~;zrRfWCnIL=vClz!a!2+bGC&&Az z`Q56Wx15{6xBrSS?Oal(HscAK|8aH;e;nz6tHH!lZB>q`|1QoIDc?P*W!{KX<;5~! zEKXGJN;+JHjv9J2NILv<;uB& z6)vSBMFP}#zALrt5%e&e|NgRZ(LVqEGOJ<`MmU71L~KA!mhQ3)hN5fF$}Cv)VIfrl zK|YuG_4a3b0v>Pg)cs!siedz#}Y*d^lJO&doL!%`N}c4$FI% zrFK^K*O^7mPnja32P^;HVgecf+%y0n_Eu5AgX!5<^L_<)?!#gM58JwBx*Y={69d`N zf&Y9u75T6tHNlV;A-t{Lct#4Tl1*}NE4zz;GU(XvB6kTiP09bh{SA>;oQq`)1LIGE zC?GFd4Qe@G+}4(3f3cQ;SQUqta(VTiA5~_dRA7C#;)lFVnB3D%!pELy&DXZ?J!ggZI_@#Szz1k4apkPRvqVR*l_W*H`Kz z0Z9zSinF&1!*`R%$Yg?8R-_WpxJTnl;I>N4=p^9YCV`ql-`OrWUyYt@4Kui_C>(^W zoPqnLBKj5=G!JqF$7880uTdB^1pal$Y)w z^zXOAzULY9>;rv06Z6O8Zuzp=jI*n7suU?W56&MPe~m<_EfbXY=0Dk*nUN1IZ|H}1 z9FQOmCD}{@_pysH7TH+M&9n_cw9lADv_T1BYE~StM~GqjoO_Ou$;^KZrn2D0+;*IX z3f7Lm;8J=pALZyy4^u2hqa8Az@Uv0Z+BMyn?|;?;y|#Cn@ICPSZF(P(e5_0b{3cyV z(hz)`o$747V{=J^{Wm}xgW=jK6<`z21j{<|8#1SM8iw+pN7n&z8CU9iMwzD2t?=?n zXdCmFUcy`c{+-!*E?PgsgF*|Jz3lvr zc~)W1=?xdTC(W`8G>-Eu;%TJk`U8dp4ZJt4@qe#9C8tvlTX?k!i-}d48N_Mni`Q~( zmGs5+wZ!)LaZOY8H34(H+vgH@LhaNBB>Xx97J} z5@Hemr@lvmE@CN^f|a%+B|Z<sc=Cst1Q@?ttHw6C67$PN^OC96zD-q4HTn{^@fDw37)VpBh=L{jg3o4Kv zxFO~XGtn1Lt;(|pqP==o7x5CY6tVXA|8rkx@J#WNi~lnCe*n!uGQSv)V-fc@ zz+n6v$-}nu|Ns1_e=fg#`iyn_Uc*aoJd&3mzEL}02$2%{Ac~nSAvGc6+>&?JNj`B3 zT#$ktEJ7a4k@FTUe=YQ_rC&?B=g(pe>(`lG)VF`%?`J!w-3 z?1`~eDk9Jxh~DxR0FMFCOZbgwJ+))e&0G3(I$84oXx9L?TLAFB-2xDvHiLg=YQ9U) zk?vvu+#)d{HrEtfQPDgAwpA_Les?vlMYP-&0Xnbo5rBseAKJR6@M?tq`I#kxO@hBN z*?45Ga2(7GMs+}VC{~~?wLjFug4E6uZpiApXxr}JxSxLeyEk^_wdY%V04m*nujlPk zp7p%#ylguQIH^@(05tS{^zk_-yAD%B(@K*lUK1{4EMmZ*HX0A?1RC(zJrZ&!v2XU` zxWiWX$)}^=HY}5IE*_wuHC)GMezYEQKfqosB6aty;{fx(6=3suW<5JTZ4C(=ixjw8 zZXFTPS$)pA8qdvqrExpBUkG+&(|~%mfpVddDni zZvg5J4a6guBFDK`>}-GX`OI5MU!lyM*)^Q#k>JK1_r5$5NEybWWC#Y6a7hn+f0|o~ z9by+B&(>+tg^hC>AX1G6FVEU2=+{Te z7d%Wp{XCTh;0I&Fiqd!o$Q<5fiS~OH=T*`d$MWclppU6Xc0Ls&WnD!ycZd5Ecdul( zeZchjIpxH&crSTl3MoU#hn@Epf2Ef@OVs=NgLdZsceb7X2O*bQ`L^@_uiW@ouZ&NZ zK(qsebh>u5i*Z-zztKC16z@hqn(_Zz-*DqUhqUkf|A*Vo{|6sEOWRFHUFZ96$g_Ko zR13H}DLubsURiA3j}kp#VmS z3?5u%c%3!F<{}ujS|D+>BEoLu)*5% zPd;D6YmCKN%4wqsPGa63?^5P4W3HG(oZLR>UNkE2J;^&^64}&VkL5#xoM~_F*H!cd z{-5R=T@DsWbpGxeLUfGa{ihkUQ9XtP>fa5c`HQyEQ^Uu0R)n zF+cPRpKBvXE%*hwOJ|&wEbFsMRs(gG<2TFGtg8HIN1dAofDHJeM2i8yK>*mTeWQ=V_~2I068-mzLT& zn2i}!Ravx7lfQ_N;+Vo7%C87BUoK1<=_D>#)^z2`o!NAu6JH2WpOE5yzto6_l6cba z4j4uKsyI^Sb5{)l#bTlpBiZeXbOV9?m=#t?X**3l;&$IzTt#@tbM<)!XpM7RX51a$#jQghnz;+?t}C2IK&O5N zdBxRy=$DoGCqH>Q<( zV--=#*EI0b2*m`@sX{6OC1BcClLf2!*zpr~tp~1P0IJsu1KhH9oBZi>2XRfK+mha5 zbAjf^Sh@;Y$sKgi+E@ppb_sta5ja>7DR~XFmv~)`c0(miW6tlS5t|w06VgAI1%bi* zeJcH9gUUD=ov!Jd~8(@Gu8aelTzWTbl|-->IbqwCz{#|QC0K^=Q?g9NHn>P zmQ|%_1uB(}R)WWjGw(Yz(TgL&+eW@Df#){kUh8+r-?;BoNS8!?ad&G4snkjBjF>14 zJO539@EoECeNV!c%KyFr!+0(@yb1qLkBcnQ%XmAgYntFSA?UQx=A411>?`=K&w?=g z&1$%lm2ju*)tfqiP4gi5jyEHYy3M-NB_0(nZ#@Qp&~0bNHq@JMzS+OSTl(?i$JUNf zvj;%C1;GCfF?yGtFWq?n+#)rjoeB8&e((1RQTiR0vhDuMSHJpId-vUULj<-Jt!)uN z{TxhliRtfNL*XNtGcnktKMMqXoE360qAdM2-P2eIERqHhlt&0M1Scsw&FxhSO8RWn zz8VCnmx1yxbrB%o4P|5MlVDLC({PUspD>Ej~tn*A63$2(z5L%J^Esc*eHB zPxxz$`6!IVgm(Dj95@@5kNJjo{b`YbvaY`By~M(l1agdU7-)4}rbF!;8snV$DA!iv zW1eRkHV?Kd1E+939j?=|->86>2;inMD}*^szL6K64vvcmFemvvjMOA@7XhxQ5gsW= zf`GAg7*E}Zw%+jucQdNbs}XK-$F(}Gxd(+=&`IPqmn^J-IFu~ZiQ^a=a#F@|n-xcM9DMIo9;ZlrQ)AJ7 zdyNgnF15CYZ#+23KX1nW*B|6j7a4BT+Qwm4Qg`?&g^J_rdER0IKJ3LZUr#UsU+r(RrU-smTI?!=L%aBpo$Dpbx=18Q#i8g1JiocM_BI*6c@^PlK2CrH! zMuBHm?z`^#K)}c`|Lgu8F}n%LkeTO7*$Ma2r0wNgWLHVqHs^OZj@ZOON#Y&#ggy~O zxccTrC&;l;C6c&QxL1fTKPS9)L2Cw(kXj@azlYqKM0S-iB@nW*Q`)p%y*7mV0Ht5&QP;{ zh*i*{0ZalsL^c!ypPWsFlzEBivzPJ79*mW{{oID;F)?49uxY~KGmik?yq`V3fNGp? z=kwZ5T^!;i zCrh}#@eJvsqXf4Rx)ii0p-8|eUIJ#)IV{I1bP5NS70ggp!{CriszIAQ@Z1uO`+H;k zf3G-N!mHEs`TNSpb|m484tR?7702-Ed-fDmBD5@aI^Ns*!}zTh9gKVetJPGVK; zR31`xNls$>&2LeBiJX^|Q?V2~jvZIo|AZ>9DO$2cQjtu{jBYNOh=@A~p0ihH&vgH~ ze?4n|xE(%z3;537d#zbBJw1J&o*Cw!;uI`}u_mXO2Hbg-%20^u%ANROlswiqXI@110 zcD?t(Bl+gPeOn$q-h;-y-gA@J=%=(njTl4*FF=bMZJ3z-lp@q|)ZbU;QGcfL0rfq@Lh3-Kdr4;hg9bQ#0L(BqL3d@9ZE0*yj8 z@ZUOySo)~Svcw4Q*6fKRFxp8RePA5Y_q1YGgg2X~=%h7A`dbdpx*Xxm^6T${3;k_< zS!lmVjd)?x>$u=PgZ{<{xu?_~D0H0Zsu}udxq6YyxOEH#hd$ zYp=CdMz-~Ub=eH??)nVZT>#+8uB+5{A=r6;Y+!+FWB~9f09XPrG61fvhxx<+kTUA2 zW6aEY09x@+NZXY6i%dO*5?Os7%s^rmbjs+hPFUx3S}62PzXsq^$^lB!`=hCEy!x#h z;KSgIb^GqPZK=>_zg4>pCc+v!+t=`b(+T9RTPq#kt3qvh*6I`ltb>Cf&si}7!z`A| zMaukMjm2%BbtUD#Yw4Bw-dNW>mTFL*CS2(0tRw3I;}ccwp$LtdRhp%>Si`Jz`~Y?{ zANRK{=M-Wecga;E37?UnBuoSgK0^^v_tAs;Hyk=y#-r%IGAojNqqt{Gl=GQw8XI6y zuOmI*)hN8tz?GkYI&BA&zbcTn+Rz{GA4}@l*kmtY(p6uL~|HRrL~H|3v7o# zR)7|EGQx{qjBr-{SJkBDG}5WP^OKO(*eXK>E^KRom-5x~@HOu5oO%{tO@@a$N3!?0W_!)-5@ zR{3V^CTx%!*XonboD6FNXMx9-?`ylp;1%sBQC$Tjz8~K8`|NmP<4|Nqp=_E2crKDN z@rUPP$)iH|5v1Ol!Xwy%h?w81--|FxVT}7K-QiaHjDCt_#!Xdpg&t(FM;P}A5TF_@ z`Q~~odX_ zhnFO0nB67=QkE817GMD@T|XUhBSib?^MaeJNVV&gDSsjU%XgM{SN=b=aqYX%ySJ1n zlxH>{nM;`sXgu5&6AWb2B>(M_d}L|gAG_XgEzHo8d_uhMN zetG-tx5pj;GWG!Y?svaCHvxS0)mLX0z{mg?KGoO*U@WtSP1u7;ch_gR?g9W$c&$V@ zi1b3R`Fm_+F_r*~>y0(g#3E&pMjC&CF8f?cW{dZ&O(t?mVVRrS5(wNLjfqZnN z`lgZrSdIt!Ez6il(e6gZ42&P7@^A5(83$q{i&P-OFiQ>4bI*Xw{S(Ao_CuQAsR8#n zvSm26RjBV{i3l*2W0>#-9C2#FPINOqA3nH|e>#u)yBFi+i?QAtYyN-J*Zj}To{8r7 z{R%Bh@kR1hd^CO|1Cn|bNB51H|A#sA4k`}BsLYuHRoj2nhCi!%nT{HPLXKHw*c8qr(1rl(!t2;fGx4S%ywdRDTlyIUprfLavDl;ZPDUzKLJ7(uX#lOOBJ0{DfSb@!n~nZfn*9j=7aFUT|EcdB^&!#=nhm`%-iXz=O4)A?zT3B(8fB~63W=B1 z6_w3GYnK`00zvSeDe!5ou_XHPH{ZTYekKGDA3mJTjU@nMzqH{qjT6)^e`9a8e1EL} zSHI-$dh+Wo0PsV)Voi#SB>Jz8!LdcVo?syR_sWBE0Yo0Y`zYZZ8i-hbv4p@(-4MUGJiklkB3g@#0S=ZR<=^qN zmmLui6r^E=N)P;&62)viN+2^}3uIsx-%l5aenlU)T+>{;o;QyU#>PpTQIYn;SUX1J zY2>7MSxuZ`1|+MF(R(Q@u>BHc@ExZPtooEyZT{9;QUIeD{j0vl zvJ9;Zm5t&gd*XxU%+ioivb8k3Hh;(I4{V#H5hsPOTF+W^e$~)XDbr(-1Unfz4QE!* z+4d>!qqU`4MgZ$iTaBW0;28{mSivFZAh!1a59&q`jOBqDjyHlNxQ375VMQ9PlWMS05*g-xc4@1v1(w41dp=6*ytLtOt9T^i43Kn}3VEuF1Q$C6a8hMKU z2Gr)UduxLjLv)H{KL5C4XBt&nv>4=uH4US zl?NpFSH~Q^&-SH+MbkWt$c5q9G1acE@YR^%4*YDy$X9rM>00Sj#sh&x;Pg5=&f1ZF zbXDNV{A8SF3s~@$$+|BA>v5+UEx7~x)gAj2=5J{3BO1S=%}_n&8r25 zwBv+fHoD(Xr%c+^Ke=VdbX6jWQP^JxeiY~pTX;$uzqO4l0b3Sb7y`=e8vonMO9Zoa z{=eO!TxEu}K4<0E`2XCu;@zj0|isWp;@&1mJJFNEnkfr-TecE&` z6IdkMB4@2b8sJ%$|1?)*03>K*8T9alM)vdA1Q4eH44-LKKlV`@zSP(=ZTMD~KP{Bm z-4cK&yzT-3Pk7~e)5|rYQ;`8MqgEq&HO{ge*LT1BUE@;#;`RAC&cqxHu%yR)s*4#? z>5f^4HA>aLa8S(!%mxK0k|zN`$ype#n7ML8ppHJ16z&C83c#j#j9?=TLmL-ms%_xc z%a`Lmvk;Ur0jvbNQdQoe*co*KuXGHW=7w!-@N3`#>BVU+2U3jiHI-y6uvhHDjY`Ba zK;S*B4S~E3Is-id3+b5R#DHi6i`OSUI19nbDA0ftGv(+^1_zQjOt7{)*BlsT{ybvRV(*f#OZU(N)!EA7mawDm@Wl zTO#{Z3bOIb?m?hZiZt+1P>paeWpixWXTI5hYf6h@a>6dUqxx>sb7^)dahp}3iFp!q zKGVpfpS#d3yzu@4(t`$3WQTEWQicc{2F-9O2fljm*E!bd!oWOjoAAs6kYmyf;+=Nj z-j}-2yeyu@riC$P`+l6QL-2z|R<4y-Z8#UHXOLGFh%%ymZ-2vDe`@o&i}U|a z{@PE?w0}T6-W?nMeKU{x^EwbbknC4sA2h&$0`xszPn=4DXA^ zE6D1ElNC%Ftkp`-%tR7hmR z%zn8f+tt$H_Eg?bQhPZU6P$>$qN%c7Nb<(+s~b|?)t__5L?Vaqh)7$lQc&<*Ymn5;Y`C}^FmmE-P0Mp9CV;sIbON`-Xx7Sr2Kn~ zqhLgjb4J~SvIL|w3k-Cs6Nodb`P6h$)9G2tVjqQNv&*EP9D^F;Hn!GP@xDuQyxCTA za;eQOu@iF9Z_%j*jsp1Fr-AU2!6!))3YxH1w%f3U{~WKt*G`-JVcf9919Qz$GC*4yvk`~T6dms%Jv$ppWaDk2U%66qTRFnQV zNP)hg{VnjXF;n78OlnVrStk1FK?A>s*?ik=@%fS?r3FN!%aDE9|KZ{N)13ML>W|+S zOZkaQ+{>K!l&df}m>@B`Ihofe@oL9xqy+RMhw&n#doq@5;5S zOw0wAfDePHaWDDbt~i)iek=Xf&d2=OVaN{1!8c&R17t6K<5}V+q>4$U;}0C*bx%0} z2U96HN#oE=Yg+!7t!YgPObIY{AK#St0R07_hLU2mjoZ60lU(Ufm*Gj^W@5LX&XWG5 zWyNQJ*o^E1YR+oLyVp&Dc*ri{r3 z^?BnFNkx%#qaCiQtJ81Q&Cdz1EN&KC@X&XouEu+3+4JnvdA;}uF>hoUpNMEOnTxP%b~~h!V52qpuUdD(vbl$HUI>;V`KH< zTVePAu@PYL#HWYj?(*v{1K`Q7aU8`o(Xa$yIRCG|{`x$+0>@bJ5`Youdi(9S=P`g> z4`l^>^2STgb%h08xgX2rQES08x*sF^T`|t&H`lutDRHCmPB@U8l35UIEN3uMS%ejk zNGlYT#jNpqO2L&8)SN_;rASXN1h_Mpv+i3tIf7K(kecJk&bU#Tdkb7evXs)}byvWZ zVAemKVj2{ww7@--seczw3)XsXZ0t7#HfCiv7#Mqu)!bvCgth_)wkWSuNRoCqb{#+O z3(gbO%2=O$^&|8M6@uB$_zT6qBkh6hk9=u$=))nEQbde05sFMhDN7791#2d}n`_T> z7{#g=*sPI_5+U2DwHf+xtB&$%0qELPlGCoGSJgFtXPufUs%GlPRU}egs@HX-9OKV1x{GcwtB47)OnF;rxqu@JEyX zDfQP-W}C-g?o2R7nYmi`K!ndfdztzF>tBHrnKS=C_p8(S7Xu$gBNxYi9`!e)6JvJ& z?4S83(lY=|kQrc{zlvwcJB2b3O*LzTL&@<&Kdal;Fo7}+JGjTu(!)pa1HAmG3pO+J#mr*`~5^M~!)dWWd z(_wo7FG@431Qcrm$luQ4q@)(eS@)zO;SPV~RWiKl1We1|rjD_NCP=SHpXh0DM4u2e zP=RKWPBYp-OS}o>!J(hhUvA^VWx!)usiZ=X10f3)u6`Kz=Sn;L?lKOHhDPcQe&-X& zzI+UuVOv@Y#k$7>lOpbY0S_Z%w@WHU6WL*uS@|h0WI2yXPwWA(`aUnc^wK;9VE9jC z3Bb69Pc?k2m~g$jen{6{0N}~4nT9f$a1iE5Pl>ZC1!*f|_J0ub_&zoP9K|0#d^kDi z-FM%e_b<^f9g(q5-?)ErBpI@ZWnq+_|N8pdQYymb4qPw3EI?fN>~Y@pt~KK~4Gfi7 ztFALG7c;X8!9$fgY;K?g_tUeO0ZxU+0@KS{%!ILgoKE#tozYzTIjtIjkq!frMKRP? zu8mp^=^0c2h|y}3qR|Y5^S}i~m1l7);{{4wbE;7?fH2`W;dzarj=cqp$Jx5!AHZ&; z$aYptntKA4lPd+YMBPT?1cQdtvfU{tg#+hkj=7lB(*1%7N=rqWflzwV4Xdt0TAn^rQs-IbA4|)mXG>>jntR1(7F7^nbxD&j! zse6h2I%2kc$0-=J7o1djzi+nZc-=y_VwXqnN` z@wIKWi~+Or*rTF`y9R$F;&xosGZ?kw*4XgxACH;;SMImn_&@mY;{1=9|8w-$j!WqQ zI>rR$GGMZl^Vv1Yu}hfa`&fSQm5cK~(*8w@bN-*-9%=t$xBqj|33&PbL(!)nTpD~l z9e+DNzO-@nAV93oF&rsU=TFuUV1O_Nvs^{2+p?t`SxNcFmu8*P%C<5qACgdjoNY{X zwW@$u3N{~8DwIww%27YK{-C=8I^bz?1mmg)n3}Vgfr5Z3^_Vr^TT`ynUKZnb9Se|U zihcvmXa}+vVK>k-;K}_nu345zlzZtiqfXJ78!dfEbKvUu5c5Pma7c;V7CMS?rvePd zTCGyu%ET6Oa1s5)|J_~Ie5cEds<-$OIx%7C$f^hRkOVl{Q2X*Ox67TjqSX#_&uB6b z#(YN$M_`Fy>sXfj_Q-P<8afJ%^JEOn_gg#kTK`k6fQN%-IR#r~XmnVV;x z<_C@cwS#^I%P2N% z;i{yEB7iby-4lO%^j%Y7cuMK!v+g{`k!!EA*Z5nFLqu}YNR%jD>b=Ip)5Z5HYl(2u zdDe`W97l5)w@v%(r?9zG%M{azvFgigF6fD?z-%=PIvAQpI^W1XDMKtE4#zah#B=Nk zfxQ^n7r_W)hCgT3vq8|61dVRORzN>lfW`y8nh%R_EK|gtIJRxU9oY|L`wO!kSS2@8 zjE;H+iUYwXcBJj6303h#v;`jlduO0wNDp@eIxlA`ek_+^+cOOaD(}A?kPY9>9n>|0 zWb|>D%m&VWj5K;Nh7vLHA+-zA%~@qszOezBtdef zLwiPO0-q8zB2>4oR%@eYZNx-xO8>!iSpKWraR88mL4YzLHUetgAeEASqyu(J0k_h- zBBk?1Dexnfx>FgwB`BLL@aI}%k1Oy~j%yEop^Wn#0wo1={x%}$Rjx$8Yt1>=D=C~f zb19b}(O7b(VB)ko;`AFrC2hJqe$7G-FLWdQHzp7&{7SDGIMuQ*R{Vf}VJn~p6v22#|CVT-By#qh z=+YKCRq5+6rO|N7mh1fA+Fjdj19=5De&;IxTfxWgt~?b@;n}Qa!;-bocjNv{^WRG5 z(vsZx>2V+CEdhEoZyAlb-zvF*0?^S)|1sPyEE(TWw@pBM@+x{{LjxT>#(-u2nb=q6A?MLjCZ= z4`+cN{m~!QM~@zj)E2uC_aQbu*27#FV`c%|lTUXs`!?9(AD4H&4!l1kqh(yQjB*Mb z7(g3Tme(^=cOe*{)d-ecCx$ihaMHC)h0eGttLL`mk!dm=;ZfH>+`jn?fB3U*6sAOz ze$*F~N_Yxb;}2yoJ%A&aDRT+BH|3Bi-h0=VnSu|QZX(7CQe22*##zmse-1V2(_hBM@m{`ahSF?_gco87;;7GcktQv zZ4e({Y>=4_OwgUgeiOV-H3?(a+&D6rC1}Wb3xySi-c~lxzS<*1b7v#iY}sc5H>DhK zV^&=1Vi_>Lp8^J_DU;LX#=cjO&ASl18ZT`@?|K+y2NX0}%fI^!hp*!=T07H1;YtCH zvB~iw^u%+e-{s>KucI#Dd(+5p(OT+IGA-mFEujI+PFjn8axe=#$w8;*?w#Zxj}8BZ z^Dh+?fb;+8F$LtL#s$NuYd}cq3&jZqP6oz3SyhtYeYgK`{+(nU&f)z3xu5%ny!GDW zTvma&mRE5pe}3eQdb*ep+bJ=^fxyC&2=9>~*~2ISI>oXb1Bh&?n*79n@Ql3h;M8Qs zJ0I-9hfxpq)c`+2j(`xPXrNw7LM&%ee7V&B`|m%L?l2VWT#r_Pq_beY_Uh{MCIX@W z>Mfa4K?`PE{#_1speu1*?C04ug@;*X=+d=sM?7L&EH^jBrjbVn(dLnwkCJeg`jvn3 z?5}i&x)tXFAzXdI!zg8aotD&$GzC;N7dvzSXpkDXuxre9p-MTUW#@ z4&+L;2v$-f$GUL8@o*3Z2W;5s=kgG!2gEWU*J-gmv!x>}SE%3D##E%EX&tsnW~W$! z7In`hp^OjcTF@i(H3D0Jb?Kvv+!cSj!oq5G`Nr%wfqe#Vm z4g+IkcOn%&XA?Evh76Q)j6AhpIzaeg7Hg|vJXy-;Kyc_EZM)~&p(+*fqug1KnROha zvPC&IzSdpxdDaf~LD)r>cD+wWwtQ5OpsE1lI9f6$JmS?f`Zen&(iic8%_>G61l4+VWlhj{OP@v_J~X)6{t!R66kl1@9G%G5(!&qjVIc z32$nK{`lB9&T%YcDgUl?0c9kJ#Q0r7fK*U`H?H%#HL|WPGX;|=rO*CnBQ!4KX_BcC zOv6Dwd!Idx-@4Hfb?m$!g2MK&>}##{2VKHRGm;%8R|hSeRAim?O!*QGp+4>haOw0A z@LX-8meRKkGftNne`DtVr^asoPoLts(+scqhqIKT zZqii{=I(()jr4!)12BV>c>+KL6XTNzREn`7|E%qw;!Q_CqTI{RKP7+o#i!&8m%snu z^ZxgTf8=TT!skDC`TjZi!t8R~DR6ntnXvW&4b-r7L+ed4ruZ!?;VU8*sATCTURZC{aGk zSfhK*yK(wsyfuc?E>u)?;i_7ahHSwsr@*0BH?%82?I@N6$Xe80QV+0g z4ZJ{CBwQ(*w2i;YEkk(AxQ=T~ijE*aYy#*cUrPYy+b_TT^2`7jO8|h1*Is*VmJR1$ z;}ih7yPoX23jjR9#gXN4Au`1q{EgZFu?N5)YPu%nzWeUGa|wV1%N*9nKnR&!5rWc< zP$?n727!b?E({e@J6ALA+Y@KEu@6%4e8#Vn!!?%tY8-8b@#Q_WSl{WQF*Y9S91-usTmueA7X3>41dK+zY*&Mg z2eR8Vdu%b=nG?(A4(g=an!&TkG=ZYw9li4;1XkynzF{8; zI1?za=XVh?!7ADmm;jchU{{2Pn6GM2QAmbn2Y@ntZEu>A}qDDY-jQe(Z0Wn9$p z5k^$^W#XMn!LjE5|A^iG8JE-f|2J>Rpp-$dJqtrQ- z;AB|rZ+;`v{?UK59YM(mgn1j}@W-Do9WvSnU{AfEB+oVa(2QHq zZ_=bSd3&>YA4XQn>7+BDGXg{7=)#kFfX6qO9M63-NjRl`#34Q3B9k^~?xY^vIjzAd zAg`2$gM;87(E#Y4oqS>b7g)SqM%hv~`kVXKkYi(1k5V(D$0~&MZe}W2(TZ5{j$WaY zsndx6y+8Fn`<_ZRhR50T(4Q6_7os_;^DsnG zvbrjhE}YgY$~^t_)AQ+=^t|{!_TGE%jS18FY@7n{;)^d{Ow(;<0KEF@tMjdqO%0!F z_*f%?FqQ$_&Hg|6br%45!VAX$4q`+A02@|}>k`SD8(Q!?V-Em)9~l5+6To~(OxmQw zH66CZ{m>r;l>L;_s1fUE1I7?o!KGrmMu4kB=tYl%K zRE(9Q79vb)7AA6s{0+7yuqrDupvN>V)l8IKcDTO*OIQW5n)zuWOQ26LDIRAO<}#h42Uhb;C^Yq#xrHc zG$PV?0pfvelAXq?)q(FZ)~Ag->pU_Xx9LmMegzr>ylu-^Sd_yq^m|WjW(Qih&sIwW z<~ZQMjBwJDnlT2#b!|DmY2a8*458eda*zhl%fAio5+uUnVL4tQYv%?=CNK(NN;w6l;IuFg={$KT(f7CZV ze(ks4m;dzVF3$h^kEI2Hh3#J@nNG6c%xMYb@I!hiPFpy8&tTvuy_+Qcr0hh0H39)a zBR3a$3y1#%hdu&JgU1JLY|4L7;$2OhH*baU zScinziX>tn>0?N=aSfh^(rd(_SKvoLBJ`SFc^7~w8zgd4@ulL}=gFFTh z7fwtY*SEj@?fE&fs>dk+xy_<0)Qy?X{%Lk8XNKD%^$cN&N>GggY(okHyDDmecff+lZU38c-I zSp{i=v+=1)b5_hqc>u;-zz<__7tGGK-0>NRD8p@45VOdZ;$4(IFRWwUB^78bAB>s* zS+S&2H4@gd{NuekIAB4lILpRxc%bm2Re}xUp;9?p+Kr~{l!Pz`-Z$E?Nb(eh3>54> zemO%Q`Qog*rhUH4GP8<-;c?Sa8a2rDyK7mV0YzVSvMVT_AQ6f==u19^&Ox$Ujp(E+ zpvs5~l-@TOgJF7nrgwU-g)`U}U^6(PXph+fwbcfaHH#Sg6;0mBAWFka zhs(^8Ur%9NW4Qs~t+cxwYhE91(X7IxaL zU(j!~uVc;sW#<3l{CnDeIco1+X4&V=|KmO7cg7j_j*sc!??nqsOeVQ*Pr9!AJC(b+ zc(rrpA8G$l(VY4JxnGqx-+Sb+tEQ~=iEd5Yrs=ove+*QNORhx_Ulw3lt{kE4V9LLg zgGux#yGoaOuD@B5E0pO58(@%iE9^YU!|U7o%F zq2GW11Aq4Z_aFK1%inwNKf2sIw+XwnvGS5g0Ufi5wtG?UzpIUji!tV$aJuXP}W&j4xk=jpP$u!*Q*O0Qh4bV zNGIGR0u}5JqWtbcH&p@M1LGOv`;rxRrN0e%;R~b83j^D4m^2%5SAY%yt zB3p=p5i<-T&-9pi*~c_af-QAGXaz8DDmY3d_cugTttk*bc24$M3l7(L4*^tb`k{)V z-regl0!Fz(fV~I|z?_B!DMpJK>gjB4r&!~(9|Wg`c86g!9nP%;^B%jT83{CAf2h8| zIQx{QOW3n*N^YliZPa(ju$(b2@@(4Nkfgu zBk$**T+vY`k-EQThbS4UmcQMZk5R|0fH6GM4Bf;LXaa4zf~(nVExRQh#I10~%N!A) z;kwG{5^08wNVAa|e-YlCZ+rV}43B$xEM)SX)Ywy>mHN`!jX((Fcl>kSYc|5N4s9Fj zAyu@&hG#&I_^j^Od~i$IR@oeGxb=GS$UDfc2)Z;}#@-q8>!v9WlRl#EDF%Z7=jMjw z@LS6usB8f2aq#^88~Mk7?K1QKNABl{4Vrp)IRC%-R_^wXB`yd8u)LjgBKec7u-qWWx{$s-8FNQ<< zGYr`H&h5CIGC#3_Ns9$T2ARDdNaH_Wf+vqJ5x7T}&qrtf{)6%R5*Thm7pE#X~HCLSPGV04!{UcStdoRQ7_wUO*cyKJ3zKWhbY*FTPVnU z)`&`_MOqqfEbnrC+3r%FFI&G8K9+!%HTqiW#2C_8vP{thF1Fnmkv_ApMEGt83bIHg zXiAGNeWhdIHI{J|ePY2*&w6Y85cp%df=+K`Zo?a0V-J99N1ng^_S^0E7ryWXjXeNx z3cy_VKeDWQw%#ob-CdvPx(fh2!9{ETjW+?rdX*8u8bll!05;aPjQg<(AkM!u?23s~ z13o1b(zi?PkCZHuGO*>q%scHY3MYRUBV!}Bn85RtN|CN4VXufSo53BU$L(hdHwqM3 zmECz}#oVyerE#<|+liSyhkI4_P~1>lHfL_~dfeemqYb-K3)Phy%vkEUeQt9& znlt}y%=`~W6dS76z5?3l3FCC$3!a>)QySw1&w$x?_4feEANz@ibGLu)&zSlD>A&+$ zdG|5{E+Q2aJy@n?Oj?W+oN&M*fd@DP<`IJEpLamX2}uLeLMkP(L>)pM+CxqSI47*t zk0Ayu<2eEZ8L-mY9I`&O9AT-wO|Tz;lJU&C$smvt|B`~rr1Y5w1{MKEbmFBn_m43a zaE$w8NWYNzqx87y1@F~ssXl9nO5bGtS&8tFYus~rZuO25Pe8|!aDZ&gKtgrD_zAew zMXWRdW~ozvAN0eh9wFLq{E^ia9i=odsYwy~F3kTbEkJ|7#7DwU|QNm zYQ&glq|s&*(gxZyDH~W1P`1nZ_m$`g@x7@T7&LuENU` z4QFZV{xLH1m({W`4OyBKH$hu2ruv|#T@^Nv>t;LRO5|3uy6qa1ox|rD#{iDs&p!LC zK79DFl^I8;kIB<0KQjP^Z^c(kz<$cs?=HUX0sv2T*&2l!831Fw%J}}B?|esIef8D3 zp~WSl#qTM~fC+9r1;CrR^}eMLtddI8Cuvj*%g%1(i28;}m>I~~wV}u_e`g6Nar`%m z?4HtWTPRT_c*KPER+FX$gbXuT1gw(q56R}@Oj}=ByK9u=)I>DklbGd5=Pu(}r>60R zwNfJ!z~m_Sb1hXWTJ1_AZ$%$QxpO#PVi|GuB(5w z<+Faqxjx8fA*?oH^pN{uxCXqVUW=X-<)&`vtQ zgs)6kksAMvzGt=z&Fp~w82+01bZ#4R?6g_oh~$a4Wda_6?1X_dmkLC2TG~zHNrXy# zfw6%t^4x=y{KNm|EAo>+ey{cM-S^M(jhOid0N|%|h)kNCt85<26o0^ovF5R}q&2_) zIo|Lu`|TV4{rQXY|Mq*2TU+?U=9TECw}aq~m5ddlf8Yw^#_~4m-D8u$+$RH{cu&gN zK^=RPnQQg8zDA$_GAOIkHmPi)G{y+QY?Kw%I?!;^HhZf&O7c;{qaVwfO zgl7Lk=0<;w>SDsheG{^$tUaZ+3t1|_vMe|SiRM%Quuf4DG(btM*=J6}=;c@PnLOK9C1v+c~ zKbhB(COz04c6kJ+)Jizi@zV8OH_8YKIC$w(jkP8`Os}6T?fyuc<02nNV*~Vq6OW0~ zF?ssMFMcuaV-Em-g(ev9uFrhk$ldiMSFwy6!aAZ{W1>jz*-j-%qy5PQ*u^hLYaV_O4jC3}pop&<4ClKep>6v9~ZU78s zJI@<~HTQsFr{(X_m$?z18$I@s!Bb1PrIh9(i78R3>I#RyWUJLq{}Qm15sdR>HShuh z!ony8{!+0?2wf;L0|pA^-j8T=qtyQ#fW3D8-|e8Zyc9d0I*|!yX6(K{VH}&81z;NZ zHR&@9=`LQ{9B)ly`D_WNsHXFoiZ6sX93c2Tb4<->V>9y^PnwNY@80}8#WSDjj|lOA zg;V@VQP1Y*&eGO)T#v5gJ+v(`URbMo-pg6oBjR5Q)B9(Elia;urFPTK_9bzI8DP`} z-q@vPSNE{;2b~QVkoW-qAh~6F>(vLOPov(`wh7Myg1a_l!wt&agE^?jr1%)B74QLO zlo`#QrOZQidS{R$X@>A^<;Y{dinarI)+6or76Ad+8GDQ+X8Xs@6GcQc&Nt*)E$m@| z#XVlczd{aqEGT#CG&GgIj1nXnfxV0n-c)O0NTDEBLXckv2wc z9QF5){@aW5|H?hWlgN8?)Spq~d(wHxG(O%*gdDnBl0l*?kBc-b`Ebr9IGcR!)ra!z zy;Ie5DKj?w`wKsRnfZVJapJdhN67{W8J3AB;Fpkpn-(3VJeS3g^iB!rZ!F~C?!AZAbM2jfPHBr#UkY=wHwgq0X@ z2wl5TVI?`fDFw>}$kVL1w~m^n4W~bj0mM@2%m5fm0A7Fn^?5wtSO#EL zxyDhS$=&stuDc9?AL2Efe`ElB?Q37to12?Sm}5Q5AnG^Xcw?M(IkE;6J713P!}%Yd zJps_V3l;Pb0a;KI!{~TJB)8}#{eMGy?Vy0u@b))?k;I_e`@v*TSUyERYSQ$XrcnwWx zoIkGXV#GAUV$39*#c<%Kal4iAsDZ;kPdFW=px`*Wp=b$9DrBL61@wd&IS!V_@E)|4 zhU?zP7Yf_E*JZqk1MRNE1&s{v_KmHTX&zXOW-zfjB-x_QFzaekESI&R!J0KL; zkgOBkpE$+%s!_&G&D?VqK@wvM5P!ZwrW&0JU^~ehdZ#4FboOr|{ohZ6@G_I1MRJ3{ zoY@cgdD<#{RYPw0X#qtGo&jh130efbh=8v^u9mc%=CKv7uop{?lO)SE-0Dh)Ng@;= z4=ik@1PWKVOpO?je?teFkZh8arEm&yFGX44i4DZ$39?IAkBU^rSB{(2C?-5+RD&FT zr(FR2iFBI+v_^qEBUxs_V@XG(SJ2;r-ctYPduC)4G)TqhKj5M9OFB>1_@XkqfKy9e zz3`H)LF$r`hd#@qcc!c=YgR#w)OHWd0iF!^HQXfaEI7}M(R^yhVPO;{PU4RrTD5K> zjlS3(;(&bddh!3vwA@Rk`6Ep}wxy?O)2L5qlw1eiBY?LqClQtrofla~UcrP&!#Tz% z*X7M?90NFxL%&Rj>No~)Tw}xZku?qf>6_pDW}X5tmRs|N>z^ze;qJQay2}9gAzgzg zF9bSvsvO4vPQv~0!w+W=;9~fXKYi(?mu5zQ#dRTkjbi}kJ^-T(L{YJ^NS8MCtU2}u zCx8tU5v1`9VGRRsTg9BhFrTKj%-Q}>n#xCm@ACJ;- zF&;EUtU!gvEJ@(R0~3*29iE)exH~{|1}>axD-9}wb=G?w)i&#$?UwUZ5qyV#{2pV7 zB@!cCypbL>eC}}4hz>zp@jMOW=qJ{+>qZ8K$r9jDfy0R5b(Cp3iV2IEumLjOIqx;z z=Y4VfQ|rMP^qimnFx~fsv_B6 zB{o2Rb|ZsNkTql>hoq4gW`EovbE4kk%}Cg2Gy?-=X03?i(gde?3!_wn&O>Ivh64R2 zUbSRi45qV=5Z>{jd5+r0B|tQ zQ?}ChY(?ihWT)Ua;A0CT5cPlVW}9pN@84V2{QuVb^3#9&8*{_IQwDLhIe!)eli6UP ziVQ}%tmowjs(1&oZcE2E#9`_or1WNBCAzi+?jftaGbFJu$htwwIzW<=t2n)d=HOFS zfj=>8>+;`HVMdYK8z9=mMu72#<3toBQDYJfCj2Y!XGe?1s$J&s(q~vUk-9$m?7E2F z16|VZl4?+4g%vNV^{zO;1ci@B)WQz)DPNF=3$Ph`S8HccX0 z#=%_kpRI{Q%$lh$KDyj{>_Th&oh9*-?UR04RSm9v--S0_@_S{(Ky{_?f}kX4WIFFw zMjeb2C`yaxrZJ-k#W@v8q<2TZXBvM1U_u!PO6mOp(}|2MK^rBzLwN3sl9^8hnH9O2 zt(G#vz5!|OZ!mY@Ncy;sTDCAKPGda6_!v0dPJ(!XOqatj{-dfr(&=lgDpi%0oWUlm zafJdB%oTP5sSuMj>B5(Z#EV%&INCU=@8oeob!4r-@e_3;dm78qIVbWadB ztdo~gz9P+u_TQlt10Sc*(2i%XppB+VI)zHGgSO$Q=YAS{1ty%V%21j|<|%Eag(kE_ zL#-{YzKtvPoSf}vKc()ONIJ|gDA;(cwzN=WmQFJGke4pND4Y&!z&C;pH(Tb_BoNr! zAcIC}=z3!gSD7H99<7>|FlT~cOcOGBsQ}xq*rW~c8VNEN ziT-`0{r|$xenr0gWA_@~$MJIiavb${2F)9Wp=5H3lydS&jKq?h;t9~+7CeD+5-^TF z{>L%%Kk9JUoI%%ofb5+=msQu0wK0E1^{TMKAl);MWcif)s5f{&qpa^%qg zselTCp^`KaWl2_4;8kW2V7#%%Qk+w!`*RRZ(#Zm`pAmQp+TpZ!kOJtpUleG8Lz5gJ z`Mr)K>yEBQ9fkmum25XEW5WMvrqXk5sn_@&5$X0Y^*yVsfU^XxO+F3XID&2G)V(xz z(gDm7jsm%lM+jN8fz3c6>j;vhBVAxuBC>MiX?(8rTS``2vzLtOxbECv`y~z1s0Z-E zK?Odwg03MJr9_7&UwPkvKRe(O&X_9Rl;CO26Ct3}b}lbH$Sx$KAQMgMw_NGd@ps`R zWo+^z(NK1*zL!kpVPF8G-v|-~eM9!!*h*#;r}Pf=;urUJU$LGSMVBg-{o3xR~Bsqy`^ z5q(Z&Co(7h3aBm$izm^=!r=jv@rp?k>T#Ek0DSP^!Cdn{jshG@07d|SuWx_*+w*f| z0Q~7c{ikhY0W8ZB@0I{O!F9I;;D>OH+5d43=O6dJ_O-9g4J^hwmec7p*01O#vSpwD z{O3jK7(lFp8CN4@z1EU_#IIGLsc;HmnIbTfOki=tb~CXQw5gznvlJf1W1jKjR%cz| zywHx-FeqCwTc9T;u`u@hWCOxwo;LksROx(f{x<^w1gB+LX&d^%sB-0|hhT}ttZbIs zwrsa%O_esWwVdhSs4rNDn)<;|+;b>k&{`-ncJB5#qu$_k@1-EJ42%UumPQ$5ey+F% z91;#Kl!S(1uca`=nnPy7iWWT<@*pGb9146muW)4BOnu@AV<%)(P*8iXK!6*P_09|g zgwfK*)Oeh$A@bS6L6S(X_cESM03%OmXJ;t`WnYbgjI%exGYvhHG;&>cTk9_jWL}1l zV<@Og)7eS_mBJ(2yXYbWfa1Fd(P)+B@4!L9!3L|OL7xVdbe*0vw_$Ybgil{80@@KaY<@U?U|#{N#__E1JB}%X=5+f9&=@j-DIj%NZLuRt0My2yVWTeJ}EwXqd@H6DfjTWqPOt((!N`JJ+XY@yM^FYwmw$R5$8w+Nz1N|eJ z!uqCW^ZG1felrm}=s z*Q(EU9s`(KCd@+U8^hRw6-q^$vNQfj8J@6|2&-pA35??dBdIJDL+zlk_Id3YRYuSH zufmO3(Ieky+iu?5G%^{9k(Ul9u0yD`S^7}gSW3WlGlI7%qjiOs;kHhnt;97H^k;EA z`h0TneQYcN7|#7T1prF`#x?d$8`rC^zM7z1CQ(NaK#kzObN-*~y2}7~vMaMuMrz7% z`bQ98oLM{1z4X#cdOn}0<3DZ;;$5Tn#}-5m+*mR)uS~aVFRejq@(;0Og9>C!sNWKK`FYHlNYlC64cl84oue^a{)_MshPD7R@j$AP_?t zz}aeX4H8Fa#sm}Pp_ulX)k;HdtCagx6njZyV`wogKXAfR)8Y=zoPAu3!ikpw4`%6r z`1qdkS5=M%-5$c6oqUaybcZF^>LRgg>uk8o+SzZ7J`6yH0C@32TBTS&Dd$g?>_$nLAL7s+L&+5N>x ztap@-(B%3wH*`#VY9ux7HM=fS*+xtU-gjw7Cyr~({*N{PzZf(BjNh5|A2a`!V-d8? zG!_EMM6QT=3%TU;#cV7?etVrh%Q`mX{A0Q1zYOwU|LynX&;RXjPM8!jU!gBzQ#oR8 z-qfr(KU%g<+p~Pa>;JAnTo-ZV8ZR=(z&lD~PrQiK-Vl{JUfAdgPW&#F)=v7Gpj{p(zGB@8`cSkiRK8$tl3>O8G~k6gC9{G%|4s8m_g(!sV0%^{-(wG$-L9Dif zL>Af;kv2f6C-u{+leCX>(o8lyY@iAr=)#LB2dHVbhZ_y%#Dx~$$rYMPd8@^v2wno6 z+-EhpLX`yr;k?lalNiaf2FQ99SXau+b#fj3j$N9u2acX%rhgQOT}kJ%UfpP)5J}y_ zpw28r$bAMNkPTjvkh=#M(`q1mtPFIePk3qUb2fY<+(8Dw+RE4iV4MOlY8ZaiI0jHi zd@TT7LH6DCNv^vLfG4=Zk!SfeHvz#%DbSq2kw zRRC5qz%X1TV0S~?@n6#kPC@JgSGHZGKx3`)UNdcqHxxk^bX!S5nebY{85G$n zOTYq_97~aO))WY(alj0u85}38=3<<-4XNE_oa-{SUHKQ8^G0kzcI8YFjW8bY2O5}g zS)_gQrh2=Op-}iRqBWeoZoBWnzlRdbz~^0*{EsEIwroSz*AlJ{)&Es|9#! zE-BEcTChtu<~-%NWS)~O@q?A)JbuqpEQ}hI3RX$>)nYk@BWF6zm;Su);B#}g|1ZbP zKgz@TpELiJ7L@Jpz>9g$_MOJof+jF0T?HUA|i zBA6k*B*OW-1~vImi;v-u7g=d#F~oT1xLL`yjqa7gk(4ulla(I+H5LYOH#hAQUyj4Z zziRRQsg0o~Y?$2_D$DeMdNvw=LwZHyLb=Wl*1$zq+k3`?P5dqE?Rs2%3K*q=>m_J< zc`sLhau8|a$2#r+#p+Nw&WS!$`dBBkl5Au+EJ>#B%S!Vh_ZSiJa7Ddx1wm5a;iPe` za<-0%mh9LTn7EDXW0cvbpPb>q_QQ6d1ruz_Cksrg9PMKvq-_e0Msp^qzY^x9eUmZN!M(__|Lf4Rj>vI{2bpz4?ZYl`{1m*6&b0S6 zKGdyecXVovZsRZ?EMm2x`@KbYv{g5(><#Rc4wy{~;sIE5!+2Es$az z@Uk5^Yl0`ldgpBYV#{~D7Qct{&zqgU_uhLAJ6QieE}Q}|HUWJ7_1EY3kpVC=t}9S{ z3v%zSPjuY{0Def<$N*R`Y+^B@S-8IUz3FSG-Aehm@Ps*00-4n0{KO_^(Z76z^fuH5VeE!uY2bbDiXnwIOjStTXookc5YR`8cxDwOS7k zNZ^FEz)A8v%s3zOvy~Aw>TcN;+#iga6mIwZXsBzhB`%yMd`fgJ)(pVi3NmyCM=tvJ zpnC9r(ni%g{!T>FSe3HE2--8Llz9YLHpZiny%L0k3;+$hJeRxu-zPa^^H{yH;olD) z`$nnbKV+TkJ1y~u@!R1P2VfcSiFZK(dHkga8KnN@b2ln~{EN@agJ({KSRKy)W#<2H zeamP5t9w+WWQhoHrZr>Ev281!a4;-sd5iH*bfZ7g12s;Zz@dcfv7#<38HV;&r*LLE z1dnD4zk+9b+G?E$5VK`keIOB#bX$MUe@+AQkF)+9IuJLt(J7KOf<-Rs;9{(yYgM@eGZr$9AOb*2Z#9|^>m(- z?vyX}nDst4*-mB5j_AA}F%ShMxQL@)&L_w<}Wuw%SlvmJIBDK`-N*$|{I`8it z?$!qBC8OV2hZIj8J4k<0ax?p*RnQnlks}^#`L0!=!==eHNvFHC0PZ^WM(?w(179Xw zN%vZEglH1&@_;L~iRx74YG9`I*OpK2FUlA?UdlIr=XZX`UVZh|aiUtjd-+b{&DNIgu1|U01puDlf?)vTV5I+#V=C}`IR97% zFpjnu*9$MaFlYV8-`E83{{8#&`G|_OV*n4@Pvqk@RtS3$;WSza#kFm{Fv~LRtQ;pR zD(~P zBJCBa<}{V&GsKpf2Eu!8Y-MBSIz+!VeQ+=oy*$r=hLOA(!J0!AUoFQ1vzVojyMvFe zpJ*VEUY5hBA;h)Q>n?>aY&wYYdpJjY4BMGDBII#LJDk3)LECBkS~&y0Hg~w-SSEj}9&CvWAV@7)K-Lcji7-AqR&Wvx zV?ceyz8J+{b<#wmr)d58i}U}#U!4E1T%7;PATfF8;{5;0x5v!?-ug1d$zHJ3`gpsF zZ_Z}HCZEk2lL`%-E}i-l7w7-}(>GcFsAo9;KmE6d^ZzIUBH9h$Kvt8b0$nE3ou{HS zr$MLLlw~5d7T=uyg=Ei`42>m@I@I2B<_5ga@hvSW_37OgN}EAewK z9l)OyO{nxNfy6rPPk>IOAx@ZrvzF*aaUxWVQ#$lQxQy>PyPGUpPQQen%#~>cX7y2| zWQaibJ79eD+{XCQg>TR=?e*q;>2ebF;=3F{s~>yEedA5(@=K)Xi|b0#>f|FlE12-9 zk-RH7l8otl=L>0_XUUWk7(Cu8nO#wv{~9;hbfie{Yi6fO@H!PFk(zHJv!jF!js3!J z$gk0m=_a7VPAf!m^=aGz>-W~d;(D0>W#NA;Bc%6LJMC4Q>%Ho<(NfM9KtalWVrcB zKSa}JP2clAS-0Wvqn?qUGeI0n04{#e+yh|jkG98}!{7V8-_wippIOvnWA$;&`j}{q z4c8@(1N7 zxi5RMrp8eiBN`U_0oW&MkOd2AY!~_(%$q7nbX~_R(hS1+ct8}p_mkZ-zn?=XjoB0| zWuLNR5B|e0%!WM%Xa;cH-)Q}yl|X|O-9xcXW4vkdDm(2bU4*cOKqBdmzJ#o7%4`~{ zv1>GTN83O`=x5?4 z{(;ltdm?D|1MO`=Q@-@V@idpdJyJFHy0CH_@f1$}_MOiv`Jm6CF zoEt>O3)L3nNNsk>nv8oUPW~=cw-TLTd@JY|%b&JRzvKU%DuVMrvZ4S6JFRHfc{wDdy6m3I zvjR3FI5*%q-shmeiRdwTTxnnkPu)33A1QdII3}@{)Bt~(;AS09>xH4r(X{@&)gjm3 zS80xt70=|6q#_4#$~4JeQ=Ep}ODKzB+e^ytYQG1xT7#GRg&Ra$#)aYr^McU#+!U8# z5NY@DxygYeMSCPLX?kZF7>{RAe_Q0~aI2C+d1OO^jp9%%hG(JU;rP=6v zr33kh-!hK@%r{2>;CtWu-UKszB|`@FSOUNoZEpAxqjPtClIt!5;0domgosGdG64Jf z*S|ig^y2)_4K2n-7caf^(p&-%>;84De~D87Y}rrXQ?%cO84FAnbStkobGukDFtK(e zoI*o=z37}_Hd;##3rZ=~Tv&jF(Loi?PLig>rf5(`g6B;NO3nH-(G?w}Sr`cN*>}wB zp(C+gy!2N}yP3%_{juS!>{5nJ;Fs%lBhx~0sT+q;c)ow~ws;nJ%Mq!2Fjh72zGHnq zN{+zEr~_OYdlG17QD7W5-)t`}6CWoyO+BI;fr)|lt*1OI@EO0{Nsl0dR7!8nxL(?| zI`$0?D>4$M(_(foMld88W~2h{;g}(1z6Nv|Ul9s+(BK^40}ps%IEIyTf^jMS$khM9 z-FT&?+mEXDIs$Ls>s^LzjybOt-6P5#e6f+0xx+XOujZynWzBY#KVALGYP29#5J@87 znVjh%bUA)3-)T;VRlkd0Yuxfv`z&G-u<()w=a=DlBQ=|yjdVT&wv4Mq`v@vv7x!9@ zWG$FvM2Dia#2}B++atpx9WYItBEXeKy%dd&`!ntTuY5(m@?-aN49DL%RxfA%1FF&H znJU?-F5n)s-;^9u4yr`ZL6$3)qKq~Fe_}ZQ_ih3{@7tXD|2yBB*$9~D%i#nrqpSoC z`cOsLg#e1jBm-u9dlNK(|II#L%U4EdiUI&U!0dT@m(~? z_$_@B_oUwU?pkCoSeC1kAXaqLK&6A8V`}sRDbLb3R5YU?FAEfsiE;1RawEQy8}-Vw zYV!Dw_E+$G+oT~p#r@gS_>N}Le_-#egl2Y)9dsG9wf=BgAzgyeXG%pQ0ylBg(fZt@=DH;5h zWo+m>vbHKC#TuN={v`P(^gK7Fqd~%0V)!!fWpY?TlK4`G8yuHRC{BMR%;QrzzV|=#+lU z^E94H_c1;_yT)#nQMX;;=SUm{I5Pld^%r3rrvShgnin#t$HwY71wg=V`bkFe?)s?f zE&%WZSIi);I%IBGfpsgdyz)v?=^JmnG1FWIfsb`B7vle+P_TwD=!&9@8aG&u>(`95 z2KNHS8t&JId+JAsi0>jQ5J-ac<9i%cQgEcqNn=Tx#N+h1+Gxj8A+owH(Xa4@JvvHM z3}a?Z&TMr9fb7#ETFN7|#4TBRT%6=20;Ihk#5O-jdN|{7&2nHZYQe8^H?Tb{PLB z?Z>u_0(15wyI32B5onI9-L5E7txX6C4dXgn!;C}~T~TW{Ch{3+GtXABxlHAp1_GxR zi`07CateVT?1ivJMhP~blkBraokBbnFl}A2f&*bhk22?+X1CT??z=l<$KVRal2dRQ zKN@NG8O;|Zhq~j?ohZ#CC)*KqRW$L0)Op<70@vpq21ju_SoU#@HEka<%V)ZxXl6s4 z;|~sL9tpSQ!l86ZBysBHPn#btH(eDac%lPTW+an#>Gyv+R1qyD6fp5gre ztBdo0K7&?_9Ksq4FvE`dY%RK-kIl0M*l9*)&kPbs(a&)H|J0XW@HPKdIQ#YA^_l;% z;UA7dRPF1QO`r!T)gN>j*+ha(A4U6;u^bDouTt`}7~}(-;l`gtsPU=SZl?u`yCo0i zI{mHW81Cuv9OaeZVtp_-65KRpDgs5k#GnDis6dc7l;hm{h2($r-LfL^rndT0_~g&= zl{f1=v@N|pd~dZH^;?d-x&}v5L#WbsmW7f*OorXs%q#f9TAi}Mhq@S6b|6zv*zv`t zr|7vZ^v8V@lC`Q#OI|2f|Inq<;a~3?Ax5bk;djEIV*X3`mU>sGiwh*gwg6&ae{J=& z7d6?oDzaW=*cUBeLd7|N!EJ*k5SVRrN;n6m_q3ac8Ki>Lt*0!9L>bhG3 z@MKqrS?2`a2#`0f7}uU>f%!E~3b+ITCKcbicTYa+l~F;Zm0fTSrI>`*@`V5EOdnni z)dNPXWN=3LWTy$5^bMTxz|-akqlM{(-vt{%Vj9lP*8T1x14F7`&h{2 z$r%L5+2X&H23K)ak0;8k3%Jb!Wi|H04thJWn*kF@`P^>4<8 ze|}@PT8|#1RsjGqRwkLyo&f2P25rJjHmwW>3;ua(toi@a*zNyDYSvljZvX$q|2Ss; z&rSAhaB!{G34`X)-&4Tk$Barda1m%pBRAy8CN+LVN%d(d!}`7;C@^Ut2_8nP9n4Aa z8|qBQmGFjs0B+C+Hl{2(BD&TJ=$()q!dwwNy)A9(tMlT+SaNg48KdNrUL_|W zM+i`&(^mJCsa8u5xqQ_cuq$Z`-02!bWEs|kLkqww+L8~IB~BPadYB9Hld%4S;T8Ttyk19njM zGb2_m8;OP1;c;4*Zg<{Fv+Mf{(AP-wlUzyHN)1sH7CHdqG-VEF>`Xh?+z#GOG`>_R zJL`lNrExYTt5~(^W5`q93{XNwei~lJ6`KH#EPy%NfANL(u?gT<9{u8rFU~Tt2f+TF z?|f&rFfsrxKGlxp))R^_PVa&MpZ&TE06gKfrq+**D#lv>@%Qa-e>;z|7{A97fRP38 z{PWM-h2WEoM>@=fA#8riC%@QfoxfASawM>q#donX`f*P7{5_odF$;8ZjdTvn>U=3R zciT7LEMORLegvSVG0Muer5-^JZC$alYSk+d0+ihrBQ96M4{J zv?!g&l@|E|zRn_Pj7(=}ukmmLWtma5c(y4iQX}WRjG9s3c{+!hIGJ?4m+8-I-c)KG zdpgi6%MyX!pIp~Ybu_*U0){hffIk8V>D-9W=3bgs1#w8(IyA;6b#uQf#ohwQm~aQ^QJ0;uEfo!IUF(YXR-mVMWd8&(KY;HU7O z{Wm>2T63%{@!&h(tNh6?v-9u${Pp4d|GcODXC2WI-^V0y6Ol=#pUG$9b^GRpTEW41 zv8~Is+D}6l`fqe8#fur(&~hBoU<+b0<{3N^1TQrWQ0&xiuC!YFzAs4yi}sNHVv>O= zzy_9r&KkdPG>M4PEGP$1AA!iRX!VXfwrKKE#A z3mR#9UzUE+d*J`ng;xA<>nR9J-Kq?E^?Bv@PkbfMtguR-z7HBekbvR23UiX6HMkKB z<(E3mluTm>DQTlRny})N_NpTqSYWjyc2?e??tJ8BOtaA*(^pM`RG=>H1%lg%aS{d+ zZ%l{4G2;r85FCtJsepMbfA8KV2Sxd%T>iH)V=_}#@Kmhh9M}F)x~m+qZ2>qG#8K|uo|{w+KAMq%L|QoiIv?Gg9!PEKm_Z1 z`#1u;a*YiDM*v{>Iuw3alU*7+QO;|uPZ{e}@cTl%S#WG@F)l0txDfPM0+38F?p+975M*4Hnu-Q>N!D$`;Vtr&8pp2)&c|wwXx1^1lb&eV2 zB<~0)(QKs%V5=;Y1T^sJV^?d)XSq$=ZuTWpC@2%oI@0UeiNNua{@r15yG@%6V;c@Q zs?NjFlcZN~yLbyUSw@cK%-VS8Y`qWjB$F5{%kp+{wB7mt@=W{p3P-!;{O{p#)`(#T zf8RGl>com2G!JJtr1Eb|)<)nlXWkVjjYu0EEP+u5+ya*fJ`oH?Op&yl?FJpT=ka~(Y5)1h za4z4ug1)za^|D&Di{tV(wT1}o-D}Pe*lQJ8tb3iVt=G1b#~5+hb(yt_X-~cP}2bl{Y*07uHTmxO$%MEzVN@|eSvLVHbY2( zMq50#$TNn`@@cQ({L^V?S;NQx7}uB}g|CDq0DQ$sYjSt}aIU)yfG4=HbN^VhGKg}l zPYL3jVu=F)h?K&)irnDLB#=-Z!)f0ncmFRWYoYn1p$r+PHB)aes4;_|J=-f- z5LPVS8^G>oQbuDO&YqDm9Bqxf`5BD3*;2@hN{pGLGl7}X*{@s>uc-viyEW$qv-_hx zoR%=!#F|qn;v4?W*}X;>B~Fp_I}`R30hZz%AC{@7afX0%OeUsF`Wt zosCmZ@2@(PrhQ9+gC31G`O|dV#&2Z5s8RbGv-dkzNgzN|FsOERtg#ddf^~Wqkrr4m zQn0`q+dz1GFZM~kn9ChDp{xQeLxN~LXQEZX-IC~m!3M)17;yGI?(HE{+!*mpknzF@ z9wOKhiA32pWDtT0n-*PhUyNYp`{!KJV`(+zdfwe<%O6KJih}Q9v?z^NTsZBcmPzSM z`~StC`LcZV$M4nnT)w>f{c`?+@10~M_$O&N?D3bUSV3#E9fZ zo>)Fm89ebG(Q;+XSY}G4BbziD*&I@vZ=OXO^VAOgQgS@-o=z!5ci;zWm^&>=>cX6T zGjN1tKUSwMpIh;7@-TQ-Yj1|m`28#6H#0;S`Q*j!bTp2}SfvcXJ*z-TCS$Q|$@WUd zLT@JjOUX98$b36d2Jk3i-_nGw<4IV?5uG$du(0I18BtQt6xkls4_%8AJirxx)7NtP zwd%sf*+#N})4vt%3RWXlG&=AU5$oh%qK|X} z)iUb_`(B{JhCdpA&E=8S^%{dhG?e(*3O^ljb_G$W2L$Lan)UJ?3()=!6-me)d3~$_1kv66#4NZkB<|&oLYwITQo@c7Yjg1%xfDiG1nmMBtz>T`ck8NAv0{?`~ zDN1SmqNTTjc$xi_dSZc$CXQN1~}_*i3k zwUWJccYXHjE(72RuJHXQsSn40M5o3QfY)DteNrZNu>8H>`#p)YmU#-mSOPG$fbJj=+#&@Jq?`3a5QHm^U=S17FW*7#geJNmM zDR+=)2RKP~pt@HB(#b^|UL7}u!{Q&b;p6W!sFpY=+*LaTLyb`xulXf{5B}r4`=1G% zKMPu`9mLVsJ!lN|jS~@&o_X48Jm*GjJnLiK;C+0q8GTV{nKy$r*^%M2ejxtgW#<2X zyUhH5<;U+AU0&cCo9q4ZzkbtG&_a$&+~hQF!}yC3J~~{Q0bG*5V#z1D zd_sJtA7i+&ytcGAQ>2*`uT4p{OUGlplS`&(JwIgF3E4Ut%Ux8`(RIG1e$6Zd*N&de zB)&W;%A8_tdv0>NA;>9>M)AXvAtVQdzBYP1C?a*)Tl^wTmbG*@=!eh)G;qo1+BV{A zD#h=?xd_~~eH289{%Z_yai1`Tc%Cwh$|NE}61TiN)YOE8JQIa@Q;Ah%@;KQeAb4&%ag;W>h%LK^{Qou_IL zdKo;Q6BkjTapgp#!IiT^Z8b$yU5k7R8O@^C+hK2?_<0$S4?g%{mKr|LJMX;XWFM!a z4PR+&0*LG4@MjCd$I52hepzb2yFSfz7XbJnT#;ss9V+Mb+H0>FHn14iNNX8;0E`TP zx88ay-+ll6_vdC95fS@X=E+M*HWQ1N+@z>(!YSQxQt8HuNJThzG^6RP%o$sY6nxB( zq>`?*A074+tD__g5jXF4({^%am-`_*JEaV zS<-Mm2Lg;{LNGqS)il%tzhPug=couOJr-U5O@q-&sr%71N-5vnDG{yIeKG3_X1R)1 zixGA*44|-chxDiiY1ipsES2K4176@balIvo`8od1bov6|-Ivryc4mw+4kkRiwN3K8 zPHDzX(u$QsjiAAN7CUaKHdM}+m5dDp{t%47@ov*mN( zA7;^kmjUK!Tdjb?t@kNrG6bV4G)UU}E|!jD$}`|>x7>lfjGG|YC3pz~XLCuF0h~Ur zB|qkx|G#o^{$IHlc=hK#^Z({0xUk2#2LBovT?QH<8Zc?INITIh6DTrXi0vjm|J0X1 zKiB+=RQS;79!tHA%XRer{V2xLFJUc&nCo6h6edZFh}UFphP)MFd%l z(p9zdB+C$ty-1Q<)h`9FJ6l@IMkLx=VU&fJMcOGbO83WwtO*wyZVTt1K!AC>{05>m>~Mztqt$YR>hK`|5FGXpT7E)Fc^vZfp;!vD(mDow6j71V@V zq4xM#Q?9So!vnk)aAv&;vTL`V$Kc(+NOJHQ_pDgGx zf>nZ-wDXP8^M-39G-hp2=4GN5$kA_}VC7xOrW>Qr05DftQM99Z3}kFuMB@SL6S>JtjNH zHGH3OjrIK_D|!S5unFLLjg!^J_0RwLKQC$kC_&f0u#as0?)n7RT>#+8E-V4a8y5o2 z@2|f4>U@A`)>r~CHoAEJ`R7N}OP+o9S>uf`42Q0c>zcA${=lF#&nx@|o2H2#4J9N0@0rTMnBYq)GC(WfCv&lpYfYrc*Br zBkI%@FNB~*gG$PAMy^%*@jl~w+@Du$YL~MS;qY;a9dyz>(hvPJ%UOvXorUs6|JCuV z8)Z+7XD7=UEH~y{5#;zltH9W{)WGHNYo)_Oc+U+UiGZe&h+s(cU3s>jl&CS@(jd)2 zl+&rtDymAZjYj2oe_!P{kwB)WCymRhV;x6YiXa`5E@3YqvCqZ**1gf+$aO!O7-^$!fwtz)rQ%2cU)|o#gM#=G~ z#hrT$1n*0*2cDAd12*6i%SvXp40vUM54g_ki>>!HXT?=2kd^qL>>{go2YJ_QC4`qF zJ$-;c4E7Xw{=rH9VQl!vv-R(OaF$=W%>4i0@m_M)%9;054^Z9`4=6X2WH=B9T($mJ zpGSe4n@wK($?Q{wx!6<`=M1jk1CvSn*_xO9hwd<&fusb}CBv^>+PIKx`=)QzkAVuS?9IZZ<8k5ykAnf zLqzy^PzI;r2XzJkt#B6}Y3;BT%vpEn%oN<#K_lx~<%X_WS%QO?%b(eg$hpaBNAAsje>+-0S`fegYERv-RDmdqp1l z4ti|#WXCbI60^=Yk`A$Q9Y%p0F_HnY0EhlaM;0r03gWk;LU?S@@HO0BrN8wajn`6! z^>S?!QZgTfGg~9ZX@UkgFp(56Ci;n>W;0V?$FpfnS>g?oXA@4ycm(++vQ2l14Xib7 z_?p}+y+7O1>L~77{!U3Mhim0+=4tKE;QZs{v#}4_$N(5i0Qfqe&#j?RW@J|nAg*i# zcz1oq>n;HBWLNN>$=D1KO8^G3e*NoT*PEN0NvLB9z~;Hx^QepQIrab;4nLw`v7Eq4 za6z(IZ!IrtPE8tsCTTzkIWVjgS)pgj+%(X!Vm7YL*IjbkGui_u7G9 zLzJl0EK%#0w$3S~peK^0HuKsD2OAWu4}?F1Q+|$8gd6AzV~b}540v}iDPe74>Cf_y zt@ae0`0+Y?gFx(^;2p30PIOOSC#4#hA(k504h}4zd0zIQH6=NRD>gOD&CNo=XG${oQYF_|n-t!BYyyYK zc!_sryD)FZn_Ll?E7wDV%T>$@ADnEcbvw zUutbP`ly*&ZETpyVw+iwX$6q3h{L3f+F)~!RPS7uFV+k=cA~J++xY#$vnTn5pTTbb zRsC3B|1ZM%A9VBhT!t5%S-`*VY~XfSQ|3_nIrC1z0ucI4`@eTXc9h9)T%7;E_;jJOn71)3?S;m4UB^u4FLKnQd7e2FHvo=vPZ?isP;={#R za7yKk+TZhKsik4sV46A<84FS}q;-RLq(vEC;$Z|l3-yMM1s_pQI@9eH1iCG42@Tnx z#az^66tbXjtGY9C074SWp-i0{e~`@(F-g`7pUg~C+mqy-RU8EHkT-=A-elhiKn%F zyFSr%7XbJnTsR2;O8`bn%h;#_*B8F<1-%e-66#xTy`>`qU|f*_pvSc=$+D7c4?#$Z zu@#>cK?zASzNY}&%b1p|%4pYoKi3_C2f}(MgT3Uf`AnjfVPIkOd8%f?ZZxIF24V^3 zI)ZMGwe_q3o6~7s2Td^(Ger^`l%=x*cGH$5OQtX^(!9>KWRtbZ9mDt@wo8-Gw96TThJ zi{yYMjclQKC}fZ28>y6}9LiyYBVJN7aM3154y+WWkYNy10Xw7U0=f}Kv($_#Ha0`L zG;i8gXvL9(z+<01B!9$lt;9pj6KwPd#@hQjG8_Qgq)n?aV<#Vhm+}1s{6+`2n4Ycx zf@J>@*vU2W$wp+%tMj=Mk8x~X^N)-YU7jg;$_}%=1C(>5x=-{>oKjjj1yoR`mVZd{ ze~>^POXf%SS&l!(z&E2T$0+wsu+3h~87`P^JQ$6b0p|7A?jeBf1qs0RLN*t35uf2YK*aifnh5 z_ZSE4cOkl0vIk}$B(L^|$T;|^I3_z;+5x|wwZ@Ck1Kz0qj{!gLtz zTHZ8ar`uYJ3ptG&w@UIQ`MaR)D z)sWGo*QnD0Q^_|EJZmeHW6T{5C&BhA(}Ykf%kM}Lm`FKI9GwsfK$&z{l;O$__I6E3 zW+K}}iB3&Ofh7;+dszqdT?_uC)rH7dC*>p5OLUhr$W&)`Wh;8GEIn(*_+tG~oLS5E z64s4$5-Q_mlq$_W>-eU&j9S{MUrA@aw6W1ct@ZQ!*Jp`(o3=D+%Q&~sf{|7qMli6( zCMQs2rB~{Qn6%mSi6Rv;?xbXj|8BgY)gk6})aWwLglFT6^a%UAQP9nU1N%;6Y<56X z+KE;{H%mNOcGDXEyyb>pAtWw1r&9o;U7bq+#^)dW!5 zph~!{QoK#;J%BwEf|Z1J%uIM{xP&|$J=z_|P;SOU<>~l_x&xf?F?Le--FHXOVYGIt z{-zP3ZZNC1SrFgFe=8$4(gAB(fR8!ZO45Q!B+T83wagyLBfkP(C2pRl8(An zmy2G+NPhy~cGd2i{oc#qp0mB822!b2 zs$V$g+#Ppz=o6Efxq?h|Y+6{$7is*RvV>K03z|vouaJBcbZddAk{;HMt;8lqP67Z_ z6HZ(kmI@SN1Apji(Vrx4r0!|a$w{mKb4;YN1MvP>?|#aoCWegJ)2_s3kO^Z3u8i9D z+IOqv01V#%F4xxMGz}Tf|Bd|O&wg2c^2eUZqcF!cX8wQWU%xds{M(6e7pXgOd9K08 z`^~T-QD#;_9Pq@J#-0~^>4m4}a|D*gn*YD}^S>tV#BTp?=vjlK_)roLnb8tE`_Hxr zoT8ngsia%*pc<_?)iey-bbC}$86Z+rS%jGNIk=ki#7JcsgmzI6WQ&59tu`A4PI9G3 z^no*2AUjL`YK==^U}&x_8rdN)gH|y_Jcg1u>-V5ExQ{D*=7TIuC^*>!{IW7WqPH~dbl1$}|$i$5jmDm_ZXC(U`=dSbDa z*V%P`_IX_?X~h6!5FjX#Itur)!i7Fa2lIXAx3Zzy>w;jlBp6FjM@VK#)t|WL4;9kq z1dA09XJ4(;Py#Ki2dZ9__m3LM!e6gz;(9NA*TyX`Yxn}NiT_d#0{Q~aVF{;EKZ|at z!mTlH!C~CzWRxSV3H@e#%(8pESG^XAF;o&BNkgEyz$p?_v?3frWGoqQQ-a6J$xe{* z(mGbb&*Nh*I}7|FdnavJ?R~3vgLgNJQv$Y7|K7*6|5dKq*v$Vd3)_u$-To|20TB31 z=EtIsOzN=*fL?+C8A%-*sq@}y;~LKY@VVsfdgALY0Ptj&=j{h0Tq0DH+JEVnehJT0 zs$3j?9h(3Sf*zXyjwJvO9z0N*C7LGzJUkT#>y-vq+3T_bimr@37d)g4!)i;F$Xq^h z;HQ(h<)YZ>29a>nNKe=OGCQTaJaZ$Swl3bj+UIh&_-RDVY=g5rbs{vVlrtSoKX^t< zVWmJWxLtsi>6*sYmQtwm2s23@(AwSGe?9iY@!$ z5^#$)Vpayb%|>+E;k@zGxHMci&&mWF1*+x_Xj9|(2?OD9U7kJrbitDHe2yWF>j(zS za}Xh%A*tO6gY)kMxzRd*hsA||1Qn!|T&Z>v=F53Z)A2r6Da?Z3drH!2KB$Oj7c;3A zLqE|#Ss$1nN?XTjoB)~;lpwdKKd0$5Kz^6Y{Imb9=<+s3lkioq7)TLiz!@s}xm%ccif1`ennSWpN&zP~KKhP7FkMLM? zpu%FTHo%F}CKZTMER!zD^Z0CyaK7})efhtB{j|wZNRMC=7y6ZB~r#`TW%nA zfBc{zZG8p_~TCJ$O0{@N}eN z#`wxL;oanrl6&i=+1=&$mb&c0Gn?FdI+FS?55Ir;-m=2PaRvA-WZJ!_;-vW46x56t z;6-C1^Vru1Pj88aA#a}x+)0x-gaavh&cJ!g;B(KMfPO|(eM?WL zY?$zjqK3*08OMT-zJSk$llJI_@#Y0NJBjZb^PM$7l6J@GBjXzMHm(;QoU&Z{l)5%>sz@W@^8d3>Zw-d6rhuwWekZHwc(oiK6V6IkX3F?vne)_1r48y{dUX_ga51!1 zPwuemSQfU8<6-3fQ)5Et6(x3$EVw)6S;v|Ni^$+t>r(-FM%eRlV@S3s@?xW7+g&@^o&bj%@0&1OUqb zMwz?40G|B1TLSQ8mr_btBSt>DVq7Dw<&8Jq&^OMg~o!sv^uCLhmFg2J(o#T}=AgO;?zwTwqwUh$csY$?)fQ zGvOLlE4|b2`Mv@*V-UEbKiiY?m1c^M6E+;&b+FEim5*%<}{&Hr>UI_>Op!38!6bd_{e;Vr_zABC}5 zAdD+ZLm*5f#kL1^M4LP7=)1S$Y45B6%CO*Zz}Ognw;B&O+U-z2Nr}hCG?xsjlmdm~ z+O1|H&<7q~q&A~*jo=Gr=apfT4zoxjxom&_E&_H6&Y5NlSfOOWWA1qS3_2^`j?aKH z+n8zhR0=#3>=H{7;<;+k-kg2c0v`3nj3CB0JE?(VT0(&F%H#cF5a5hf8nj=zL;`z> z2&G(01!2G{4pRhfMDx7k41z=*oW6*0POyoH9$cJ*|7AM=_ZkVg^Z!;l|DYRe^cQU3 z9sTHEE@Pno+?a|DLABPDr*!CIcK*Hl!6R}Uq^SY$$HXD6$2F;?F}`%8%4b>njdvg_ z>s?90=C+F7im&q7euNXaZ}#P)kA&K9jhGa^w&I&SS}yKCiW3=uOE6RzqY?Jv9 z`f2g5HvFPs@@qBg_x3dlB%TLNiqWzzz@*$Cq8D4*O*ob;gOz>)2eR_ixHdTwQX6B- zca?`jdwHJyPQErd@Q1F*kP7nMwiCWCZR!GRE01!wF$bPC17j)ALQv(Pt}Ah=^KJ#LS=C=_YWTnKTMg)zqK!KZR^|u0KZ|D=8eaI6C+3Y1qL+60$*x zzw8!ycpUeB@g4y8@88eTyb0jg13(t+V-vu!1YpSkFuA)v^K};hc=9XwR^^}lvwt>C zEgV@f*013D!WX_^FTM1Vjbi}ce*5hdb7K?0kq&d2{V&n?2}#;WORz2^-fl_?;Oe4W zXFYB;wRLXe+7+p)ND(sO<78lH0E%f)o-Na`OOUR?2w9XI1WShvhHwS}LXxHto_iHg zTcd64zzRXk4v1(|sIxopN{oc;BB-$*OoebC5%)YM@bcn0%F~-Zdnz#tAKDWNA&<=) zPtFnn4mh6CW=1C5O>_rJ(>ctU;#j<&2A9D=0sbuaSilU^e3v$)vuLC1M!%0)wk>ev zb~Y4+#=Z(xJO8UTdQ6=wN183$!f7Q_)$8?Cq#%cyJv5MTj;$E7VlWEb9zeTTLvF3V zg+F{WL)qepJpwLgU85Zg_4sE`!=RMvq(zLs)u6G#irbA>ngyav_5!9azSm}yj|V4} zG}z(j@WxY;`pZr3^;9f)Ijf&cCF8U5Z0=fHFB zVW=hJ*0I5ub$rkjM3K0$4w_wg$7NdtPDF(FHA$MM_Gq}1XV4C*$X3s>QK}22i0GjQ zwTd79sM&mnaqKUa1k8X+>H)d3NuH2{Xa_tcUL@?WTf8mMT2v?pX6Gi9aivs2$8FxA z!7yrwhlQI>-4)}k3|s5qE%&2#Tj9{<-Q~Nk^?p?S9I3kAe6JK}(gh^o6MZ*&m1sno z%(vEr^v6l#ZPPz-4U@bOb>>MXS_9tquST=F{`1K|ZeZhrO0Qef& z&?AxhGC4XkrE!03qRu`Pu2^y%?cHqx_$1d|0N}|lEM?I@^Jo6dHd0iu1Yqm|fD7yY z$1#BX@`DEtN{@U7VlKylB%F!ltOpw!^_Cn&4sPw%)&p%w9}lBtDy`V$$2gR$uFX;r zhQ>F7LF6bqRwc@?nW0Y{*>~ewn{`=rvEG}gp-lCRWHv!=X<%Ygz7n!PiQm{!F1j>> z>a@8SoG02e+CR?ZIEb{3jBzBFN;tf^(G`YNQvfFp6?nkEF+u@+Dh@cnsg_TLc}MZ8ac8Bd z(o+bjGRJoWfOaFL=@0$9cTIe2wv!>CG>DN^!H%`^ETc)=EYT7I7`|RFoEsQSJY(#S z3LdHIWT*R1OPcSe->;IJxOt$j!)~&S5q)|&OT2Gu5F=@D87t{xsqQB9%`t#IjB(wt z!?IaAdK;V!Vlbyks|`5GI6Ch|pU*$oFri^)De-? zb^u