1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
% These routines are common to both regular expression searches and ordinary
% searches.
define mark_next_nchars (n, dir)
{
variable h;
ERROR_BLOCK
{
set_line_hidden (h); pop_mark_0 ();
}
h = is_line_hidden ();
set_line_hidden (0);
push_visible_mark ();
go_right (n);
if (dir < 0) exchange_point_and_mark ();
update(1);
ungetkey(getkey());
EXECUTE_ERROR_BLOCK;
}
% The search function is to return: 0 if non-match found or the length of the
% item matched.
% search_fun takes the pattern to search for and returns the length of the
% pattern matched. If no match occurs, return -1.
% rep_fun returns the length of characters replaced.
define replace_with_query (search_fun, pat, rep, query, rep_fun)
{
variable n, prompt, doit, err, ch, pat_len;
variable undo_stack_type = struct
{
rep_len,
prev_string,
user_mark,
next
};
variable undo_stack = NULL;
variable tmp;
variable replacement_length = strlen (rep);
prompt = sprintf ("Replace '%s' with '%s'? (y/n/!/+/q/h)", pat, rep);
while (pat_len = @search_fun (pat), pat_len >= 0)
{
!if (query)
{
tmp = create_user_mark ();
() = @rep_fun (rep, pat_len);
if ((pat_len == 0)
and (tmp == create_user_mark ()))
go_right_1 ();
continue;
}
do
{
message(prompt);
mark_next_nchars (pat_len, -1);
ch = getkey ();
if (ch == 'r')
{
recenter (window_info('r') / 2);
}
} while (ch == 'r');
switch(ch)
{ case 'u' and (undo_stack != NULL) :
goto_user_mark (undo_stack.user_mark);
push_spot ();
() = @rep_fun (undo_stack.prev_string, undo_stack.rep_len);
pop_spot ();
undo_stack = undo_stack.next;
}
{ case 'y' :
tmp = @undo_stack_type;
tmp.next = undo_stack;
undo_stack = tmp;
push_spot(); push_mark ();
go_right (pat_len); undo_stack.prev_string = bufsubstr ();
pop_spot ();
undo_stack.user_mark = create_user_mark ();
undo_stack.rep_len = @rep_fun (rep, pat_len);
}
{ case 'n' : go_right_1 ();}
{ case '+' : () = @rep_fun (rep, pat_len);
break;
}
{ case '!' :
query = 0;
}
{ case 'q' : break; }
{
flush ("y:replace, n:skip, !:replace all, u: undo last, +:replace then quit, q:quit");
() = input_pending (30);
}
}
}
define search_maybe_again (fun, str, dir, match_ok_fun)
{
variable ch, len;
while (len = @fun (str, dir), len >= 0)
{
if (@match_ok_fun ())
{
if (EXECUTING_MACRO or DEFINING_MACRO) return 1;
message ("Press RET to continue searching.");
mark_next_nchars (len, -1);
ch = getkey ();
if (ch != '\r')
{
ungetkey (ch);
return 1;
}
}
if (dir > 0) go_right_1 ();
}
return 0;
}
provide ("srchmisc");
|