parent
172d9dc589
commit
f10e9d1794
11 changed files with 65 additions and 52 deletions
|
@ -2,17 +2,15 @@ use std::{
|
|||
env,
|
||||
fmt::{Display, Formatter},
|
||||
str::FromStr,
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
sync::{Arc, LazyLock, Mutex, RwLock},
|
||||
thread::sleep,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use clap::Parser;
|
||||
use hyprland::data::Client;
|
||||
use hyprland::dispatch::WindowIdentifier;
|
||||
use hyprland::{
|
||||
data::{Workspace, Workspaces},
|
||||
dispatch::{Dispatch, DispatchType, WorkspaceIdentifierWithSpecial},
|
||||
data::{Client, Workspace, Workspaces},
|
||||
dispatch::{Dispatch, DispatchType, WindowIdentifier, WorkspaceIdentifierWithSpecial},
|
||||
prelude::HyprData,
|
||||
shared::HyprDataActive,
|
||||
};
|
||||
|
@ -478,12 +476,14 @@ fn main() -> Result<(), String> {
|
|||
cfg.worf.set_prompt(cfg.hypr_space_mode().to_string());
|
||||
}
|
||||
|
||||
let pattern = Mode::iter()
|
||||
.map(|m| regex::escape(&m.to_string().to_lowercase()))
|
||||
.collect::<Vec<_>>()
|
||||
.join("|");
|
||||
|
||||
let pattern = Regex::new(&format!("(?i){pattern}")).map_err(|e| e.to_string())?;
|
||||
static PATTERN_RE: LazyLock<Regex> = LazyLock::new(|| {
|
||||
let pattern = Mode::iter()
|
||||
.map(|m| regex::escape(&m.to_string().to_lowercase()))
|
||||
.collect::<Vec<_>>()
|
||||
.join("|");
|
||||
Regex::new(&format!("(?i){pattern}")).unwrap()
|
||||
});
|
||||
let pattern = PATTERN_RE.clone();
|
||||
|
||||
let provider = Arc::new(Mutex::new(HyprspaceProvider::new(
|
||||
&cfg,
|
||||
|
|
|
@ -6,9 +6,11 @@ use std::{
|
|||
os::unix::{fs::PermissionsExt, prelude::CommandExt},
|
||||
path::{Path, PathBuf},
|
||||
process::{Command, Stdio},
|
||||
sync::LazyLock,
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
// re-export freedesktop_file_parser for easier access
|
||||
pub use freedesktop_file_parser::{DesktopFile, EntryType};
|
||||
use notify_rust::Notification;
|
||||
use rayon::prelude::*;
|
||||
|
@ -26,8 +28,9 @@ use crate::{
|
|||
/// When it cannot parse the internal regex
|
||||
#[must_use]
|
||||
pub fn known_image_extension_regex_pattern() -> Regex {
|
||||
Regex::new(r"(?i).*\.(png|jpg|gif|svg|jpeg)$")
|
||||
.expect("Internal image regex is not valid anymore.")
|
||||
static RE: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"(?i).*\.(png|jpg|gif|svg|jpeg)$").unwrap());
|
||||
RE.clone()
|
||||
}
|
||||
|
||||
/// Helper function to retrieve a file with given regex.
|
||||
|
@ -59,6 +62,8 @@ fn find_files(folder: &Path, file_name: &Regex) -> Option<Vec<PathBuf>> {
|
|||
/// When it cannot parse the internal regex
|
||||
#[must_use]
|
||||
pub fn find_desktop_files() -> Vec<DesktopFile> {
|
||||
static DESKTOP_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?i).*\.desktop$").unwrap());
|
||||
|
||||
let mut paths = vec![
|
||||
PathBuf::from("/usr/share/applications"),
|
||||
PathBuf::from("/usr/local/share/applications"),
|
||||
|
@ -81,12 +86,10 @@ pub fn find_desktop_files() -> Vec<DesktopFile> {
|
|||
}
|
||||
}
|
||||
|
||||
let regex = &Regex::new("(?i).*\\.desktop$").expect("invalid internal regex");
|
||||
|
||||
let p: Vec<_> = paths
|
||||
.into_par_iter()
|
||||
.filter(|desktop_dir| desktop_dir.exists())
|
||||
.filter_map(|desktop_dir| find_files(&desktop_dir, regex))
|
||||
.filter_map(|desktop_dir| find_files(&desktop_dir, &DESKTOP_RE))
|
||||
.flat_map(|desktop_files| {
|
||||
desktop_files.into_par_iter().filter_map(|desktop_file| {
|
||||
fs::read_to_string(desktop_file)
|
||||
|
@ -160,7 +163,9 @@ pub fn fork_if_configured(config: &Config) {
|
|||
/// # Panics
|
||||
/// When internal regex unwrapping fails. Should not happen as the regex is static
|
||||
pub fn spawn_fork(cmd: &str, working_dir: Option<&String>) -> Result<(), Error> {
|
||||
let re = Regex::new(r#"'([^']*)'|"([^"]*)"|(\S+)"#).expect("invalid regex in spawn_fork");
|
||||
static RE: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r#"'([^']*)'|"([^"]*)"|(\S+)"#).unwrap());
|
||||
let re = &*RE;
|
||||
let parts: Vec<String> = re
|
||||
.captures_iter(cmd)
|
||||
.map(|cap| {
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use regex::Regex;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::sync::{Arc, LazyLock, Mutex, RwLock};
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
use crate::gui::ArcProvider;
|
||||
use crate::{
|
||||
Error,
|
||||
config::Config,
|
||||
desktop::spawn_fork,
|
||||
gui::{self, DefaultItemFactory, ExpandMode, ItemProvider, MenuItem, ProviderData},
|
||||
gui::{
|
||||
self, ArcProvider, DefaultItemFactory, ExpandMode, ItemProvider, MenuItem, ProviderData,
|
||||
},
|
||||
modes::{
|
||||
drun::{DRunProvider, update_drun_cache_and_run},
|
||||
file::FileItemProvider,
|
||||
|
@ -74,15 +76,15 @@ impl AutoItemProvider {
|
|||
|
||||
fn contains_math_functions_or_starts_with_number(input: &str) -> bool {
|
||||
// Regex for function names (word boundaries to match whole words)
|
||||
let math_functions = r"\b(sqrt|abs|exp|ln|sin|cos|tan|asin|acos|atan|atan2|sinh|cosh|tanh|asinh|acosh|atanh|floor|ceil|round|signum|min|max|pi|e|0x|0b|\||&|<<|>>|\^)\b";
|
||||
static MATH_REGEX: LazyLock<Regex> = LazyLock::new(|| {
|
||||
Regex::new(r"\b(sqrt|abs|exp|ln|sin|cos|tan|asin|acos|atan|atan2|sinh|cosh|tanh|asinh|acosh|atanh|floor|ceil|round|signum|min|max|pi|e|0x|0b|\||&|<<|>>|\^)\b").unwrap()
|
||||
});
|
||||
|
||||
// Regex for strings that start with a number (including decimals)
|
||||
let starts_with_number = r"^\s*[+-]?(\d+(\.\d*)?|\.\d+)";
|
||||
static NUMBER_REGEX: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"^\s*[+-]?(\d+(\.\d*)?|\.\d+)").unwrap());
|
||||
|
||||
let math_regex = Regex::new(math_functions).unwrap();
|
||||
let number_regex = Regex::new(starts_with_number).unwrap();
|
||||
|
||||
math_regex.is_match(input) || number_regex.is_match(input)
|
||||
MATH_REGEX.is_match(input) || NUMBER_REGEX.is_match(input)
|
||||
}
|
||||
|
||||
impl ItemProvider<AutoRunType> for AutoItemProvider {
|
||||
|
@ -99,7 +101,8 @@ impl ItemProvider<AutoRunType> for AutoItemProvider {
|
|||
} else if search.starts_with("ssh") {
|
||||
(AutoRunType::Ssh, self.ssh.get_elements(search_opt))
|
||||
} else if search.starts_with('?') {
|
||||
let re = Regex::new(r"^\?\s*").unwrap();
|
||||
static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^\?\s*").unwrap());
|
||||
let re = &*RE;
|
||||
let query = re.replace(search, "");
|
||||
(
|
||||
AutoRunType::WebSearch,
|
||||
|
@ -151,7 +154,7 @@ pub fn show(config: &Arc<RwLock<Config>>) -> Result<(), Error> {
|
|||
Some(
|
||||
vec!["ssh", "emoji", "^\\$\\w+", "^\\?\\s*"]
|
||||
.into_iter()
|
||||
.map(|s| Regex::new(s).unwrap())
|
||||
.map(|s| Regex::new(s).unwrap()) // Consider precompiling if s is constant
|
||||
.collect(),
|
||||
),
|
||||
ExpandMode::Verbatim,
|
||||
|
|
|
@ -9,7 +9,6 @@ use freedesktop_file_parser::EntryType;
|
|||
use rayon::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::gui::ArcProvider;
|
||||
use crate::{
|
||||
Error,
|
||||
config::{Config, SortOrder},
|
||||
|
@ -17,7 +16,7 @@ use crate::{
|
|||
find_desktop_files, get_locale_variants, lookup_name_with_locale, save_cache_file,
|
||||
spawn_fork,
|
||||
},
|
||||
gui::{self, ExpandMode, ItemProvider, MenuItem, ProviderData},
|
||||
gui::{self, ArcProvider, ExpandMode, ItemProvider, MenuItem, ProviderData},
|
||||
modes::load_cache,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use regex::Regex;
|
||||
use std::sync::Mutex;
|
||||
use std::{
|
||||
fs,
|
||||
os::unix::fs::FileTypeExt,
|
||||
path::{Path, PathBuf},
|
||||
sync::{Arc, RwLock},
|
||||
sync::{Arc, LazyLock, Mutex, RwLock},
|
||||
};
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
use crate::{
|
||||
Error,
|
||||
config::{Config, SortOrder, expand_path},
|
||||
|
@ -201,6 +201,8 @@ impl<T: Clone> ItemProvider<T> for FileItemProvider<T> {
|
|||
/// # Panics
|
||||
/// In case an internal regex does not parse anymore, this should never happen
|
||||
pub fn show(config: &Arc<RwLock<Config>>) -> Result<(), Error> {
|
||||
static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^\$\w+").unwrap());
|
||||
|
||||
let provider = Arc::new(Mutex::new(FileItemProvider::new(
|
||||
0,
|
||||
config.read().unwrap().sort_order(),
|
||||
|
@ -211,7 +213,7 @@ pub fn show(config: &Arc<RwLock<Config>>) -> Result<(), Error> {
|
|||
config,
|
||||
provider,
|
||||
None,
|
||||
Some(vec![Regex::new("^\\$\\w+").unwrap()]),
|
||||
Some(vec![RE.clone()]),
|
||||
ExpandMode::Verbatim,
|
||||
None,
|
||||
)?;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{
|
||||
collections::VecDeque,
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
sync::{Arc, LazyLock, Mutex, RwLock},
|
||||
};
|
||||
|
||||
use regex::Regex;
|
||||
|
@ -79,13 +79,12 @@ enum Value {
|
|||
|
||||
/// Normalize base literals like 0x and 0b into decimal format
|
||||
fn normalize_bases(expr: &str) -> String {
|
||||
let hex_re = Regex::new(r"0x[0-9a-fA-F]+").unwrap();
|
||||
let expr = hex_re.replace_all(expr, |caps: ®ex::Captures| {
|
||||
static HEX_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"0x[0-9a-fA-F]+").unwrap());
|
||||
static BIN_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"0b[01]+").unwrap());
|
||||
let expr = HEX_RE.replace_all(expr, |caps: ®ex::Captures| {
|
||||
i64::from_str_radix(&caps[0][2..], 16).unwrap().to_string()
|
||||
});
|
||||
|
||||
let bin_re = Regex::new(r"0b[01]+").unwrap();
|
||||
bin_re
|
||||
BIN_RE
|
||||
.replace_all(&expr, |caps: ®ex::Captures| {
|
||||
i64::from_str_radix(&caps[0][2..], 2).unwrap().to_string()
|
||||
})
|
||||
|
|
|
@ -7,12 +7,11 @@ use std::{
|
|||
sync::{Arc, Mutex, RwLock},
|
||||
};
|
||||
|
||||
use crate::gui::ArcProvider;
|
||||
use crate::{
|
||||
Error,
|
||||
config::{Config, SortOrder},
|
||||
desktop::{is_executable, save_cache_file},
|
||||
gui::{self, ExpandMode, ItemProvider, MenuItem, ProviderData},
|
||||
gui::{self, ArcProvider, ExpandMode, ItemProvider, MenuItem, ProviderData},
|
||||
modes::load_cache,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::sync::{Arc, Mutex, RwLock};
|
||||
|
||||
use urlencoding::encode;
|
||||
|
||||
use crate::{
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
use regex::Regex;
|
||||
use std::fs;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::{
|
||||
fs,
|
||||
sync::{Arc, LazyLock, Mutex, RwLock},
|
||||
};
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
use crate::gui::{ExpandMode, ProviderData};
|
||||
use crate::{
|
||||
Error,
|
||||
config::{Config, SortOrder},
|
||||
desktop::spawn_fork,
|
||||
gui::{self, ItemProvider, MenuItem},
|
||||
gui::{self, ExpandMode, ItemProvider, MenuItem, ProviderData},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -17,7 +19,8 @@ pub(crate) struct SshProvider<T: Clone> {
|
|||
|
||||
impl<T: Clone> SshProvider<T> {
|
||||
pub(crate) fn new(menu_item_data: T, order: &SortOrder) -> Self {
|
||||
let re = Regex::new(r"(?m)^\s*Host\s+(.+)$").unwrap();
|
||||
static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?m)^\s*Host\s+(.+)$").unwrap());
|
||||
let re = &*RE;
|
||||
let mut items: Vec<_> = dirs::home_dir()
|
||||
.map(|home| home.join(".ssh").join("config"))
|
||||
.filter(|path| path.exists())
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use clap::Parser;
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
use std::{
|
||||
env,
|
||||
fmt::Display,
|
||||
str::FromStr,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
use clap::Parser;
|
||||
use worf::{Error, config, desktop::fork_if_configured, modes};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::fmt;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
/// Configuration and command line parsing
|
||||
|
|
Loading…
Add table
Reference in a new issue