mirror of
https://github.com/wez/wezterm.git
synced 2025-01-08 07:01:35 +03:00
charselect: switch to nucleo fuzzy matcher
This has more intuitive sorting; eg: `line` used to show the first match as `linux_endeavour` but now matches `LINEAR B IDEOGRAM VESSEL B212` first, which feels more relevant (has an exact prefix match). refs: https://github.com/wez/wezterm/issues/5532
This commit is contained in:
parent
30ecc426ca
commit
6b5edad360
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -3374,6 +3374,16 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nucleo-matcher"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf33f538733d1a5a3494b836ba913207f14d9d4a1d3cd67030c5061bdd2cac85"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.3"
|
||||
@ -6323,6 +6333,7 @@ dependencies = [
|
||||
"mlua",
|
||||
"mux",
|
||||
"mux-lua",
|
||||
"nucleo-matcher",
|
||||
"once_cell",
|
||||
"ordered-float",
|
||||
"parking_lot 0.12.3",
|
||||
|
@ -34,6 +34,8 @@ As features stabilize some brief notes about them will accumulate here.
|
||||
drawing glyphs. See
|
||||
[custom_block_glyphs](config/lua/config/custom_block_glyphs.md) for more
|
||||
details. Thanks to @stribor14! #5051 #5169
|
||||
* Switched to the [nucleo](https://github.com/helix-editor/nucleo) fuzzy
|
||||
matcher for `CharSelect`. #5532
|
||||
|
||||
#### New
|
||||
* [wezterm.serde](config/lua/wezterm.serde/index.md) module for serialization
|
||||
|
@ -54,6 +54,7 @@ finl_unicode = "1.2"
|
||||
frecency = { path = "../frecency" }
|
||||
futures = "0.3"
|
||||
fuzzy-matcher = "0.3"
|
||||
nucleo-matcher = "0.3"
|
||||
hdrhistogram = "7.1"
|
||||
http_req = "0.11"
|
||||
image = "0.25"
|
||||
|
@ -13,8 +13,7 @@ use config::keyassignment::{
|
||||
use config::Dimension;
|
||||
use emojis::{Emoji, Group};
|
||||
use frecency::Frecency;
|
||||
use fuzzy_matcher::skim::SkimMatcherV2;
|
||||
use fuzzy_matcher::FuzzyMatcher;
|
||||
use nucleo_matcher::{Matcher, Utf32Str};
|
||||
use rayon::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::borrow::Cow;
|
||||
@ -244,18 +243,18 @@ fn build_aliases() -> Vec<Alias> {
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct MatchResult {
|
||||
row_idx: usize,
|
||||
score: i64,
|
||||
score: u32,
|
||||
}
|
||||
|
||||
impl MatchResult {
|
||||
fn new(row_idx: usize, score: i64, selection: &str, aliases: &[Alias]) -> Self {
|
||||
fn new(row_idx: usize, score: u32, selection: &str, aliases: &[Alias]) -> Self {
|
||||
Self {
|
||||
row_idx,
|
||||
score: if aliases[row_idx].name == selection {
|
||||
// Pump up the score for an exact match, otherwise
|
||||
// the order may be undesirable if there are a lot
|
||||
// of candidates with the same score
|
||||
i64::max_value()
|
||||
u32::max_value()
|
||||
} else {
|
||||
score
|
||||
},
|
||||
@ -272,7 +271,11 @@ fn compute_matches(selection: &str, aliases: &[Alias], group: CharSelectGroup) -
|
||||
.map(|(idx, _a)| idx)
|
||||
.collect()
|
||||
} else {
|
||||
let matcher = SkimMatcherV2::default();
|
||||
let pattern = nucleo_matcher::pattern::Pattern::parse(
|
||||
selection,
|
||||
nucleo_matcher::pattern::CaseMatching::Ignore,
|
||||
nucleo_matcher::pattern::Normalization::Smart,
|
||||
);
|
||||
|
||||
let numeric_selection = if selection.chars().all(|c| c.is_ascii_hexdigit()) {
|
||||
// Make this uppercase so that eg: `e1` matches `U+E1` rather
|
||||
@ -285,14 +288,24 @@ fn compute_matches(selection: &str, aliases: &[Alias], group: CharSelectGroup) -
|
||||
None
|
||||
};
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
let all_matches: Vec<(String, MatchResult)> = aliases
|
||||
.par_iter()
|
||||
.enumerate()
|
||||
.filter_map(|(row_idx, entry)| {
|
||||
thread_local! {
|
||||
static MATCHER: RefCell<Matcher> = RefCell::new(Matcher::new(nucleo_matcher::Config::DEFAULT));
|
||||
}
|
||||
|
||||
let glyph = entry.glyph();
|
||||
let alias_result = matcher
|
||||
.fuzzy_match(&entry.name, selection)
|
||||
.map(|score| MatchResult::new(row_idx, score, selection, aliases));
|
||||
|
||||
let alias_result = MATCHER.with_borrow_mut(|matcher| {
|
||||
let mut buf = vec![];
|
||||
pattern
|
||||
.score(Utf32Str::new(&entry.name, &mut buf), matcher)
|
||||
.map(|score| MatchResult::new(row_idx, score , selection, aliases))
|
||||
});
|
||||
|
||||
match &numeric_selection {
|
||||
Some(sel) => {
|
||||
let codepoints = entry.codepoints();
|
||||
@ -301,13 +314,15 @@ fn compute_matches(selection: &str, aliases: &[Alias], group: CharSelectGroup) -
|
||||
glyph,
|
||||
MatchResult {
|
||||
row_idx,
|
||||
score: i64::max_value(),
|
||||
score: u32::max_value(),
|
||||
},
|
||||
))
|
||||
} else {
|
||||
let number_result = matcher
|
||||
.fuzzy_match(&codepoints, &sel)
|
||||
.map(|score| MatchResult::new(row_idx, score, sel, aliases));
|
||||
let number_result = MATCHER.with_borrow_mut(|matcher| {
|
||||
let mut buf = vec![];
|
||||
pattern
|
||||
.score(Utf32Str::new(&codepoints, &mut buf), matcher)
|
||||
.map(|score| MatchResult::new(row_idx, score , selection, aliases))});
|
||||
|
||||
match (alias_result, number_result) {
|
||||
(
|
||||
|
Loading…
Reference in New Issue
Block a user