Skip to content

Commit 1c32c69

Browse files
committed
Merge branch '4751_mcedit_replace_eol_in_last_line'
* 4751_mcedit_replace_eol_in_last_line: tests/editor: improve regex replacement tests. (edit_find): reduce variable scope. Ticket #4751: mcedit: fix regex replacement in selection.
2 parents 5c0833b + 094e935 commit 1c32c69

File tree

2 files changed

+205
-62
lines changed

2 files changed

+205
-62
lines changed

src/editor/editsearch.c

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -276,19 +276,8 @@ edit_search_fix_search_start_if_selection (WEdit *edit)
276276
if (!edit_search_options.only_in_selection)
277277
return;
278278

279-
if (!eval_marks (edit, &start_mark, &end_mark))
280-
return;
281-
282-
if (edit_search_options.backwards)
283-
{
284-
if (edit->search_start > end_mark || edit->search_start <= start_mark)
285-
edit->search_start = end_mark;
286-
}
287-
else
288-
{
289-
if (edit->search_start < start_mark || edit->search_start >= end_mark)
290-
edit->search_start = start_mark;
291-
}
279+
if (eval_marks (edit, &start_mark, &end_mark))
280+
edit->search_start = edit_search_options.backwards ? end_mark : start_mark;
292281
}
293282

294283
/* --------------------------------------------------------------------------------------------- */
@@ -299,7 +288,6 @@ edit_find (edit_search_status_msg_t *esm, gsize *len)
299288
WEdit *edit = esm->edit;
300289
edit_buffer_t *buf = &edit->buffer;
301290
off_t search_start = edit->search_start;
302-
off_t search_end;
303291
off_t start_mark = 0;
304292
off_t end_mark = buf->size;
305293
gboolean start_from_next_line = FALSE;
@@ -323,20 +311,15 @@ edit_find (edit_search_status_msg_t *esm, gsize *len)
323311
const off_t bol =
324312
edit_calculate_start_of_current_line (buf, search_start, end_string_symbol);
325313

326-
if (search_start != bol)
327-
{
328-
start_mark = edit_calculate_start_of_next_line (buf, start_mark, buf->size,
329-
end_string_symbol);
330-
start_from_next_line = TRUE;
331-
}
314+
start_from_next_line = search_start != bol;
332315
}
333316

334317
if ((edit->search_line_type & MC_SEARCH_LINE_END) != 0
335318
&& (end_mark - 1 != buf->size
336319
|| edit_buffer_get_byte (buf, end_mark) != end_string_symbol))
337320
end_mark = edit_calculate_end_of_previous_line (buf, end_mark, end_string_symbol);
338321

