fix: make case option work with non-ascii input (closes #454)

This commit is contained in:
Loric ANDRE 2026-01-22 00:12:18 +01:00
parent 79672e348f
commit 662e92f835
9 changed files with 112 additions and 7 deletions

View file

@ -12,7 +12,7 @@ pub fn regex_match(choice: &str, pattern: &Option<Regex>) -> Option<(usize, usiz
pub fn contains_upper(string: &str) -> bool {
for ch in string.chars() {
if ch.is_ascii_uppercase() {
if ch.is_uppercase() {
return true;
}
}

View file

@ -82,7 +82,7 @@ impl ClangdMatcher {
fn contains_upper(&self, string: &str) -> bool {
for ch in string.chars() {
if ch.is_ascii_uppercase() {
if ch.is_uppercase() {
return true;
}
}

View file

@ -135,7 +135,7 @@ fn build_graph(choice: &str, pattern: &str) -> Option<Vec<Vec<MatchingStatus>>>
let mut vec = vec![];
let mut choice_prev_ch = '\0';
for (idx, ch) in choice.chars().enumerate() {
if ch.eq_ignore_ascii_case(&pat_ch) && idx >= match_start_idx {
if char_equal(ch, pat_ch, false) && idx >= match_start_idx {
let score = fuzzy_score(
ch,
idx as IndexType,
@ -813,7 +813,7 @@ impl SkimMatcherV2 {
}
fn contains_upper(&self, string: &str) -> bool {
string.chars().any(|ch| ch.is_ascii_uppercase())
string.chars().any(|ch| ch.is_uppercase())
}
/// Performs fuzzy matching with full algorithm and returns score and indices

View file

@ -30,7 +30,17 @@ pub fn char_equal(a: char, b: char, case_sensitive: bool) -> bool {
if case_sensitive {
a == b
} else {
a.eq_ignore_ascii_case(&b)
let a_lower = a.to_lowercase();
let mut b_lower = b.to_lowercase();
for a_n in a_lower {
let Some(b_n) = b_lower.next() else {
return false;
};
if a_n != b_n {
return false;
}
}
return true;
}
}

View file

@ -224,12 +224,12 @@ impl Input {
let mut pos = self.cursor_pos as usize;
// Skip any trailing whitespace
while pos > 0 && self.value.chars().nth(pos - 1).unwrap().is_whitespace() {
while pos > 0 && self.value.chars().nth(pos - 1).unwrap_or_default().is_whitespace() {
pos -= 1;
}
// Delete back to next whitespace or start
while pos > 0 && !self.value.chars().nth(pos - 1).unwrap().is_whitespace() {
while pos > 0 && !self.value.chars().nth(pos - 1).unwrap_or_default().is_whitespace() {
pos -= 1;
}

View file

@ -71,3 +71,14 @@ insta_test!(insta_case_respect_no_match, ["aBcDeF"], &["--case", "respect"], {
@type "Abc";
@snap;
});
// Non-ascii input
insta_test!(insta_case_non_ascii, ["слово", "Слово", "СЛОВО"], &["--case", "smart"], {
@snap;
@type "слово";
@snap;
@ctrl 'w';
@type "Слово";
@snap;
});

View file

@ -0,0 +1,28 @@
---
source: tests/case.rs
expression: h.buffer_view()
---
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" СЛОВО "
" Слово "
"> слово "
" 3/3 0/0"
"> слово "

View file

@ -0,0 +1,28 @@
---
source: tests/case.rs
expression: h.buffer_view()
---
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
"> Слово "
" 1/3 0/0"
"> Слово "

View file

@ -0,0 +1,28 @@
---
source: tests/case.rs
expression: h.buffer_view()
---
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" СЛОВО "
" Слово "
"> слово "
" 3/3 0/0"
"> "