add a find in page
authorLaurent Mazet <mazet@softndesign.org>
Sun, 9 Mar 2025 12:21:50 +0000 (13:21 +0100)
committerLaurent Mazet <mazet@softndesign.org>
Sun, 9 Mar 2025 12:21:50 +0000 (13:21 +0100)
display.c

index e2c74ff0546b087e915dc66cdc9ec23051824847..d4caf48ef476b4420b534373d4e81be33d9fcd75 100644 (file)
--- a/display.c
+++ b/display.c
@@ -9,6 +9,10 @@
 
 #include "display.h"
 
+#define GETSKIP(s, ss) (((ss) > 0) ? (ss) : (s))
+
+#define MAXLEN 256
+
 typedef enum {
     white = 1,
     red,
@@ -443,6 +447,7 @@ char *getwindow (char *msg, window_t *win, int length, int size, char *init)
         }
         VERBOSE (DEBUG, fprintf (stderr, "i: %d l: %d\n", i, l));
     }
+    set_color (white);
 
     if (name) {
         VERBOSE (DEBUG, fprintf (stderr, "name: '%s'\n", name));
@@ -531,9 +536,31 @@ void errorwindow (char *msg, window_t *win)
     }
 }
 
+int _find (char **lines, int nblines, int skip, char *search)
+{
+    int len = strlen (search);
+    int i, j, k;
+    for (i = skip; i < nblines; i++) {
+        for (j = 0; lines[i][j] != 0; j++) {
+            int count = 0;
+            for (k = 0; k < len; k++) {
+                if (lines[i][j + k] == search[k]) {
+                    count++;
+                }
+            }
+            if (count == len) {
+                return i;
+            }
+        }
+    }
+
+    return -1;
+}
+
 char *filewindow (char *name, window_t *win)
 {
     static char *_help =
+        "<f> Find in page\n"
         "<h> Help message\n"
         "<i> Move up\n"
         "<k> Move down\n"
@@ -562,19 +589,21 @@ char *filewindow (char *name, window_t *win)
     char *basename = strrchr (name, *SEPARATOR);
     basename = (basename) ? basename + 1 : name;
 
-    set_color (black);
     int skip  = 0;
     int stop = 0;
     int mode = 1;
+    char *pt, *search = NULL;
+    int sskip = 0;
     while (!stop) {
         int i, j;
         char **lines = (mode) ? std : hexa;
         int len = (mode) ? lenstd : lenhexa;
 
+        set_color (black);
         _dobound (win->xsize, win->ysize, win->xoffset, win->yoffset);
 
         char percent[4] = {' ', ' ', ' ', 0};
-        int ratio = (skip + win->ysize > len) ? 100 : 100 * (skip + win->ysize) / len;
+        int ratio = (GETSKIP (skip, sskip) + win->ysize > len) ? 100 : 100 * (GETSKIP (skip, sskip) + win->ysize) / len;
         for (i = 2; (i >= 0) && (ratio > 0); i--, ratio /= 10) {
             percent[i] = '0' + (ratio % 10);
         }
@@ -582,17 +611,17 @@ char *filewindow (char *name, window_t *win)
         mvaddstr (win->yoffset - 1, win->xoffset + (win->xsize - strlen (title)) / 2, title);
         free (title);
 
-        if (skip > 0) {
+        if (GETSKIP (skip, sskip) > 0) {
             mvaddch (win->yoffset, win->xoffset - 1, ACS_UARROW);
             mvaddch (win->yoffset, win->xsize + win->xoffset, ACS_UARROW);
         }
-        if (skip + win->ysize < len) {
+        if (GETSKIP (skip, sskip) + win->ysize < len) {
             mvaddch (win->ysize + win->yoffset - 1, win->xoffset - 1, ACS_DARROW);
             mvaddch (win->ysize + win->yoffset - 1, win->xsize + win->xoffset, ACS_DARROW);
         }
 
-        for (i = 0; (i < win->ysize) && (lines[skip + i]); i++) {
-            unsigned char *pt = (unsigned char *)(lines[skip + i]);
+        for (i = 0; (i < win->ysize) && (lines[GETSKIP (skip, sskip) + i]); i++) {
+            unsigned char *pt = (unsigned char *)(lines[GETSKIP (skip, sskip) + i]);
             for (j = 0; (j < win->xsize) && (pt[j] != '\0'); j++) {
                 if (pt[j] == 128) {
                     set_color (imagenta);
@@ -635,6 +664,13 @@ char *filewindow (char *name, window_t *win)
         case 'q':
             stop = 1;
             break;
+        case '/':
+        case 'f':
+            pt = getwindow ("Search", win, 12, MAXLEN, search);
+            free (search);
+            search = pt;
+            sskip = _find (lines, len, skip, search);
+            break;
         case 'h':
             helpwindow (_help, (win->xsize - strmaxlen (_help, '\n')) / 2, 3 * win->yoffset);
             set_color (black);
@@ -654,6 +690,12 @@ char *filewindow (char *name, window_t *win)
         case 'm':
             mode = (mode) ? 0 : 1;
             break;
+        case 'n':
+            sskip = _find (lines, len, GETSKIP (skip, sskip) + 1, search);
+            if (sskip == -1) {
+                sskip = _find (lines, len, 0, search);
+            }
+            break;
         }
     }
     set_color (white);
@@ -661,6 +703,8 @@ char *filewindow (char *name, window_t *win)
     freelines (hexa);
     freelines (std);
 
+    free (search);
+
     return NULL;
 }