--- src/gui.c.old	2004-11-08 14:08:53.735671616 +0100
+++ src/gui.c	2004-11-08 15:40:58.565769776 +0100
@@ -4429,7 +4429,7 @@
 
 #if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MOTIF) \
 	|| defined(MSWIN_FIND_REPLACE) || defined(PROTO)
-static void concat_esc __ARGS((garray_T *gap, char_u *text, int what));
+static void concat_esc __ARGS((garray_T *gap, char_u *text, int what, int incregexp));
 
 /*
  * Get the text to use in a find/replace dialog.  Uses the last search pattern
@@ -4496,12 +4496,14 @@
 
 /*
  * Concatenate "text" to grow array "gap", escaping "what" with a backslash.
+ * Also, if incregexp, \1 will become \2, etc.
  */
     static void
-concat_esc(gap, text, what)
+concat_esc(gap, text, what, incregexp)
     garray_T	*gap;
     char_u	*text;
     int		what;
+    int		incregexp;
 {
     while (*text != NUL)
     {
@@ -4514,9 +4516,22 @@
 	    continue;
 	}
 #endif
+	if (incregexp 
+	    && (*text == '\\') 
+	    && ('1' <= *(text+1))
+	    && (*(text+1) <= '8')) 
+	/* yep, \9 won't be incremented, it's a bug */
+	{
+	    ga_append(gap, '\\');
+	    ga_append(gap, (*(text+1))+1);
+	    ++text;
+	}
+	else 
+	{
 	if (*text == what)
 	    ga_append(gap, '\\');
 	ga_append(gap, *text);
+	}
 	++text;
     }
 }
@@ -4536,26 +4551,59 @@
     int		i;
     int		type = (flags & FRD_TYPE_MASK);
     char_u	*p;
+    int		curcol;
+    int		curlnum;
 
     ga_init2(&ga, 1, 100);
 
     if (type == FRD_REPLACE)
     {
-	/* Do the replacement when the text under the cursor matches. */
-	i = STRLEN(find_text);
-	p = ml_get_cursor();
-	if (((flags & FRD_MATCH_CASE)
-		    ? STRNCMP(p, find_text, i) == 0
-		    : STRNICMP(p, find_text, i) == 0)
-		&& u_save_cursor() == OK)
-	{
-	    /* A button was pressed thus undo should be synced. */
-	    if (no_u_sync == 0)
+	/* A button was pressed thus undo should be synced. */
+	if (no_u_sync == 0)
 		u_sync();
-
-	    del_bytes((long)i, FALSE);
-	    ins_str(repl_text);
+	curcol = curwin->w_cursor.col;
+	curlnum = curwin->w_cursor.lnum;
+	ga_concat(&ga, (char_u *)".s/");
+	ga_concat(&ga, (char_u *)"\\V");
+	if (flags & FRD_MATCH_CASE)
+		ga_concat(&ga, (char_u *)"\\C");
+	else
+		ga_concat(&ga, (char_u *)"\\c");
+	/* modify the regexp to replace the match under cursor, 
+	 * not the first match on the line. In short, if on column 12
+	 * then "s/foo/bar/" becomes "s/^\(\.\{12\}\)foo/\1bar/". */
+	if (curcol > 0)
+	{
+	    ga_concat(&ga, (char_u *)"\\^\\(\\.\\{");
+	    i = 1;
+	    while (((int)MAXCOL / 10) >= i)
+		i *= 10 ;
+	    while (i >= 1) {
+		if (curcol >= i)
+		    ga_append(&ga, (((curcol / i) % 10) + 48)) ;
+		i /= 10 ;
+	    }
+	    ga_concat(&ga, (char_u *)"\\}\\)");
 	}
+	if (flags & FRD_WHOLE_WORD)
+		ga_concat(&ga, (char_u *)"\\<");
+	concat_esc(&ga, find_text, '/', (curcol > 0));	/* escape slashes */
+	if (flags & FRD_WHOLE_WORD)
+		ga_concat(&ga, (char_u *)"\\>");
+	ga_concat(&ga, (char_u *)"/");
+	if (curcol > 0)
+	    ga_concat(&ga, (char_u *)"\\1");
+	concat_esc(&ga, repl_text, '/', (curcol > 0));	/* escape slashes */
+	ga_concat(&ga, (char_u *)"/");
+	ga_append(&ga, NUL);
+	do_cmdline_cmd(ga.ga_data);
+	/* ga will be reused for the next match search right after */
+	ga_clear(&ga);
+	/* restore cursor, or the next match search 
+	 * won't start at the right position */
+	curwin->w_cursor.col = curcol;
+	curwin->w_cursor.lnum = curlnum;
+	check_cursor();
     }
     else if (type == FRD_REPLACEALL)
 	ga_concat(&ga, (char_u *)"%s/");
@@ -4568,9 +4616,9 @@
     if (flags & FRD_WHOLE_WORD)
 	ga_concat(&ga, (char_u *)"\\<");
     if (type == FRD_REPLACEALL || down)
-	concat_esc(&ga, find_text, '/');	/* escape slashes */
+	concat_esc(&ga, find_text, '/', 0);	/* escape slashes */
     else
-	concat_esc(&ga, find_text, '?');	/* escape '?' */
+	concat_esc(&ga, find_text, '?', 0);	/* escape '?' */
     if (flags & FRD_WHOLE_WORD)
 	ga_concat(&ga, (char_u *)"\\>");
 
@@ -4581,7 +4629,7 @@
 	    u_sync();
 
 	ga_concat(&ga, (char_u *)"/");
-	concat_esc(&ga, repl_text, '/');	/* escape slashes */
+	concat_esc(&ga, repl_text, '/', 0);	/* escape slashes */ 
 	ga_concat(&ga, (char_u *)"/g");
 	ga_append(&ga, NUL);
 	do_cmdline_cmd(ga.ga_data);
