nnn

mirror of https://github.com/jarun/nnn
Log | Files | Refs | README | LICENSE

commit 1b9d4438f2a013f35ef21afddf1e1950145a2939
parent 8a013d965d41a1a0c68ca11e173a88b6ffa58afe
Author: Arun Prakash Jana <engineerarun@gmail.com>
Date:   Sun, 22 Feb 2026 18:08:19 +0530

Dim characters matching filters

Enabled by default. To disable:

    make O_DIMFILTERED=0

Diffstat:
MMakefile | 6+++---
Mpatches/namefirst/mainline.diff | 92++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/nnn.c | 29++++++++++++-----------------
3 files changed, 61 insertions(+), 66 deletions(-)

diff --git a/Makefile b/Makefile @@ -28,7 +28,7 @@ O_NOUG := 0 # disable user, group name in status bar O_NOX11 := 0 # disable X11 integration O_MATCHFLTR := 0 # allow filters without matches O_NOSORT := 0 # disable sorting entries on dir load -O_NOHIGHLIGHT := 0 # disable filter match highlights (default: enabled) +O_DIMFILTERED := 1 # dim characters matching filter (default: enabled) # User patches O_COLEMAK := 0 # change key bindings to colemak compatible layout @@ -147,8 +147,8 @@ ifeq ($(strip $(O_NOSORT)),1) CPPFLAGS += -DNOSORT endif -ifeq ($(strip $(O_NOHIGHLIGHT)),1) - CPPFLAGS += -DNOHIGHLIGHT_FILTER +ifeq ($(strip $(O_DIMFILTERED)),1) + CPPFLAGS += -DDIM_FILTERED endif ifeq ($(shell $(PKG_CONFIG) ncursesw && echo 1),1) diff --git a/patches/namefirst/mainline.diff b/patches/namefirst/mainline.diff @@ -10,41 +10,41 @@ index 19ebc2cf..42a0a6b0 100644 @@ -430,6 +430,10 @@ typedef struct { } session_header_t; #endif - + +static struct { + ushort_t maxnameln, maxsizeln, maxuidln, maxgidln, maxentln, uidln, gidln, printguid; +} dtls; + /* GLOBALS */ - + /* Configuration, contexts */ @@ -1175,10 +1179,13 @@ static char *getpwname(uid_t uid) static char *namecache; - + if (uidcache != uid) { + if (dtls.maxuidln && !dtls.printguid) + dtls.printguid = 1; struct passwd *pw = getpwuid(uid); - + uidcache = uid; namecache = pw ? pw->pw_name : NULL; + dtls.uidln = xstrlen(namecache ? namecache : xitoa(uid)); } - + return namecache ? namecache : xitoa(uid); @@ -1190,10 +1197,13 @@ static char *getgrname(gid_t gid) static char *grpcache; - + if (gidcache != gid) { + if (dtls.maxgidln && !dtls.printguid) + dtls.printguid = 1; struct group *gr = getgrgid(gid); - + gidcache = gid; grpcache = gr ? gr->gr_name : NULL; + dtls.gidln = xstrlen(grpcache ? grpcache : xitoa(gid)); } - + return grpcache ? grpcache : xitoa(gid); @@ -4346,14 +4356,13 @@ static void resetdircolor(int flags) * Max supported str length: NAME_MAX; @@ -67,27 +67,27 @@ index 19ebc2cf..42a0a6b0 100644 @@ -4378,7 +4387,7 @@ static wchar_t *unescape(const char *str, uint_t maxcols) ++buf; } - + - return wbuf; + return len; } - + static off_t get_size(off_t size, off_t *pval, int comp) @@ -4627,9 +4636,10 @@ static uchar_t get_color_pair_name_ind(const struct entry *ent, char *pind, int } - - #ifndef NOHIGHLIGHT_FILTER --static void printent_name(const struct entry *ent, uint_t namecols, bool sel) -+static size_t printent_name(const struct entry *ent, uint_t namecols, bool sel) + + #ifdef DIM_FILTERED +-static void printent_name(const struct entry *ent, uint_t namecols) ++static size_t printent_name(const struct entry *ent, uint_t namecols) { char * const fltr = g_ctx[cfg.curctx].c_fltr; + size_t namelen; - - /* If there's a filter string, highlight matches */ + + /* If there's a filter string, dim matching characters */ if (fltr[1]) { -@@ -4644,15 +4654,18 @@ static void printent_name(const struct entry *ent, uint_t namecols, bool sel) +@@ -4644,15 +4654,18 @@ static void printent_name(const struct entry *ent, uint_t namecols) if (cfg.regex) { - /* For regex, we don't highlight - just print normally */ + /* For regex, we don't dim - just print normally */ #ifndef NOLC - addwstr(unescape(ent->name, namecols)); + namelen = unescape(ent->name, namecols); @@ -107,18 +107,18 @@ index 19ebc2cf..42a0a6b0 100644 uint_t col = 0; for (wchar_t *p = wbuf; *p && col < namecols; ++p, ++col) { if (matched[col]) { -@@ -4665,7 +4678,8 @@ static void printent_name(const struct entry *ent, uint_t namecols, bool sel) +@@ -4665,7 +4678,8 @@ static void printent_name(const struct entry *ent, uint_t namecols) } #else - /* Non-wide character version for fuzzy highlighting */ + /* Non-wide character version for fuzzy dimming */ - const char *name = unescape(ent->name, MIN(namecols, ent->nlen) + 1); + namelen = unescape(ent->name, MIN(namecols, ent->nlen) + 1); + const char *name = (char *)g_buf; for (uint_t i = 0; (i < namecols) && name[i]; ++i) { if (matched[i]) { attron(match_attrs); -@@ -4680,7 +4694,8 @@ static void printent_name(const struct entry *ent, uint_t namecols, bool sel) - /* String match - highlight the substring */ +@@ -4680,7 +4694,8 @@ static void printent_name(const struct entry *ent, uint_t namecols) + /* String match - dim the substring */ string_match_positions(fltr + 1, ent->name, matched); #ifndef NOLC - wchar_t * const wbuf = unescape(ent->name, namecols); @@ -127,17 +127,17 @@ index 19ebc2cf..42a0a6b0 100644 uint_t col = 0; for (wchar_t *p = wbuf; *p && col < namecols; ++p, ++col) { if (matched[col]) { -@@ -4693,7 +4708,8 @@ static void printent_name(const struct entry *ent, uint_t namecols, bool sel) +@@ -4693,7 +4708,8 @@ static void printent_name(const struct entry *ent, uint_t namecols) } #else - /* Non-wide character version for string highlighting */ + /* Non-wide character version for string dimming */ - const char *name = unescape(ent->name, MIN(namecols, ent->nlen) + 1); + namelen = unescape(ent->name, MIN(namecols, ent->nlen) + 1); + const char *name = (char *)g_buf; for (uint_t i = 0; (i < namecols) && name[i]; ++i) { if (matched[i]) { attron(match_attrs); -@@ -4708,22 +4724,30 @@ static void printent_name(const struct entry *ent, uint_t namecols, bool sel) +@@ -4708,22 +4724,30 @@ static void printent_name(const struct entry *ent, uint_t namecols) } else { /* No filter or filter not active - print normally */ #ifndef NOLC @@ -154,9 +154,9 @@ index 19ebc2cf..42a0a6b0 100644 + return namelen; } #else - /* Without highlight support, just print the name normally */ --static inline void printent_name(const struct entry *ent, uint_t namecols, bool sel) -+static inline size_t printent_name(const struct entry *ent, uint_t namecols, bool sel) + /* Without dimming support, just print the name normally */ +-static inline void printent_name(const struct entry *ent, uint_t namecols) ++static inline size_t printent_name(const struct entry *ent, uint_t namecols) { (void)sel; /* Suppress unused parameter warning */ #ifndef NOLC @@ -172,8 +172,8 @@ index 19ebc2cf..42a0a6b0 100644 + return namelen; } #endif - -@@ -4731,38 +4755,14 @@ static void printent(int pdents_index, uint_t namecols, bool sel) + +@@ -4731,38 +4755,14 @@ static void printent(int pdents_index, uint_t namecols) { const struct entry *ent = &pdents[pdents_index]; char ind = '\0'; @@ -203,24 +203,24 @@ index 19ebc2cf..42a0a6b0 100644 - } + int attrs = 0; + size_t namelen; - + if (g_state.showlines) { ptrdiff_t rel_num = pdents_index - cur; printw(rel_num == 0 ? "%4td" : "%+4td", rel_num); } - + - attrs = 0; - uchar_t color_pair = get_color_pair_name_ind(ent, &ind, &attrs); - + addch((ent->flags & FILE_SELECTED) ? '+' | A_REVERSE | A_BOLD : ' '); -@@ -4786,12 +4786,44 @@ static void printent(int pdents_index, uint_t namecols, bool sel) +@@ -4786,12 +4786,44 @@ static void printent(int pdents_index, uint_t namecols) if (!ind) ++namecols; - -- printent_name(ent, namecols, sel); -+ namelen = printent_name(ent, namecols, sel); - + +- printent_name(ent, namecols); ++ namelen = printent_name(ent, namecols); + - if (attrs) + if (!sel && attrs) attroff(attrs); @@ -259,12 +259,12 @@ index 19ebc2cf..42a0a6b0 100644 + if (attrs) + attroff(attrs); } - + /** @@ -7670,26 +7702,19 @@ static void statusbar(char *path) tocursor(); } - + -static inline void markhovered(void) -{ - if (cfg.showdetail && ndents) { /* Bold forward arrowhead */ @@ -289,7 +289,7 @@ index 19ebc2cf..42a0a6b0 100644 - n -= 32; + n -= (dtls.maxentln - 2 - dtls.maxnameln); } - + /* 2 columns for preceding space and indicator */ @@ -7728,8 +7753,6 @@ static void draw_line(int ncols) /* Must reset e.g. no files in dir */ @@ -298,12 +298,12 @@ index 19ebc2cf..42a0a6b0 100644 - - markhovered(); } - + static void redraw(char *path) @@ -7837,6 +7860,26 @@ static void redraw(char *path) int onscreen = MIN(ONSCREEN + curscroll, ndents); int len = scanselforpath(path, FALSE); - + + if (cfg.showdetail) { + ushort_t lenbuf = dtls.maxnameln = dtls.maxsizeln = dtls.maxuidln = dtls.maxgidln = dtls.printguid = 0; + for (i = curscroll; i < onscreen; ++i) { @@ -325,14 +325,14 @@ index 19ebc2cf..42a0a6b0 100644 + } + ncols = adjust_cols(ncols); - + /* Print listing */ @@ -7865,7 +7908,7 @@ static void redraw(char *path) #endif } - + - markhovered(); + statusbar(path); } - + static bool cdprep(char *lastdir, char *lastname, char *path, char *newpath) diff --git a/src/nnn.c b/src/nnn.c @@ -3159,7 +3159,7 @@ static int visible_str(const fltrexp_t *fltrexp, const char *fname) return fnstrstr(fname, fltrexp->str) != NULL; } -#ifndef NOHIGHLIGHT_FILTER +#ifdef DIM_FILTERED /* * Get match positions for fuzzy matching * Populates matched array with 1 for matched bytes, 0 otherwise @@ -4626,23 +4626,19 @@ static uchar_t get_color_pair_name_ind(const struct entry *ent, char *pind, int return C_UND; } -#ifndef NOHIGHLIGHT_FILTER -static void printent_name(const struct entry *ent, uint_t namecols, bool sel) +#ifdef DIM_FILTERED +static void printent_name(const struct entry *ent, uint_t namecols) { char * const fltr = g_ctx[cfg.curctx].c_fltr; - /* If there's a filter string, highlight matches */ + /* If there's a filter string, dim matching characters */ if (fltr[1]) { uchar_t matched[NAME_MAX] = {0}; - int match_attrs = A_BOLD; /* Default: just bold for selected entries */ - - /* For non-selected entries, also add reverse video to matches */ - if (!sel) - match_attrs |= A_REVERSE; + int match_attrs = A_DIM; /* Get match positions based on filter type */ if (cfg.regex) { - /* For regex, we don't highlight - just print normally */ + /* For regex, we don't dim - just print normally */ #ifndef NOLC addwstr(unescape(ent->name, namecols)); #else @@ -4664,7 +4660,7 @@ static void printent_name(const struct entry *ent, uint_t namecols, bool sel) } } #else - /* Non-wide character version for fuzzy highlighting */ + /* Non-wide character version for fuzzy dimming */ const char *name = unescape(ent->name, MIN(namecols, ent->nlen) + 1); for (uint_t i = 0; (i < namecols) && name[i]; ++i) { if (matched[i]) { @@ -4677,7 +4673,7 @@ static void printent_name(const struct entry *ent, uint_t namecols, bool sel) } #endif } else { - /* String match - highlight the substring */ + /* String match - dim the substring */ string_match_positions(fltr + 1, ent->name, matched); #ifndef NOLC wchar_t * const wbuf = unescape(ent->name, namecols); @@ -4692,7 +4688,7 @@ static void printent_name(const struct entry *ent, uint_t namecols, bool sel) } } #else - /* Non-wide character version for string highlighting */ + /* Non-wide character version for string dimming */ const char *name = unescape(ent->name, MIN(namecols, ent->nlen) + 1); for (uint_t i = 0; (i < namecols) && name[i]; ++i) { if (matched[i]) { @@ -4715,10 +4711,9 @@ static void printent_name(const struct entry *ent, uint_t namecols, bool sel) } } #else -/* Without highlight support, just print the name normally */ -static inline void printent_name(const struct entry *ent, uint_t namecols, bool sel) +/* Without dimming support, just print the name normally */ +static inline void printent_name(const struct entry *ent, uint_t namecols) { - (void)sel; /* Suppress unused parameter warning */ #ifndef NOLC addwstr(unescape(ent->name, namecols)); #else @@ -4786,7 +4781,7 @@ static void printent(int pdents_index, uint_t namecols, bool sel) if (!ind) ++namecols; - printent_name(ent, namecols, sel); + printent_name(ent, namecols); if (attrs) attroff(attrs);