qemacs-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemacs-commit] qemacs qe.c qe.h qestyles.h search.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs qe.c qe.h qestyles.h search.c
Date: Wed, 19 Aug 2015 20:33:01 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        15/08/19 20:33:01

Modified files:
        .              : qe.c qe.h qestyles.h search.c 

Log message:
        search: show search matches, fix bugs
        - fix bug with word-match incremental search
        - pass max offset to eb_search
        - simplify search code, keep separate u32 and flag arrays
        - add ISearchState* to EditWindow to display current or last matches
        - add style for search matches

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.204&r2=1.205
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.201&r2=1.202
http://cvs.savannah.gnu.org/viewcvs/qemacs/qestyles.h?cvsroot=qemacs&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/qemacs/search.c?cvsroot=qemacs&r1=1.2&r2=1.3

Patches:
Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.204
retrieving revision 1.205
diff -u -b -r1.204 -r1.205
--- qe.c        19 Aug 2015 19:54:29 -0000      1.204
+++ qe.c        19 Aug 2015 20:33:01 -0000      1.205
@@ -1656,6 +1656,8 @@
 #endif
     /* deactivate region hilite */
     s->region_style = 0;
+    /* deactivate search hilite */
+    s->isearch_state = NULL;
 
     /* well, currently nothing needs to be aborted in global context */
     /* CG: Should remove popups, sidepanes, helppanes... */
@@ -3607,19 +3609,24 @@
 int generic_get_colorized_line(EditState *s, unsigned int *buf, int buf_size,
                                int *offsetp, int line_num)
 {
+    int len, offset = *offsetp;
+
 #ifndef CONFIG_TINY
     if (s->colorize_func) {
-        int offset = *offsetp;
-        int len = syntax_get_colorized_line(s, buf, buf_size, offsetp, 
line_num);
+        len = syntax_get_colorized_line(s, buf, buf_size, offsetp, line_num);
         if (s->b->b_styles)
             len = combine_static_colorized_line(s, buf, buf_size, &offset, 
line_num);
-        return len;
-    }
+    } else
 #endif
     if (s->b->b_styles)
-        return get_staticly_colorized_line(s, buf, buf_size, offsetp, 
line_num);
+        len = get_staticly_colorized_line(s, buf, buf_size, offsetp, line_num);
+    else
+        len = eb_get_line(s->b, buf, buf_size, offsetp);
+
+    if (s->isearch_state)
+        isearch_colorize_matches(s, buf, len, offset, *offsetp);
 
-    return eb_get_line(s->b, buf, buf_size, offsetp);
+    return len;
 }
 
 #define RLE_EMBEDDINGS_SIZE    128
