diff --git a/crates/assistant/src/context_store.rs b/crates/assistant/src/context_store.rs index 9c2c02c35d..0ff6b01fc6 100644 --- a/crates/assistant/src/context_store.rs +++ b/crates/assistant/src/context_store.rs @@ -22,6 +22,7 @@ use paths::contexts_dir; use project::Project; use regex::Regex; use rpc::AnyProtoClient; +use std::sync::LazyLock; use std::{ cmp::Reverse, ffi::OsStr, @@ -753,8 +754,8 @@ impl ContextStore { continue; } - let pattern = r" - \d+.zed.json$"; - let re = Regex::new(pattern).unwrap(); + static ASSISTANT_CONTEXT_REGEX: LazyLock = + LazyLock::new(|| Regex::new(r" - \d+.zed.json$").unwrap()); let metadata = fs.metadata(&path).await?; if let Some((file_name, metadata)) = path @@ -763,11 +764,15 @@ impl ContextStore { .zip(metadata) { // This is used to filter out contexts saved by the new assistant. - if !re.is_match(file_name) { + if !ASSISTANT_CONTEXT_REGEX.is_match(file_name) { continue; } - if let Some(title) = re.replace(file_name, "").lines().next() { + if let Some(title) = ASSISTANT_CONTEXT_REGEX + .replace(file_name, "") + .lines() + .next() + { contexts.push(SavedContextMetadata { title: title.to_string(), path, diff --git a/crates/feedback/src/feedback_modal.rs b/crates/feedback/src/feedback_modal.rs index 2c98267ccf..15b3bc5789 100644 --- a/crates/feedback/src/feedback_modal.rs +++ b/crates/feedback/src/feedback_modal.rs @@ -1,4 +1,8 @@ -use std::{ops::RangeInclusive, sync::Arc, time::Duration}; +use std::{ + ops::RangeInclusive, + sync::{Arc, LazyLock}, + time::Duration, +}; use anyhow::{anyhow, bail}; use bitflags::bitflags; @@ -34,7 +38,8 @@ const DEV_MODE: bool = true; const DEV_MODE: bool = false; const DATABASE_KEY_NAME: &str = "email_address"; -const EMAIL_REGEX: &str = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"; +static EMAIL_REGEX: LazyLock = + LazyLock::new(|| Regex::new(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b").unwrap()); const FEEDBACK_CHAR_LIMIT: RangeInclusive = 10..=5000; const FEEDBACK_SUBMISSION_ERROR_TEXT: &str = "Feedback failed to submit, see error log for details."; @@ -320,7 +325,7 @@ impl FeedbackModal { let mut invalid_state_flags = InvalidStateFlags::empty(); let valid_email_address = match self.email_address_editor.read(cx).text_option(cx) { - Some(email_address) => Regex::new(EMAIL_REGEX).unwrap().is_match(&email_address), + Some(email_address) => EMAIL_REGEX.is_match(&email_address), None => true, }; diff --git a/crates/git_hosting_providers/src/providers/github.rs b/crates/git_hosting_providers/src/providers/github.rs index cbd1cc73a8..6026c6ed20 100644 --- a/crates/git_hosting_providers/src/providers/github.rs +++ b/crates/git_hosting_providers/src/providers/github.rs @@ -1,5 +1,5 @@ use std::str::FromStr; -use std::sync::{Arc, OnceLock}; +use std::sync::{Arc, LazyLock}; use anyhow::{bail, Context, Result}; use async_trait::async_trait; @@ -15,9 +15,9 @@ use git::{ }; fn pull_request_number_regex() -> &'static Regex { - static PULL_REQUEST_NUMBER_REGEX: OnceLock = OnceLock::new(); - - PULL_REQUEST_NUMBER_REGEX.get_or_init(|| Regex::new(r"\(#(\d+)\)$").unwrap()) + static PULL_REQUEST_NUMBER_REGEX: LazyLock = + LazyLock::new(|| Regex::new(r"\(#(\d+)\)$").unwrap()); + &PULL_REQUEST_NUMBER_REGEX } #[derive(Debug, Deserialize)] diff --git a/crates/html_to_markdown/src/markdown_writer.rs b/crates/html_to_markdown/src/markdown_writer.rs index 579e576116..a9caf7afa7 100644 --- a/crates/html_to_markdown/src/markdown_writer.rs +++ b/crates/html_to_markdown/src/markdown_writer.rs @@ -1,7 +1,6 @@ -use std::cell::RefCell; use std::collections::VecDeque; use std::rc::Rc; -use std::sync::OnceLock; +use std::{cell::RefCell, sync::LazyLock}; use anyhow::Result; use markup5ever_rcdom::{Handle, NodeData}; @@ -10,13 +9,14 @@ use regex::Regex; use crate::html_element::HtmlElement; fn empty_line_regex() -> &'static Regex { - static REGEX: OnceLock = OnceLock::new(); - REGEX.get_or_init(|| Regex::new(r"^\s*$").unwrap()) + static REGEX: LazyLock = + LazyLock::new(|| Regex::new(r"^\s*$").expect("Failed to create empty_line_regex")); + ®EX } fn more_than_three_newlines_regex() -> &'static Regex { - static REGEX: OnceLock = OnceLock::new(); - REGEX.get_or_init(|| Regex::new(r"\n{3,}").unwrap()) + static REGEX: LazyLock = LazyLock::new(|| Regex::new(r"\n{3,}").unwrap()); + ®EX } pub enum StartTagOutcome { diff --git a/crates/project/src/search.rs b/crates/project/src/search.rs index 0708f25410..f70baeb6d8 100644 --- a/crates/project/src/search.rs +++ b/crates/project/src/search.rs @@ -10,13 +10,11 @@ use std::{ io::{BufRead, BufReader, Read}, ops::Range, path::Path, - sync::{Arc, LazyLock, OnceLock}, + sync::{Arc, LazyLock}, }; use text::Anchor; use util::paths::PathMatcher; -static TEXT_REPLACEMENT_SPECIAL_CHARACTERS_REGEX: OnceLock = OnceLock::new(); - pub enum SearchResult { Buffer { buffer: Model, @@ -265,16 +263,17 @@ impl SearchQuery { regex, replacement, .. } => { if let Some(replacement) = replacement { - let replacement = TEXT_REPLACEMENT_SPECIAL_CHARACTERS_REGEX - .get_or_init(|| Regex::new(r"\\\\|\\n|\\t").unwrap()) - .replace_all(replacement, |c: &Captures| { - match c.get(0).unwrap().as_str() { - r"\\" => "\\", - r"\n" => "\n", - r"\t" => "\t", - x => unreachable!("Unexpected escape sequence: {}", x), - } - }); + static TEXT_REPLACEMENT_SPECIAL_CHARACTERS_REGEX: LazyLock = + LazyLock::new(|| Regex::new(r"\\\\|\\n|\\t").unwrap()); + let replacement = TEXT_REPLACEMENT_SPECIAL_CHARACTERS_REGEX.replace_all( + replacement, + |c: &Captures| match c.get(0).unwrap().as_str() { + r"\\" => "\\", + r"\n" => "\n", + r"\t" => "\t", + x => unreachable!("Unexpected escape sequence: {}", x), + }, + ); Some(regex.replace(text, replacement)) } else { None diff --git a/crates/util/src/util.rs b/crates/util/src/util.rs index 777b8b60dc..3ba42e33cd 100644 --- a/crates/util/src/util.rs +++ b/crates/util/src/util.rs @@ -9,7 +9,7 @@ pub mod test; use futures::Future; use regex::Regex; -use std::sync::OnceLock; +use std::sync::{LazyLock, OnceLock}; use std::{ borrow::Cow, cmp::{self, Ordering}, @@ -567,8 +567,9 @@ impl<'a> PartialOrd for NumericPrefixWithSuffix<'a> { } fn emoji_regex() -> &'static Regex { - static EMOJI_REGEX: OnceLock = OnceLock::new(); - EMOJI_REGEX.get_or_init(|| Regex::new("(\\p{Emoji}|\u{200D})").unwrap()) + static EMOJI_REGEX: LazyLock = + LazyLock::new(|| Regex::new("(\\p{Emoji}|\u{200D})").unwrap()); + &EMOJI_REGEX } /// Returns true if the given string consists of emojis only.