From 83fa6a0ff62289c9f420a435d4457042f7c420c6 Mon Sep 17 00:00:00 2001 From: Arun Prakash Jana Date: Sun, 2 Aug 2020 16:18:35 +0530 Subject: [PATCH] Support xterm 256 color --- README.md | 2 +- nnn.1 | 11 +++++++- src/nnn.c | 75 +++++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 65 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 5aaa7dd4..2ba6c2ee 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ It runs smoothly on the Pi, [Termux](https://www.youtube.com/watch?v=AbaauM7gUJw - Frugal - Typically needs less than 3.5MB resident memory - - Works with 8-bit colors + - Works with 8 colors (and xterm 256 colors) - Disk-IO sensitive (few disk reads and writes) - No FPU usage (all integer maths, even for file size) - Minimizes screen refresh with fast line redraws diff --git a/nnn.1 b/nnn.1 index df7e02d9..f000eda9 100644 --- a/nnn.1 +++ b/nnn.1 @@ -408,9 +408,18 @@ separated by \fI;\fR: .Pp \fBNNN_COLORS:\fR string of color codes for each context, e.g.: .Bd -literal + # 8 color codes + # codes: 0-black, 1-red, 2-green, 3-yellow, 4-blue (default), 5-magenta, 6-cyan, 7-white export NNN_COLORS='1234' - codes: 0-black, 1-red, 2-green, 3-yellow, 4-blue (default), 5-magenta, 6-cyan, 7-white + # xterm 256 color codes (in hex) + # codes: https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg + export NNN_COLORS='#0a1b2c3d' + + # both (256 followed by 8 as fallback, separated by ';') + export NNN_COLORS='#0a1b2c3d;1234' + + NOTE: If only 256 colors are specified and the terminal doesn't support, default (4-blue) is used. .Ed .Pp \fBNNN_ARCHIVE:\fR archive types to be handled silently (default: bzip2, (g)zip, tar). diff --git a/src/nnn.c b/src/nnn.c index b6557399..714ea353 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -757,6 +757,21 @@ static char *xitoa(uint val) return &ascbuf[++i]; } +/* Return the integer value of a char representing HEX */ +static uchar xchartohex(uchar c) +{ + if (xisdigit(c)) + return c - '0'; + + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + + return c; +} + /* * Source: https://elixir.bootlin.com/linux/latest/source/arch/alpha/include/asm/bitops.h */ @@ -1571,18 +1586,51 @@ static bool initcurses(void *oldmask) char *colors = getenv(env_cfg[NNN_COLORS]); if (colors || !getenv("NO_COLOR")) { + uint *pcode; + char ch; + bool ext = FALSE; + start_color(); use_default_colors(); + if (colors && *colors == '#') { + if (COLORS >= 256) { + ++colors; + ext = TRUE; + + /* + * If fallback colors are specified, set the separator + * to NULL so we don't interpret separator and fallback + * if fewer than CTX_MAX xterm 256 colors are specified. + */ + char *sep = strchr(colors, ';'); + if (sep) + *sep = '\0'; + } else + /* Check if 8 colors fallback is appended */ + colors = strchr(colors, ';') + 1; + } + /* Get and set the context colors */ for (uchar i = 0; i < CTX_MAX; ++i) { - if (colors && *colors) { - g_ctx[i].color = (*colors < '0' || *colors > '7') ? 4 : *colors - '0'; - ++colors; - } else - g_ctx[i].color = 4; + pcode = &g_ctx[i].color; - init_pair(i + 1, g_ctx[i].color, -1); + if (colors && *colors) { + if (ext) { + ch = *colors; + if (*++colors) { + *pcode = (16 * xchartohex(ch)) + xchartohex(*colors); + ++colors; + } else + *pcode = xchartohex(ch); + } else { + *pcode = (*colors < '0' || *colors > '7') ? 4 : *colors - '0'; + ++colors; + } + } else + *pcode = 4; + + init_pair(i + 1, *pcode, -1); } } @@ -2217,21 +2265,6 @@ static int xstrverscasecmp(const char * const s1, const char * const s2) static int (*namecmpfn)(const char * const s1, const char * const s2) = &xstricmp; -/* Return the integer value of a char representing HEX */ -static char xchartohex(char c) -{ - if (xisdigit(c)) - return c - '0'; - - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - - return c; -} - static char * (*fnstrstr)(const char *haystack, const char *needle) = &strcasestr; #ifdef PCRE static const unsigned char *tables;