]> Sergey Matveev's repositories - nnn.git/commitdiff
better helpstring compression
authorNRK <nrk@disroot.org>
Tue, 13 Jun 2023 16:41:56 +0000 (22:41 +0600)
committerNRK <nrk@disroot.org>
Thu, 15 Jun 2023 02:49:30 +0000 (08:49 +0600)
this avoids multiple printf calls and instead decodes the buffer
natively. using %NN instead of %-NNc also saves two bytes per run.
helpstr is also made `static` to avoid unnecessary stack allocation.

src/nnn.c

index 592a083a92b31c20d6b0111692d4634b25a8ba34..ecedee43f9a8414f04ffa719f28011d7c6f5d0e0 100644 (file)
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -5079,82 +5079,87 @@ static void add_bookmark(char *path, char *newpath, int *presel)
 }
 
 /*
- * The help string tokens (each line) start with a HEX value
- * which indicates the number of spaces to print before the
- * particular token. This method was chosen instead of a flat
- * string because the number of bytes in help was increasing
- * the binary size by around a hundred bytes. This would only
- * have increased as we keep adding new options.
+ * The help string tokens (each line) start with a HEX value which indicates
+ * the number of spaces to print before the particular token. In the middle,
+ * %NN can be used to insert a run of spaces, e.g %10 will print 10 spaces.
+ * %NN MUST be 2 characters long, e.g %05 for 5 spaces.
+ *
+ * This method was chosen instead of a flat string because the number of bytes
+ * in help was increasing the binary size by around a hundred bytes. This would
+ * only have increased as we keep adding new options.
  */
 static void show_help(const char *path)
 {
-       const char *start, *end;
-       const char helpstr[] = {
+       static const char helpstr[] = {
+       "2|V\\_\n"
+       "2/. \\\\\n"
+       "1(;^; ||\n"
+       "3/___3\n"
+       "2(___n))\n"
        "0\n"
        "1NAVIGATION\n"
-              "9Up k  Up%-16cPgUp ^U  Page up\n"
-              "9Dn j  Down%-14cPgDn ^D  Page down\n"
-              "9Lt h  Parent%-12c~ ` @ -  ~, /, start, prev\n"
-          "5Ret Rt l  Open%-20c'  First file/match\n"
-              "9g ^A  Top%-21cJ  Jump to entry/offset\n"
-              "9G ^E  End%-20c^J  Toggle auto-advance on open\n"
-             "8B (,)  Book(mark)%-11cb ^/  Select bookmark\n"
-               "a1-4  Context%-11c(Sh)Tab  Cycle/new context\n"
-           "62Esc ^Q  Quit%-20cq  Quit context\n"
-                "b^G  QuitCD%-18cQ  Pick/err, quit\n"
+              "9Up k  Up%16PgUp ^U  Page up\n"
+              "9Dn j  Down%14PgDn ^D  Page down\n"
+              "9Lt h  Parent%12~ ` @ -  ~, /, start, prev\n"
+          "5Ret Rt l  Open%20'  First file/match\n"
+              "9g ^A  Top%21J  Jump to entry/offset\n"
+              "9G ^E  End%20^J  Toggle auto-advance on open\n"
+             "8B (,)  Book(mark)%11b ^/  Select bookmark\n"
+               "a1-4  Context%11(Sh)Tab  Cycle/new context\n"
+           "62Esc ^Q  Quit%20q  Quit context\n"
+                "b^G  QuitCD%18Q  Pick/err, quit\n"
        "0\n"
        "1FILTER & PROMPT\n"
-                 "c/  Filter%-17c^N  Toggle type-to-nav\n"
-               "aEsc  Exit prompt%-12c^L  Toggle last filter\n"
-                 "c.  Toggle hidden%-5cAlt+Esc  Unfilter, quit context\n"
+                 "c/  Filter%17^N  Toggle type-to-nav\n"
+               "aEsc  Exit prompt%12^L  Toggle last filter\n"
+                 "c.  Toggle hidden%05Alt+Esc  Unfilter, quit context\n"
        "0\n"
        "1FILES\n"
-              "9o ^O  Open with%-15cn  Create new/link\n"
-              "9f ^F  File stats%-14cd  Detail mode toggle\n"
-                "b^R  Rename/dup%-14cr  Batch rename\n"
-                 "cz  Archive%-17ce  Edit file\n"
-                 "c*  Toggle exe%-14c>  Export list\n"
-           "6Space +  (Un)select%-12cm-m  Select range/clear\n"
-                 "ca  Select all%-14cA  Invert sel\n"
-              "9p ^P  Copy here%-12cw ^W  Cp/mv sel as\n"
-              "9v ^V  Move here%-15cE  Edit sel list\n"
-              "9x ^X  Delete%-18cS  Listed sel size\n"
+              "9o ^O  Open with%15n  Create new/link\n"
+              "9f ^F  File stats%14d  Detail mode toggle\n"
+                "b^R  Rename/dup%14r  Batch rename\n"
+                 "cz  Archive%17e  Edit file\n"
+                 "c*  Toggle exe%14>  Export list\n"
+           "6Space +  (Un)select%12m-m  Select range/clear\n"
+                 "ca  Select all%14A  Invert sel\n"
+              "9p ^P  Copy here%12w ^W  Cp/mv sel as\n"
+              "9v ^V  Move here%15E  Edit sel list\n"
+              "9x ^X  Delete%18S  Listed sel size\n"
                "aEsc  Send to FIFO\n"
        "0\n"
        "1MISC\n"
-             "8Alt ;  Select plugin%-11c=  Launch app\n"
-              "9! ^]  Shell%-19c]  Cmd prompt\n"
-                 "cc  Connect remote%-10cu  Unmount remote/archive\n"
-              "9t ^T  Sort toggles%-12cs  Manage session\n"
-                 "cT  Set time type%-11c0  Lock\n"
-                "b^L  Redraw%-18c?  Help, conf\n"
+             "8Alt ;  Select plugin%11=  Launch app\n"
+              "9! ^]  Shell%19]  Cmd prompt\n"
+                 "cc  Connect remote%10u  Unmount remote/archive\n"
+              "9t ^T  Sort toggles%12s  Manage session\n"
+                 "cT  Set time type%110  Lock\n"
+                "b^L  Redraw%18?  Help, conf\n"
        };
 
        int fd = create_tmp_file();
        if (fd == -1)
                return;
 
-       dprintf(fd, "  |V\\_\n"
-                   "  /. \\\\\n"
-                   " (;^; ||\n"
-                   "   /___3\n"
-                   "  (___n))\n");
-
        char *prog = xgetenv(env_cfg[NNN_HELP], NULL);
        if (prog)
                get_output(prog, NULL, NULL, fd, FALSE);
 
-       start = end = helpstr;
-       while (*end) {
-               if (*end == '\n') {
-                       snprintf(g_buf, CMD_LEN_MAX, "%*c%.*s",
-                                xchartohex(*start), ' ', (int)(end - start), start + 1);
-                       dprintf(fd, g_buf, ' ');
-                       start = end + 1;
+       bool hex = true;
+       char *w = g_buf;
+       const char *end = helpstr + (sizeof helpstr - 1);
+       for (const char *s = helpstr; s < end; ++s) {
+               if (hex) {
+                       for (int k = 0, n = xchartohex(*s); k < n; ++k) *w++ = ' ';
+               } else if (*s == '%') {
+                       int n = ((s[1] - '0') * 10) + (s[2] - '0');
+                       for (int k = 0; k < n; ++k) *w++ = ' ';
+                       s += 2;
+               } else {
+                       *w++ = *s;
                }
-
-               ++end;
+               hex = *s == '\n';
        }
+       if (write(fd, g_buf, w - g_buf)) {} // silence warning
 
        dprintf(fd, "\nLOCATIONS\n");
        for (uchar_t i = 0; i < CTX_MAX; ++i)
@@ -5178,9 +5183,9 @@ static void show_help(const char *path)
        }
 
        for (uchar_t i = NNN_OPENER; i <= NNN_TRASH; ++i) {
-               start = getenv(env_cfg[i]);
-               if (start)
-                       dprintf(fd, "%s: %s\n", env_cfg[i], start);
+               char *s = getenv(env_cfg[i]);
+               if (s)
+                       dprintf(fd, "%s: %s\n", env_cfg[i], s);
        }
 
        if (selpath)