Backward search in internal viewer - 2nd Approximation

Andrew V. Samoilov sav at bcs.zp.ua
Tue Aug 28 11:21:37 UTC 2001


Hi!
: 
: > This patch adds backward search feature for normal search
: > in internal viewer. This one is for non gnome edition, sorry.
: 
: Thanks for trying, but an implementation for GNOME would be nice too. I
: understand that you cannot use input_dialog(), so this means writing a
: real GNOME dialog. You can find some examples in gdialogs.c.

I think now we don't care about GNOME edition.

: 
: Another problem is that your patch doesn't implement backward search in
: the Hex mode and for regular expressions. This would make the behavior of

Now backward search in the Hex mode is implemented. Regular expressions are
still waiting...

: the viewer inconsistent. From the user's point of view, backward search
: makes sence in all of those modes.

Well, but now I have time to satisfy only my needs ;-(

: Now let's see your patch.
: > -	p = (found_len ? search_start : view->last) - 1;
: > +	p = found_len ? (search_start ? search_start - 1 : 0) : search_start;
: 
: Not clear. Why aren't you using view->last anymore? I understand it
: affects GNOME too.

I don't want cycling now, but it may be implemented in future...

BTW, first field of view structure is always 0 and can be safely removed.
I did it 2 years ago and don't find any side effects.

Regards,
Andrew.

Index: view.c
===================================================================
RCS file: /home/sav/.cvsroot/mc/src/view.c,v
retrieving revision 1.57
diff -u -p -r1.57 view.c
--- view.c	14 Aug 2001 16:45:05 -0000	1.57
+++ view.c	14 Aug 2001 16:53:37 -0000
@@ -1383,11 +1379,32 @@ icase_search_p (WView *view, char *text,
     char *q;
     int lng;
 
+#ifdef	HAVE_GNOME
     if ((q = _icase_search (text, data, &lng)) != 0) {
 	view->found_len = lng;
 	view->search_start = q - data - lng;
 	return 1;
     }
+#else
+    int direction = view->direction;
+
+    if (direction == -1)
+	reverse_string (text);
+
+    q = _icase_search (text, data, &lng);
+
+    if (direction == -1)
+	reverse_string (text);
+
+    if (q != 0) {
+	if (direction > 0)
+	    view->search_start = q - data - lng;
+	else
+	    view->search_start = strlen (data) - (q - data);
+	view->found_len = lng;
+	return 1;
+    }
+#endif
     return 0;
 }
 
@@ -1417,8 +1434,13 @@ get_line_at (WView *view, unsigned long 
     long i = 0;
     int  prev = 0;
 
+    if (!pos && direction == -1)
+	return 0;
+
     /* skip over all the possible zeros in the file */
     while ((ch = get_byte (view, pos)) == 0) {
+	if (!pos && direction == -1)
+	    return 0;
 	pos += direction; i++;
     }
     *skipped = i;
@@ -1436,21 +1458,27 @@ get_line_at (WView *view, unsigned long 
 	    usable_size = buffer_size - 2;
 	}
 
-	pos += direction; i++;
+	i++;
+	buffer [i] = ch;
 
-	if (ch == '\n' || !ch){
+	if (!pos && direction == -1)
+	    break;
+
+	pos += direction;
+
+	if (ch == '\n' || !ch)
 	    break;
-	}
-	buffer [i] = ch;
     }
+
     if (buffer){
 	buffer [0] = prev;
 	buffer [i] = 0;
-
+#ifdef	HAVE_GNOME	
 	/* If we are searching backwards, reverse the string */
 	if (direction < 0) {
 	    reverse_string (buffer + 1);
 	}
+#endif
     }
 
     *p = pos;
@@ -1535,7 +1563,7 @@ search (WView *view, char *text, int (*s
     if (view->direction == 1){
 	p = found_len ? search_start + 1 : search_start;
     } else {
-	p = (found_len ? search_start : view->last) - 1;
+	p = (found_len && search_start) ? search_start - 1 : search_start;
     }
     beginning = p;
 
@@ -1598,7 +1626,7 @@ search (WView *view, char *text, int (*s
 	if (view->direction == 1)
 	    t += forward_line_start;
 	else
-	    t += reverse_line_start ? reverse_line_start + 3 : 0;
+	    t = reverse_line_start ? reverse_line_start + 2 : 0;
 	view->search_start += t;
 
 	if (t != beginning){
@@ -1632,18 +1660,51 @@ static long
 block_search (WView *view, char *buffer, int len)
 {
     int w = view->widget.cols - view->have_frame + 1;
-
+    int direction = view->direction;
     char *d = buffer, b;
     unsigned long e;
 
     /* clear interrupt status */
     got_interrupt ();
     enable_interrupt_key ();
-    e = view->found_len ? view->search_start + 1 : view->search_start;
+    if (direction == 1)
+	e = view->found_len ? view->search_start + 1 : view->search_start;
+    else
+	e = (view->found_len && view->search_start) ? view->search_start - 1 : view->search_start;
 
     search_update_steps (view);
     update_activate = 0;
-    
+
+#ifndef HAVE_GNOME    
+    if (direction == -1) {
+
+	for (d += len - 1; ; e--) {
+	    if (e <= update_activate){
+		update_activate -= update_steps;
+		if (verbose){
+		    view_percent (view, e, w, TRUE);
+		    mc_refresh ();
+		}
+		if (got_interrupt ())
+		    break;
+	    }
+	    b = get_byte (view, e);
+
+	    if (*d == b){
+		if (d == buffer){
+		    disable_interrupt_key ();
+		    return e;
+		}
+		d--;
+	    } else {
+		e += buffer + len - 1 - d;
+		d = buffer + len - 1;
+	    }
+	    if (e == 0)
+		break;
+	}
+    } else
+#endif
     while (e < view->last_byte){
 	if (e >= update_activate){
 	    update_activate += update_steps;
@@ -1993,7 +2054,54 @@ normal_search (WView *view, int directio
 	convert_to_display( exp );
 #endif
 
+#ifndef HAVE_GNOME
+    {
+
+    enum {
+	SEARCH_DLG_HEIGHT = 8,
+	SEARCH_DLG_WIDTH  = 58
+    };
+    
+    static int replace_backwards;
+    int treplace_backwards = replace_backwards;
+    char *tsearch_text;
+
+    QuickWidget quick_widgets[] = {
+	{quick_button, 6, 10, 5, SEARCH_DLG_HEIGHT, N_("&Cancel"), 0, B_CANCEL, 
+	 0, 0, NULL},
+	{quick_button, 2, 10, 5, SEARCH_DLG_HEIGHT, N_("&Ok"), 0, B_ENTER, 
+	 0, 0, NULL},
+	{quick_checkbox, 3, SEARCH_DLG_WIDTH, 4, SEARCH_DLG_HEIGHT, N_("&Backwards"), 0, 0,
+	 0, 0, NULL},
+	{quick_input, 3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT, "", 52, 0, 
+	 0, 0, N_(" Search ")},
+	{quick_label, 2, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT, N_(" Enter search string:"), 0, 0, 
+	 0, 0, 0},
+	{0}
+    };
+
+    quick_widgets[2].result = &treplace_backwards;
+    quick_widgets[3].str_result = &tsearch_text;
+    quick_widgets[3].text = exp;
+
+    {
+	QuickDialog Quick_input = {
+	 SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT, -1, 0, N_(" Search "),
+	 "[Input Line Keys]", "quick_input", 0, 0 
+	};
+	Quick_input.widgets = quick_widgets;
+	if (quick_dialog (&Quick_input) == B_CANCEL) {
+	    return;
+	}
+	exp = *(quick_widgets[3].str_result);
+	replace_backwards = treplace_backwards;
+	direction = (replace_backwards) ? -1 : 1;
+    }
+}   
+#else
     exp = input_dialog (_(" Search "), _(" Enter search string:"), exp);
+#endif	/* !HAVE_GNOME */
+
     if ((!exp)){
 	return;
     }




More information about the mc-devel mailing list