-
Notifications
You must be signed in to change notification settings - Fork 626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add smartcase support like vim #2060
Conversation
Interesting patch, thanks! |
2093605
to
cfa36ce
Compare
If I understand the code correctly, this changes the default behaviour? It would be good (to avoid users annoyance) to keep the existing behaviour and add this as an extra option. |
Sorry for late reply. Then maybe I could add a new global option like |
cfa36ce
to
c1aaea3
Compare
Now I make it a non-breaking change. |
4b95f34
to
14adf04
Compare
Added some tests. |
177f677
to
497d4bf
Compare
commit 2ad9aa0789305034dea943ac1f8792e8ac540875
Author: Dave Davenport <[email protected]>
Date: Mon Jan 27 13:11:00 2025 +0100
Remove allocation and do manual walk to detect case
Update the sort indicator live in smart-case
Fix constness
Move insensitive param to right State (not textbox)
diff --git a/include/helper.h b/include/helper.h
index 4f690dbc..937bb30d 100644
--- a/include/helper.h
+++ b/include/helper.h
@@ -208,7 +208,7 @@ char *rofi_expand_path(const char *input);
*/
unsigned int levenshtein(const char *needle, const glong needlelen,
const char *haystack, const glong haystacklen,
- int case_sensitive);
+ const int case_sensitive);
/**
* @param data the unvalidated character array holding possible UTF-8 data
@@ -266,7 +266,7 @@ char *rofi_latin_to_utf8_strdup(const char *input, gssize length);
* @returns the sorting weight.
*/
int rofi_scorer_fuzzy_evaluate(const char *pattern, glong plen, const char *str,
- glong slen, int case_sensitive);
+ glong slen, const int case_sensitive);
/*@}*/
/**
@@ -361,7 +361,7 @@ void parse_ranges(char *input, rofi_range_pair **list, unsigned int *length);
*
* @returns String matching should be case sensitive or insensitive
*/
-int parse_case_sensitivity(char *input);
+int parse_case_sensitivity(const char *input);
/**
* @param format The format string used. See below for possible syntax.
diff --git a/include/view-internal.h b/include/view-internal.h
index da6bd09a..bd48a68a 100644
--- a/include/view-internal.h
+++ b/include/view-internal.h
@@ -144,6 +144,8 @@ struct RofiViewState {
/** Regexs used for matching */
rofi_int_matcher **tokens;
+ /** For case-sensitivity */
+ gboolean case_sensitive;
};
/** @} */
#endif
diff --git a/include/widgets/textbox.h b/include/widgets/textbox.h
index bf849c03..85331b20 100644
--- a/include/widgets/textbox.h
+++ b/include/widgets/textbox.h
@@ -69,7 +69,6 @@ typedef struct {
int tbft;
int markup;
int changed;
- int case_sensitive;
int blink;
guint blink_timeout;
diff --git a/source/helper.c b/source/helper.c
index 5c0003d8..3534c2f6 100644
--- a/source/helper.c
+++ b/source/helper.c
@@ -1248,12 +1248,23 @@ void parse_ranges(char *input, rofi_range_pair **list, unsigned int *length) {
}
}
-int parse_case_sensitivity(char *input) {
- gchar *lowercase = g_utf8_strdown(input, -1);
- int case_sensitive = config.case_smart
- ? (g_utf8_collate(input, lowercase) != 0)
- : config.case_sensitive;
- g_free(lowercase);
+int parse_case_sensitivity(const char *input) {
+ int case_sensitive = config.case_sensitive;
+ if ( config.case_smart ) {
+ // By default case is false, unless the search query has a
+ // uppercase in it?
+ case_sensitive = FALSE;
+ const char *end;
+ if ( g_utf8_validate(input, -1, &end) ){
+ for ( const char *c = (input);
+ !case_sensitive && c != NULL && *c; c = g_utf8_next_char(c)){
+ gunichar uc = g_utf8_get_char(c);
+ if ( g_unichar_isupper(uc)){
+ case_sensitive = TRUE;
+ }
+ }
+ }
+ }
return case_sensitive;
}
diff --git a/source/view.c b/source/view.c
index 816c24f5..c21d7d12 100644
--- a/source/view.c
+++ b/source/view.c
@@ -189,7 +189,7 @@ void rofi_view_get_current_monitor(int *width, int *height) {
}
}
static char *get_matching_state(RofiViewState *state) {
- if (state->text->case_sensitive) {
+ if (state->case_sensitive) {
if (config.sort) {
return "±";
}
@@ -776,12 +776,12 @@ static void filter_elements(thread_state *ts,
switch (config.sorting_method_enum) {
case SORT_FZF:
t->state->distance[i] = rofi_scorer_fuzzy_evaluate(
- t->pattern, t->plen, str, slen, t->state->text->case_sensitive);
+ t->pattern, t->plen, str, slen, t->state->case_sensitive);
break;
case SORT_NORMAL:
default:
t->state->distance[i] = levenshtein(t->pattern, t->plen, str, slen,
- t->state->text->case_sensitive);
+ t->state->case_sensitive);
break;
}
g_free(str);
@@ -1483,8 +1483,12 @@ static gboolean rofi_view_refilter_real(RofiViewState *state) {
unsigned int j = 0;
gchar *pattern = mode_preprocess_input(state->sw, state->text->text);
glong plen = pattern ? g_utf8_strlen(pattern, -1) : 0;
- state->text->case_sensitive = parse_case_sensitivity(state->text->text);
- state->tokens = helper_tokenize(pattern, state->text->case_sensitive);
+ state->case_sensitive = parse_case_sensitivity(state->text->text);
+ state->tokens = helper_tokenize(pattern, state->case_sensitive);
+
+ if ( config.case_smart && state->case_indicator ) {
+ textbox_text(state->case_indicator, get_matching_state(state));
+ }
/**
* On long lists it can be beneficial to parallelize.
* If number of threads is 1, no thread is spawn. this fixes some of the feedback I've given. |
497d4bf
to
91ee3e4
Compare
Thanks, amended. |
ready to be merged? |
I think it's ready. Have used this for a month. Work fine for me. (: |
"smartcase": case sensitive if all chars in current query are in lowercase, otherwise it's case insensitive
I notice that there are two flags now:
-case-sensitive
byrofi
globally-i
used inrofi -dmenu
moderofi
is case insensitive, but case sensitive inrofi -dmenu
mode.This PR implement:
rofi
androfi -dmenu
).opt-out
this behavior, users can still use-case-sensitive
and-i
.