mirror of
https://github.com/jarun/nnn.git
synced 2024-11-28 05:41:31 +00:00
Toggle filter case-sensitivity
This commit is contained in:
parent
8588b3f0bd
commit
70dcbf43d7
6
nnn.1
6
nnn.1
|
@ -138,13 +138,15 @@ When a session is loaded dynamically, the last working session is saved automati
|
||||||
All the session files are located in the \fB${XDG_CONFIG_HOME:-$HOME/.config}/nnn/sessions\fR directory by the session name.
|
All the session files are located in the \fB${XDG_CONFIG_HOME:-$HOME/.config}/nnn/sessions\fR directory by the session name.
|
||||||
"@" is the "last session" file.
|
"@" is the "last session" file.
|
||||||
.Sh FILTERS
|
.Sh FILTERS
|
||||||
Filters are substrings to find matching entries in the current directory instantly (\fIsearch-as-you-type\fR). There is a program option to switch to regex filters.
|
Filters are strings to find matching entries in the current directory instantly (\fIsearch-as-you-type\fR). There is a program option to switch to regex filters. Matches are case-insensitive by default.
|
||||||
.Pp
|
.Pp
|
||||||
To switch the filter type at runtime:
|
To modify match criteria at runtime:
|
||||||
.br
|
.br
|
||||||
- string to regex: press '\\' at empty filter prompt
|
- string to regex: press '\\' at empty filter prompt
|
||||||
.br
|
.br
|
||||||
- regex to string: press '/' at empty filter prompt
|
- regex to string: press '/' at empty filter prompt
|
||||||
|
.br
|
||||||
|
- toggle case sensitivity: press '|' at empty filter prompt
|
||||||
.Pp
|
.Pp
|
||||||
Common regex use cases:
|
Common regex use cases:
|
||||||
.Pp
|
.Pp
|
||||||
|
|
79
src/nnn.c
79
src/nnn.c
|
@ -693,6 +693,18 @@ static void printprompt(const char *str)
|
||||||
addstr(str);
|
addstr(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clearinfoln(void)
|
||||||
|
{
|
||||||
|
move(xlines - 2, 0);
|
||||||
|
addstr("");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printinfoln(const char *str)
|
||||||
|
{
|
||||||
|
clearinfoln();
|
||||||
|
mvaddstr(xlines - 2, xcols - strlen(str), str);
|
||||||
|
}
|
||||||
|
|
||||||
static int get_input(const char *prompt)
|
static int get_input(const char *prompt)
|
||||||
{
|
{
|
||||||
int r = KEY_RESIZE;
|
int r = KEY_RESIZE;
|
||||||
|
@ -1817,9 +1829,12 @@ static char xchartohex(char c)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char * (*fnstrstr)(const char *haystack, const char *needle) = &strcasestr;
|
||||||
|
static int regflags = REG_NOSUB | REG_EXTENDED | REG_ICASE;
|
||||||
|
|
||||||
static int setfilter(regex_t *regex, const char *filter)
|
static int setfilter(regex_t *regex, const char *filter)
|
||||||
{
|
{
|
||||||
return regcomp(regex, filter, REG_NOSUB | REG_EXTENDED | REG_ICASE);
|
return regcomp(regex, filter, regflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int visible_re(const fltrexp_t *fltrexp, const char *fname)
|
static int visible_re(const fltrexp_t *fltrexp, const char *fname)
|
||||||
|
@ -1829,7 +1844,7 @@ static int visible_re(const fltrexp_t *fltrexp, const char *fname)
|
||||||
|
|
||||||
static int visible_str(const fltrexp_t *fltrexp, const char *fname)
|
static int visible_str(const fltrexp_t *fltrexp, const char *fname)
|
||||||
{
|
{
|
||||||
return strcasestr(fname, fltrexp->str) != NULL;
|
return fnstrstr(fname, fltrexp->str) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int (*filterfn)(const fltrexp_t *fltr, const char *fname) = &visible_str;
|
static int (*filterfn)(const fltrexp_t *fltr, const char *fname) = &visible_str;
|
||||||
|
@ -1992,6 +2007,22 @@ static int nextsel(int presel)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void showfilterinfo(void)
|
||||||
|
{
|
||||||
|
char info[REGEX_MAX];
|
||||||
|
|
||||||
|
snprintf(info, REGEX_MAX - 1, " %s [/\\], %s [|]",
|
||||||
|
(cfg.regex ? "regex" : "str"),
|
||||||
|
((fnstrstr == &strcasestr) ? "ic" : "noic"));
|
||||||
|
printinfoln(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void showfilter(char *str)
|
||||||
|
{
|
||||||
|
showfilterinfo();
|
||||||
|
printprompt(str);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void swap_ent(int id1, int id2)
|
static inline void swap_ent(int id1, int id2)
|
||||||
{
|
{
|
||||||
struct entry _dent, *pdent1 = &dents[id1], *pdent2 = &dents[id2];
|
struct entry _dent, *pdent1 = &dents[id1], *pdent2 = &dents[id2];
|
||||||
|
@ -2063,7 +2094,7 @@ static int filterentries(char *path, char *lastname)
|
||||||
|
|
||||||
cleartimeout();
|
cleartimeout();
|
||||||
curs_set(TRUE);
|
curs_set(TRUE);
|
||||||
printprompt(ln);
|
showfilter(ln);
|
||||||
|
|
||||||
while ((r = get_wch(ch)) != ERR) {
|
while ((r = get_wch(ch)) != ERR) {
|
||||||
//DPRINTF_D(*ch);
|
//DPRINTF_D(*ch);
|
||||||
|
@ -2074,7 +2105,7 @@ static int filterentries(char *path, char *lastname)
|
||||||
case KEY_RESIZE:
|
case KEY_RESIZE:
|
||||||
clearoldprompt();
|
clearoldprompt();
|
||||||
redraw(path);
|
redraw(path);
|
||||||
printprompt(ln);
|
showfilter(ln);
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
case KEY_DC: // fallthrough
|
case KEY_DC: // fallthrough
|
||||||
|
@ -2101,12 +2132,12 @@ static int filterentries(char *path, char *lastname)
|
||||||
if (matches(pln) != -1)
|
if (matches(pln) != -1)
|
||||||
redraw(path);
|
redraw(path);
|
||||||
|
|
||||||
printprompt(ln);
|
showfilter(ln);
|
||||||
continue;
|
continue;
|
||||||
case KEY_MOUSE: // fallthrough
|
case KEY_MOUSE: // fallthrough
|
||||||
case 27: /* Exit filter mode on Escape */
|
case 27: /* Exit filter mode on Escape */
|
||||||
goto end;
|
goto end;
|
||||||
case KEY_UP: /* On the first Up, show previous filter */
|
case KEY_UP: /* On the first Up, apply previous filter */
|
||||||
if (len == 1 && ln[REGEX_MAX - 1]) {
|
if (len == 1 && ln[REGEX_MAX - 1]) {
|
||||||
ln[1] = ln[REGEX_MAX - 1];
|
ln[1] = ln[REGEX_MAX - 1];
|
||||||
ln[REGEX_MAX - 1] = '\0';
|
ln[REGEX_MAX - 1] = '\0';
|
||||||
|
@ -2115,7 +2146,7 @@ static int filterentries(char *path, char *lastname)
|
||||||
if (matches(pln) != -1)
|
if (matches(pln) != -1)
|
||||||
redraw(path);
|
redraw(path);
|
||||||
|
|
||||||
printprompt(ln);
|
showfilter(ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2135,23 +2166,29 @@ static int filterentries(char *path, char *lastname)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF_S(ln);
|
/* Toggle case-sensitivity */
|
||||||
|
if (*ch == '|') {
|
||||||
if (*ch == RFILTER && ln[0] == FILTER) {
|
fnstrstr = (fnstrstr == &strcasestr) ? &strstr : &strcasestr;
|
||||||
DPRINTF_S("set back");
|
regflags ^= REG_ICASE;
|
||||||
wln[0] = ln[0] = RFILTER;
|
showfilter(ln);
|
||||||
cfg.regex = TRUE;
|
|
||||||
filterfn = &visible_re;
|
|
||||||
printprompt(ln);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* string to regex */
|
||||||
|
if (*ch == RFILTER && ln[0] == FILTER) {
|
||||||
|
wln[0] = ln[0] = RFILTER;
|
||||||
|
cfg.regex = TRUE;
|
||||||
|
filterfn = &visible_re;
|
||||||
|
showfilter(ln);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* regex to string */
|
||||||
if (*ch == FILTER && ln[0] == RFILTER) {
|
if (*ch == FILTER && ln[0] == RFILTER) {
|
||||||
DPRINTF_S("set forward");
|
|
||||||
wln[0] = ln[0] = FILTER;
|
wln[0] = ln[0] = FILTER;
|
||||||
cfg.regex = FALSE;
|
cfg.regex = FALSE;
|
||||||
filterfn = &visible_str;
|
filterfn = &visible_str;
|
||||||
printprompt(ln);
|
showfilter(ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2173,7 +2210,7 @@ static int filterentries(char *path, char *lastname)
|
||||||
/* ndents = total; */
|
/* ndents = total; */
|
||||||
|
|
||||||
if (matches(pln) == -1) {
|
if (matches(pln) == -1) {
|
||||||
printprompt(ln);
|
showfilter(ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2193,11 +2230,13 @@ static int filterentries(char *path, char *lastname)
|
||||||
* cases where the dir has permissions. This skips a redraw().
|
* cases where the dir has permissions. This skips a redraw().
|
||||||
*/
|
*/
|
||||||
redraw(path);
|
redraw(path);
|
||||||
printprompt(ln);
|
showfilter(ln);
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
|
clearinfoln();
|
||||||
|
|
||||||
/* Save last working filter in-filter */
|
/* Save last working filter in-filter */
|
||||||
if (ln[1])
|
if (ln[1])
|
||||||
ln[REGEX_MAX - 1] = ln[1];
|
ln[REGEX_MAX - 1] = ln[1];
|
||||||
|
@ -5608,7 +5647,7 @@ static void usage(void)
|
||||||
" -H show hidden files\n"
|
" -H show hidden files\n"
|
||||||
" -K detect key collision\n"
|
" -K detect key collision\n"
|
||||||
" -n nav-as-you-type mode\n"
|
" -n nav-as-you-type mode\n"
|
||||||
" -o open files on Enter\n"
|
" -o open files only on Enter\n"
|
||||||
" -p file selection file [stdout if '-']\n"
|
" -p file selection file [stdout if '-']\n"
|
||||||
" -Q no quit confirmation\n"
|
" -Q no quit confirmation\n"
|
||||||
" -r use advcpmv patched cp, mv\n"
|
" -r use advcpmv patched cp, mv\n"
|
||||||
|
|
Loading…
Reference in a new issue