@@ -3686,7 +3693,8 @@
     offset0 = offset;
     if (s->colorize_func
     ||  s->curline_style || s->region_style
-    ||  s->b->b_styles) {
+    ||  s->b->b_styles
+    ||  s->isearch_state) {
         colored_nb_chars = s->get_colorized_line(s, colored_chars,
                                                  countof(colored_chars),
                                                  &offset0, line_num);

Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.201
retrieving revision 1.202
diff -u -b -r1.201 -r1.202
--- qe.h        19 Aug 2015 19:20:58 -0000      1.201
+++ qe.h        19 Aug 2015 20:33:01 -0000      1.202
@@ -1174,6 +1174,7 @@
     EditBuffer *b;
 
     EditBuffer *last_buffer;    /* for predict_switch_to_buffer */
+    ISearchState *isearch_state;  /* active search to colorize matches */
 
     /* mode specific info */
     ModeDef *mode;
@@ -1804,7 +1805,8 @@
 void do_save_buffer(EditState *s);
 void do_write_file(EditState *s, const char *filename);
 void do_write_region(EditState *s, const char *filename);
-// should take argument?
+void isearch_colorize_matches(EditState *s, unsigned int *buf, int len,
+                              int offset, int offset_end);
 void do_isearch(EditState *s, int dir);
 void do_query_replace(EditState *s, const char *search_str,
                       const char *replace_str);

Index: qestyles.h
===================================================================
RCS file: /sources/qemacs/qemacs/qestyles.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- qestyles.h  15 Aug 2015 13:08:42 -0000      1.10
+++ qestyles.h  19 Aug 2015 20:33:01 -0000      1.11
@@ -70,9 +70,11 @@
 
     /* popup / region styles */
     STYLE_DEF(QE_STYLE_REGION_HILITE, "region-hilite",
-              COLOR_TRANSPARENT, QERGB(0x80, 0xf0, 0xf0),
+              QERGB(0x00, 0x00, 0x00), QERGB(0x80, 0xf0, 0xf0),
+              0, 0)
+    STYLE_DEF(QE_STYLE_SEARCH_HILITE, "search-hilite",
+              QERGB(0x00, 0x00, 0x00), QERGB(0x00, 0x80, 0x80),
               0, 0)
-
     STYLE_DEF(QE_STYLE_SEARCH_MATCH, "search-match",
               QERGB(0xe0, 0xe0, 0xe0), QERGB(0xf0, 0x00, 0xf0),
               0, 0)

Index: search.c
===================================================================
RCS file: /sources/qemacs/qemacs/search.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- search.c    19 Aug 2015 16:22:30 -0000      1.2
+++ search.c    19 Aug 2015 20:33:01 -0000      1.3
@@ -31,8 +31,34 @@
 #define SEARCH_FLAG_HEX        0x0010
 #define SEARCH_FLAG_UNIHEX     0x0020
 
-/* XXX: OPTIMIZE ! */
-static int eb_search(EditBuffer *b, int start_offset, int dir, int flags,
+/* should separate search string length and number of match positions */
+#define SEARCH_LENGTH  256
+#define FOUND_TAG      0x80000000
+#define FOUND_REV      0x40000000
+
+struct ISearchState {
+    EditState *s;
+    int saved_mark;
+    int start_offset;
+    int start_dir;
+    int quoting;
+    int dir;
+    int pos;  /* position in search_u32_flags */
+    int search_u32_len;
+    int search_flags;
+    int found_offset, found_end;
+    unsigned int search_u32_flags[SEARCH_LENGTH];
+    unsigned int search_u32[SEARCH_LENGTH];
+};
+
+ISearchState isearch_state;
+
+/* store last searched string */
+static unsigned int last_search_u32[SEARCH_LENGTH];
+static int last_search_u32_len = 0;
+
+static int eb_search(EditBuffer *b, int dir, int flags,
+                     int start_offset, int end_offset,
                      const unsigned int *buf, int len,
                      CSSAbortFunc *abort_func, void *abort_opaque,
                      int *found_offset, int *found_end)
@@ -43,6 +69,9 @@
     if (len == 0)
         return 0;
 
+    if (end_offset > total_size)
+        end_offset = total_size;
+
     *found_offset = -1;
     *found_end = -1;
 
@@ -61,15 +90,18 @@
     if (flags & SEARCH_FLAG_HEX) {
         /* handle buffer as single bytes */
         /* XXX: should handle ucs2 and ucs4 as words */
-        for (;; (void)(dir >= 0 && offset++)) {
+        if (dir > 0)
+              offset--;
+        for (;;) {
             if (dir < 0) {
                 if (offset == 0)
                     return 0;
                 offset--;
-            }
-            if (offset >= total_size)
+            } else {
+                offset++;
+                if (offset >= end_offset)
                 return 0;
-
+            }
             if ((offset & 0xfffff) == 0) {
                 /* check for search abort every megabyte */
                 if (abort_func && abort_func(abort_opaque))
@@ -84,7 +116,7 @@
                 if (c != c2)
                     break;
                 if (pos >= len) {
-                    /* check end of word */
+                    if (dir > 0 || offset2 <= start_offset) {
                     *found_offset = offset;
                     *found_end = offset2;
                     return 1;
@@ -92,6 +124,7 @@
             }
         }
     }
+    }
 
     for (offset1 = offset;;) {
         if (dir < 0) {
@@ -100,7 +133,7 @@
             eb_prevc(b, offset, &offset);
         } else {
             offset = offset1;
-            if (offset >= total_size)
+            if (offset >= end_offset)
                 return 0;
         }
         if ((offset & 0xfffff) == 0) {
@@ -109,13 +142,6 @@
                 return -1;
         }
 
-        if (flags & SEARCH_FLAG_WORD) {
-            /* check for start of word */
-            c = eb_prevc(b, offset, &offset3);
-            if (qe_isword(c))
-                continue;
-        }
-
         /* CG: XXX: Should use buffer specific accelerator */
         /* Get first char separately to compute offset1 */
         c = eb_nextc(b, offset, &offset1);
@@ -132,9 +158,9 @@
             }
             if (pos >= len) {
                 if (flags & SEARCH_FLAG_WORD) {
-                    /* check for end of word */
-                    c = eb_nextc(b, offset2, &offset3);
-                    if (qe_isword(c))
+                    /* check for word boundaries */
+                    if (qe_isword(eb_prevc(b, offset, &offset3))
+                    ||  qe_isword(eb_nextc(b, offset2, &offset3)))
                         break;
                 }
                 if (dir > 0 || offset2 <= start_offset) {
@@ -150,40 +176,17 @@
     }
 }
 
-/* should separate search string length and number of match positions */
-#define SEARCH_LENGTH  256
-#define FOUND_TAG      0x80000000
-#define FOUND_REV      0x40000000
-
-/* store last searched string */
-static unsigned int last_search_u32[SEARCH_LENGTH];
-static int last_search_u32_len = 0;
-
 static int search_abort_func(__unused__ void *opaque)
 {
     return is_user_input_pending();
 }
 
-struct ISearchState {
-    EditState *s;
-    int saved_mark;
-    int start_offset;
-    int start_dir;
-    int quoting;
-    int dir;
-    int pos;
-    int search_flags;
-    int found_offset, found_end;
-    unsigned int search_u32[SEARCH_LENGTH];
-};
-
 static void buf_encode_search_u32(buf_t *out, const unsigned int *str, int len)
 {
     int i;
 
     for (i = 0; i < len; i++) {
         unsigned int v = str[i];
-        if (!(v & FOUND_TAG)) {
             if (v < 32 || v == 127) {
                 buf_printf(out, "^%c", (v + '@') & 127);
             } else {
@@ -192,7 +195,6 @@
             if (buf_avail(out) <= 0)
                 break;
         }
-    }
 }
 
 static void buf_encode_search_str(buf_t *out, const char *str)
@@ -214,7 +216,6 @@
     EditState *s = is->s;
     char ubuf[256];
     buf_t outbuf, *out;
-    unsigned int buf[SEARCH_LENGTH];
     int c, i, len, hex_nibble, max_nibble, h, hc;
     unsigned int v;
     int search_offset, flags, dir = is->start_dir;
@@ -230,38 +231,39 @@
         max_nibble = 2;
 
     for (i = 0; i < is->pos; i++) {
-        v = is->search_u32[i];
+        v = is->search_u32_flags[i];
         if (v & FOUND_TAG) {
             dir = (v & FOUND_REV) ? -1 : 1;
             search_offset = v & ~(FOUND_TAG | FOUND_REV);
             continue;
         }
         c = v;
-        if (len < countof(buf)) {
+        if (len < countof(is->search_u32)) {
             if (max_nibble) {
                 h = to_hex(c);
                 if (h >= 0) {
                     hc = (hc << 4) | h;
                     if (++hex_nibble == max_nibble) {
-                        buf[len++] = hc;
+                        is->search_u32[len++] = hc;
                         hex_nibble = hc = 0;
                     }
                 } else {
                     if (c == ' ' && hex_nibble) {
-                        buf[len++] = hc;
+                        is->search_u32[len++] = hc;
                         hex_nibble = hc = 0;
                     }
                 }
             } else {
-                buf[len++] = c;
+                is->search_u32[len++] = c;
             }
         }
     }
-    if (hex_nibble >= 2) {
-        buf[len++] = hc;
+    if (hex_nibble >= 2 && len < countof(is->search_u32)) {
+        is->search_u32[len++] = hc;
         hex_nibble = hc = 0;
     }
 
+    is->search_u32_len = len;
     is->dir = dir;
 
     if (len == 0) {
@@ -270,8 +272,10 @@
         s->region_style = 0;
         is->found_offset = -1;
     } else {
-        if (eb_search(s->b, search_offset, is->dir, flags,
-                      buf, len, search_abort_func, NULL,
+        if (eb_search(s->b, is->dir, flags,
+                      search_offset, s->b->total_size,
+                      is->search_u32, is->search_u32_len,
+                      search_abort_func, NULL,
                       &is->found_offset, &is->found_end) > 0) {
             s->region_style = QE_STYLE_SEARCH_MATCH;
             if (is->dir > 0) {
@@ -309,14 +313,14 @@
     if (is->dir < 0)
         buf_puts(out, " backward");
     buf_puts(out, ": ");
-    buf_encode_search_u32(out, is->search_u32, is->pos);
+    buf_encode_search_u32(out, is->search_u32, is->search_u32_len);
     if (is->quoting)
         buf_puts(out, "^Q-");
 
     /* display text */
     do_center_cursor_maybe(s);
     edit_display(s->qe_state);
-    put_status(NULL, "%s", out->buf);
+    put_status(NULL, "%s", out->buf);   /* XXX: why NULL? */
     dpy_flush(s->screen);
 }
 
@@ -328,7 +332,7 @@
             to = b->total_size;
         for (offset = from; is->pos < SEARCH_LENGTH && offset < to;) {
             c = eb_nextc(b, offset, &offset);
-            is->search_u32[is->pos++] = c;
+            is->search_u32_flags[is->pos++] = c;
         }
     }
     return is->pos - last;
@@ -339,7 +343,7 @@
     ISearchState *is = opaque;
     EditState *s = is->s;
     QEmacsState *qs = &qe_state;
-    int i, j, offset0, offset1, curdir = is->dir;
+    int offset0, offset1, curdir = is->dir;
     int emacs_behaviour = !qs->emulation_flags;
 
     if (is->quoting) {
@@ -358,19 +362,16 @@
         s->b->mark = is->saved_mark;
         s->offset = is->start_offset;
         s->region_style = 0;
+        s->isearch_state = NULL;
         put_status(s, "Quit");
     the_end:
         /* save current searched string */
-        if (is->pos > 0) {
-            j = 0;
-            for (i = 0; i < is->pos; i++) {
-                if (!(is->search_u32[i] & FOUND_TAG))
-                    last_search_u32[j++] = is->search_u32[i];
-            }
-            last_search_u32_len = j;
+        if (is->search_u32_len > 0) {
+            memcpy(last_search_u32, is->search_u32,
+                   is->search_u32_len * sizeof(*is->search_u32));
+            last_search_u32_len = is->search_u32_len;
         }
         qe_ungrab_keys();
-        qe_free(&is);
         edit_display(s->qe_state);
         dpy_flush(s->screen);
         return;
@@ -381,22 +382,23 @@
         is->dir = -1;
     addpos:
         /* use last seached string if no input */
-        if (is->pos == 0 && is->dir == curdir) {
-            memcpy(is->search_u32, last_search_u32,
-                   last_search_u32_len * sizeof(*is->search_u32));
-            is->pos = last_search_u32_len;
+        if (is->search_u32_len == 0 && is->dir == curdir) {
+            int len = min(last_search_u32_len, SEARCH_LENGTH - is->pos);
+            memcpy(is->search_u32_flags + is->pos, last_search_u32,
+                   len * sizeof(*is->search_u32_flags));
+            is->pos += len;
         } else
         if (is->pos < SEARCH_LENGTH) {
             /* add the match position, if any */
             unsigned long v = is->dir > 0 ? FOUND_TAG : FOUND_TAG | FOUND_REV;
-            if (is->found_offset < 0) {
+            if (is->found_offset < 0 && is->search_u32_len > 0) {
                 is->search_flags |= SEARCH_FLAG_WRAPPED;
                 if (is->dir < 0)
                     v |= s->b->total_size;
             } else {
                 v |= s->offset;
             }
-            is->search_u32[is->pos++] = v;
+            is->search_u32_flags[is->pos++] = v;
         }
         break;
     case KEY_CTRL('q'):
@@ -476,13 +478,16 @@
             s->region_style = 0;
             put_status(s, "Mark saved where search started");
             /* repost key */
-            if (ch != KEY_RET)
+            if (ch != KEY_RET) {
+                /* keep search matches lingering if exit via RET */
+                s->isearch_state = NULL;
                 unget_key(ch);
+            }
             goto the_end;
         } else {
         addch:
             if (is->pos < SEARCH_LENGTH) {
-                is->search_u32[is->pos++] = ch;
+                is->search_u32_flags[is->pos++] = ch;
             }
         }
         break;
@@ -493,17 +498,22 @@
 /* XXX: handle busy */
 void do_isearch(EditState *s, int dir)
 {
-    ISearchState *is;
+    ISearchState *is = &isearch_state;
+    EditState *e;
     int flags = SEARCH_FLAG_SMARTCASE;
 
-    is = qe_mallocz(ISearchState);
-    if (!is)
-        return;
+    /* stop displaying search matches on last window */
+    e = check_window(&is->s);
+    if (e) {
+        e->isearch_state = NULL;
+    }
+
+    memset(is, 0, sizeof(isearch_state));
+    s->isearch_state = is;
     is->s = s;
     is->saved_mark = s->b->mark;
     is->start_offset = s->offset;
     is->start_dir = is->dir = dir;
-    is->pos = 0;
     if (s->hex_mode) {
         if (s->unihex_mode)
             flags |= SEARCH_FLAG_UNIHEX;
@@ -516,6 +526,47 @@
     isearch_display(is);
 }
 
+void isearch_colorize_matches(EditState *s, unsigned int *buf, int len,
+                              int offset_start, int offset_end)
+{
+    ISearchState *is = s->isearch_state;
+    EditBuffer *b = s->b;
+    int offset, char_offset, found_offset, found_end;
+
+    if (!is || is->search_u32_len <= 0)
+        return;
+
+    char_offset = eb_get_char_offset(b, offset_start);
+    offset = eb_goto_char(b, char_offset <= is->search_u32_len ? 0 :
+                          char_offset - is->search_u32_len - 1);
+
+    while (eb_search(b, 1, is->search_flags, offset, offset_end,
+                     is->search_u32, is->search_u32_len, NULL, NULL,
+                     &found_offset, &found_end) > 0) {
+        int line, start, stop;
+
+        if (found_offset >= offset_end)
+            break;
+        if (found_end > offset_start) {
+            /* Compute character positions */
+            start = 0;
+            if (found_offset > offset_start)
+                eb_get_pos(b, &line, &start, found_offset);
+            stop = len;
+            if (found_end < offset_end) {
+                eb_get_pos(b, &line, &stop, found_end);
+                if (stop > len)
+                    stop = len;
+            }
+            if (start < stop) {
+                clear_color(buf + start, stop - start);
+                set_color(buf + start, buf + stop, QE_STYLE_SEARCH_HILITE);
+            }
+        }
+        offset = found_end;
+    }
+}
+
 static int search_to_u32(unsigned int *buf, int size,
                          const char *str, int flags)
 {
@@ -610,7 +661,8 @@
                                         is->replace_str, is->search_flags);
 
     for (;;) {
-        if (eb_search(s->b, is->found_offset, 1, is->search_flags,
+        if (eb_search(s->b, 1, is->search_flags,
+                      is->found_offset, s->b->total_size,
                       is->search_u32, is->search_u32_len,
                       NULL, NULL, &is->found_offset, &is->found_end) <= 0) {
             query_replace_abort(is);
@@ -784,7 +836,9 @@
     }
     search_u32_len = search_to_u32(search_u32, countof(search_u32),
                                    search_str, flags);
-    if (eb_search(s->b, s->offset, dir, flags, search_u32, search_u32_len,
+    if (eb_search(s->b, dir, flags,
+                  s->offset, s->b->total_size,
+                  search_u32, search_u32_len,
                   NULL, NULL, &found_offset, &found_end) > 0) {
         s->offset = (dir < 0) ? found_offset : found_end;
         do_center_cursor_maybe(s);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]