339-
if (start_mark >= end_mark)
322+
if (search_start >= end_mark)
340323
{
341324
mc_search_set_error (edit->search, MC_SEARCH_E_NOTFOUND, "%s", _ (STR_E_NOTFOUND));
342325
return FALSE;
@@ -357,7 +340,8 @@ edit_find (edit_search_status_msg_t *esm, gsize *len)
357340
if (edit_search_options.backwards)
358341
{
359342
// backward search
360-
search_end = end_mark;
343+
344+
off_t search_end = end_mark;
361345

362346
if ((edit->search_line_type & MC_SEARCH_LINE_BEGIN) != 0)
363347
search_start =
@@ -396,12 +380,29 @@ edit_find (edit_search_status_msg_t *esm, gsize *len)
396380

397381
// correct end_mark if cursor is in column 0: move end_mark to the end of previous line
398382
if (end_mark == edit_calculate_start_of_current_line (buf, end_mark, end_string_symbol))
383+
{
399384
end_mark = edit_calculate_end_of_previous_line (buf, end_mark, end_string_symbol);
400385

386+
// update bottom marker
387+
if (edit->mark2 >= 0 && edit->mark2 != edit->mark1)
388+
{
389+
if (edit->mark2 > edit->mark1)
390+
edit->mark2 = end_mark;
391+
else
392+
edit->mark1 = end_mark;
393+
}
394+
}
395+
401396
if (start_from_next_line)
402397
search_start =
403398
edit_calculate_start_of_next_line (buf, search_start, end_mark, end_string_symbol);
404399

400+
if (search_start >= end_mark)
401+
{
402+
mc_search_set_error (edit->search, MC_SEARCH_E_NOTFOUND, "%s", _ (STR_E_NOTFOUND));
403+
return FALSE;
404+
}
405+
405406
return mc_search_run (edit->search, (void *) esm, search_start, end_mark, len);
406407
}
407408

tests/src/editor/edit_replace_cmd.c

Lines changed: 182 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -38,52 +38,85 @@
3838

3939
static WGroup owner;
4040
static WEdit *test_edit;
41+
static const char **replace_regex__from;
42+
static const char **replace_regex__to;
4143
static gboolean only_in_selection = FALSE;
4244

43-
static const char *test_regex_in = "qwe\n" //
44-
"qwe\n" //
45-
"qwe\n" //
46-
"qwe\n" //
47-
"qwe\n" //
48-
"qwe\n" //
49-
"qwe\n" //
50-
"qwe\n"; //
51-
static const char *test_regex_out = "Xqwe\n" //
52-
"Xqwe\n" //
53-
"Xqwe\n" //
54-
"Xqwe\n" //
55-
"Xqwe\n" //
56-
"Xqwe\n" //
57-
"Xqwe\n" //
58-
"Xqwe\n"; //
59-
60-
static const char *test_regex_selected_in = "qwe\n" //
61-
"qwe\n" //
62-
"qwe\n" // selected, mark1 = 8 (begin of line) or 9
63-
"qwe\n" // selected
64-
"qwe\n" // selected
65-
"qwe\n" // mark2 = 20, begin of line
66-
"qwe\n" //
67-
"qwe\n"; //
45+
// input text: entire text
46+
static const char *test_regex_in = "qwe\n" //
47+
"qwe\n" //
48+
"qwe\n" //
49+
"qwe\n" //
50+
"qwe\n" //
51+
"qwe\n" //
52+
"qwe\n" //
53+
"qwe\n"; //
54+
55+
// insert char at begin of string:
56+
// s/^.*/X\\0
57+
// s/^/X
58+
// not in selection
59+
static const char *test_regex_out1 = "Xqwe\n" //
60+
"Xqwe\n" //
61+
"Xqwe\n" //
62+
"Xqwe\n" //
63+
"Xqwe\n" //
64+
"Xqwe\n" //
65+
"Xqwe\n" //
66+
"Xqwe\n"; //
67+
68+
// replace first char of string:
69+
// s/^./X
70+
// not in selection
71+
static const char *test_regex_out2 = "Xwe\n" //
72+
"Xwe\n" //
73+
"Xwe\n" //
74+
"Xwe\n" //
75+
"Xwe\n" //
76+
"Xwe\n" //
77+
"Xwe\n" //
78+
"Xwe\n"; //
79+
80+
// input text: selected
81+
static const char *test_regex_selected_in = "qwe\n" //
82+
"qwe\n" //
83+
"qwe\n" // selected, mark1 = 8 (begin of string) or 9
84+
"qwe\n" // selected
85+
"qwe\n" // selected
86+
"qwe\n" // mark2 = 20, begin of string
87+
"qwe\n" //
88+
"qwe\n"; //
89+
90+
// insert char at begin of string:
91+
// s/^.*/X\\0
92+
// in selection from begin of string
6893
static const char *test1_regex_selected_out = "qwe\n" //
6994
"qwe\n" //
70-
"Xqwe\n" // selected, mark1 = 8 (begin of line)
95+
"Xqwe\n" // selected, mark1 = 8 (begin of string)
7196
"Xqwe\n" // selected
7297
"Xqwe\n" // selected
73-
"qwe\n" // mark2 = 20, begin of line
98+
"qwe\n" // mark2 = 20, begin of string
7499
"qwe\n" //
75100
"qwe\n"; //
101+
102+
// insert char at begin of string:
103+
// s/^.*/X\\0
104+
// in selection not from begin of string
76105
static const char *test2_regex_selected_out = "qwe\n" //
77106
"qwe\n" //
78-
"qwe\n" // selected, mark1 = 9 (not begin of line)
107+
"qwe\n" // selected, mark1 = 9 (not begin of string)
79108
"Xqwe\n" // selected
80109
"Xqwe\n" // selected
81-
"qwe\n" // mark2 = 20, begin of line
110+
"qwe\n" // mark2 = 20, begin of string
82111
"qwe\n" //
83112
"qwe\n"; //
84113

85-
static const char *replace_regex_from = "^.*";
86-
static const char *replace_regex_to = "X\\0";
114+
static const char *replace_regex_entire_string__from = "^.*";
115+
static const char *replace_regex_entire_string__to = "X\\0";
116+
117+
static const char *replace_regex_insert_char_at_begin_of_string__from = "^";
118+
static const char *replace_regex_replace_first_char_of_string__from = "^.";
119+
static const char *replace_regex_begin_of_string__to = "X";
87120

88121
/* --------------------------------------------------------------------------------------------- */
89122

@@ -145,8 +178,8 @@ edit_dialog_replace_show (WEdit *edit, const char *search_default, const char *r
145178
(void) search_default;
146179
(void) replace_default;
147180

148-
*search_text = g_strdup (replace_regex_from);
149-
*replace_text = g_strdup (replace_regex_to);
181+
*search_text = g_strdup (*replace_regex__from);
182+
*replace_text = g_strdup (*replace_regex__to);
150183

151184
edit_search_options.type = MC_SEARCH_T_REGEX;
152185
edit_search_options.only_in_selection = only_in_selection;
@@ -264,10 +297,61 @@ test_replace_check (const char *test_out)
264297

265298
/* --------------------------------------------------------------------------------------------- */
266299

267-
START_TEST (test_replace_regex)
300+
// replace entire string
301+
START_TEST (test_replace_regex__entire_string)
302+
{
303+
// given
304+
only_in_selection = FALSE;
305+
replace_regex__from = &replace_regex_entire_string__from;
306+
replace_regex__to = &replace_regex_entire_string__to;
307+
test_edit->mark1 = 0;
308+
test_edit->mark2 = 0;
309+
310+
for (const char *ti = test_regex_in; *ti != '\0'; ti++)
311+
edit_buffer_insert (&test_edit->buffer, *ti);
312+
313+
// when
314+
edit_cursor_move (test_edit, 0);
315+
edit_replace_cmd (test_edit, FALSE);
316+
317+
// then
318+
test_replace_check (test_regex_out1);
319+
}
320+
END_TEST
321+
322+
/* --------------------------------------------------------------------------------------------- */
323+
324+
// insert first char in string
325+
START_TEST (test_replace_regex__insert_char_at_begin_of_string)
326+
{
327+
// given
328+
only_in_selection = FALSE;
329+
replace_regex__from = &replace_regex_insert_char_at_begin_of_string__from;
330+
replace_regex__to = &replace_regex_begin_of_string__to;
331+
test_edit->mark1 = 0;
332+
test_edit->mark2 = 0;
333+
334+
for (const char *ti = test_regex_in; *ti != '\0'; ti++)
335+
edit_buffer_insert (&test_edit->buffer, *ti);
336+
337+
// when
338+
edit_cursor_move (test_edit, 0);
339+
edit_replace_cmd (test_edit, FALSE);
340+
341+
// then
342+
test_replace_check (test_regex_out1);
343+
}
344+
END_TEST
345+
346+
/* --------------------------------------------------------------------------------------------- */
347+
348+
// replace first char of string
349+
START_TEST (test_replace_regex__replace_first_char_of_string)
268350
{
269351
// given
270352
only_in_selection = FALSE;
353+
replace_regex__from = &replace_regex_replace_first_char_of_string__from;
354+
replace_regex__to = &replace_regex_begin_of_string__to;
271355
test_edit->mark1 = 0;
272356
test_edit->mark2 = 0;
273357

@@ -279,16 +363,19 @@ START_TEST (test_replace_regex)
279363
edit_replace_cmd (test_edit, FALSE);
280364

281365
// then
282-
test_replace_check (test_regex_out);
366+
test_replace_check (test_regex_out2);
283367
}
284368
END_TEST
285369

286370
/* --------------------------------------------------------------------------------------------- */
287371

288-
START_TEST (test1_replace_regex_in_selection)
372+
// replace from begin of string in selection
373+
START_TEST (test_replace_regex__in_selection_top_down_1)
289374
{
290375
// given
291376
only_in_selection = TRUE;
377+
replace_regex__from = &replace_regex_entire_string__from;
378+
replace_regex__to = &replace_regex_entire_string__to;
292379
test_edit->mark1 = 8;
293380
test_edit->mark2 = 20;
294381

@@ -306,10 +393,13 @@ END_TEST
306393

307394
/* --------------------------------------------------------------------------------------------- */
308395

309-
START_TEST (test2_replace_regex_in_selection)
396+
// replace not from begin of string in selection
397+
START_TEST (test_replace_regex__in_selection_top_down_2)
310398
{
311399
// given
312400
only_in_selection = TRUE;
401+
replace_regex__from = &replace_regex_entire_string__from;
402+
replace_regex__to = &replace_regex_entire_string__to;
313403
test_edit->mark1 = 9;
314404
test_edit->mark2 = 20;
315405

@@ -327,6 +417,54 @@ END_TEST
327417

328418
/* --------------------------------------------------------------------------------------------- */
329419

420+
// replace from begin of string in selection
421+
START_TEST (test_replace_regex__in_selection_bottom_up_1)
422+
{
423+
// given
424+
only_in_selection = TRUE;
425+
replace_regex__from = &replace_regex_entire_string__from;
426+
replace_regex__to = &replace_regex_entire_string__to;
427+
test_edit->mark1 = 20;
428+
test_edit->mark2 = 8;
429+
430+
for (const char *ti = test_regex_selected_in; *ti != '\0'; ti++)
431+
edit_buffer_insert (&test_edit->buffer, *ti);
432+
433+
// when
434+
edit_cursor_move (test_edit, 0);
435+
edit_replace_cmd (test_edit, FALSE);
436+
437+
// then
438+
test_replace_check (test1_regex_selected_out);
439+
}
440+
END_TEST
441+
442+
/* --------------------------------------------------------------------------------------------- */
443+
444+
// replace not from begin of string in selection
445+
START_TEST (test_replace_regex__in_selection_bottom_up_2)
446+
{
447+
// given
448+
only_in_selection = TRUE;
449+
replace_regex__from = &replace_regex_entire_string__from;
450+
replace_regex__to = &replace_regex_entire_string__to;
451+
test_edit->mark1 = 20;
452+
test_edit->mark2 = 9;
453+
454+
for (const char *ti = test_regex_selected_in; *ti != '\0'; ti++)
455+
edit_buffer_insert (&test_edit->buffer, *ti);
456+
457+
// when
458+
edit_cursor_move (test_edit, 0);
459+
edit_replace_cmd (test_edit, FALSE);
460+
461+
// then
462+
test_replace_check (test2_regex_selected_out);
463+
}
464+
END_TEST
465+
466+
/* --------------------------------------------------------------------------------------------- */
467+
330468
int
331469
main (void)
332470
{
@@ -337,9 +475,13 @@ main (void)
337475
tcase_add_checked_fixture (tc_core, setup, teardown);
338476

339477
// Add new tests here: ***************
340-
tcase_add_test (tc_core, test_replace_regex);
341-
tcase_add_test (tc_core, test1_replace_regex_in_selection);
342-
tcase_add_test (tc_core, test2_replace_regex_in_selection);
478+
tcase_add_test (tc_core, test_replace_regex__entire_string);
479+
tcase_add_test (tc_core, test_replace_regex__insert_char_at_begin_of_string);
480+
tcase_add_test (tc_core, test_replace_regex__replace_first_char_of_string);
481+
tcase_add_test (tc_core, test_replace_regex__in_selection_top_down_1);
482+
tcase_add_test (tc_core, test_replace_regex__in_selection_top_down_2);
483+
tcase_add_test (tc_core, test_replace_regex__in_selection_bottom_up_1);
484+
tcase_add_test (tc_core, test_replace_regex__in_selection_bottom_up_2);
343485
// ***********************************
344486

345487
return mctest_run_all (tc_core);

0 commit comments

Comments
 (0)