%
%  forward and backward search functions.  These functions can search across
%  lines.
%
define search_across_lines (str, dir)
{
   variable n, s, s1, fun;

   fun = &fsearch;
   if (dir < 0) fun = &bsearch;

   n = is_substr (str, "\n");

   !if (n) return fun(str);
   
   s = substr (str, 1, n);
   s1 = substr (str, n + 1, strlen(str));
   n = strlen(s);
   
   push_mark ();
   
   while (fun(s))
     {
	% we are matched at end of the line.
	go_right (n);
	if (looking_at(s1)) 
	  {
	     go_left(n);
	     pop_mark(0);
	     return 1;
	  }
	if (dir < 0) go_left (n);
     }
   pop_mark(1);
   0;
}

define search_forward ()
{
   variable str, not_found;
   
   str = read_mini("Search forward:", LAST_SEARCH, Null_String);
   !if (strlen(str)) return;
   
   push_mark ();
   if (looking_at(str)) go_right(1);
   
   save_search_string (str);
   not_found = not (search_across_lines (str, 1));
   pop_mark (not_found);
   
   if (not_found) error ("Not found.");
}

define search_backward ()
{
   variable str;
   
   str = read_mini("Search backward:", LAST_SEARCH, Null_String);
   !if (strlen(str)) return;
   
   save_search_string (str);
   !if (search_across_lines (str, -1)) error ("Not found.");
}


define replace_do_replace (str, len)
{
   push_mark ();
   go_right(len);
   del_region ();
   insert (str);
}

define replace_cmd ()
{
   variable pat, n, rep, prompt, doit, err, ch, len;

   pat = read_mini("Replace:", Null_String, Null_String);
   len = strlen (pat);
   !if (len) return;
   
   prompt = strcat (strcat ("Replace '", pat), "' with:");
   rep = read_mini(prompt, Null_String, Null_String);

   push_spot ();
   prompt =  strcat(strcat(strcat (prompt, " '"), rep), "' ? (y/n/!/+/q/h)");
   while (n = search_across_lines(pat, 1), n)
     {
	do 
	  {
	     message(prompt);
	     update (0);
	     % regexp_mark_pattern(n);  this might be nice 
	
	     ch = getkey ();
	     if (ch == 'r')
	       {
		  recenter (window_info('r') / 2);
		  go_left(n);
	       }
	     
	  } while (ch == 'r');
	
	switch(ch)
	  { () == 'y' : replace_do_replace(rep, len) }
	  { () == 'n' : go_right(1);}
	  { () == '+' : replace_do_replace(rep, len);
	                return;
	  }
	  { () == '!' :
	     do 
	       {
		  replace_do_replace (rep, len);
	       }
	     while(search_across_lines(pat, 1));
	  }
          { () == 'q' : return; }
          {  pop();
	     flush ("y:replace, n:skip, !:replace all, +:replace then quit, q:quit");
	     input_pending (30); pop ();
	  }
     }
   message ("done.");
}

