diff --git a/lib/widget/wtools.h b/lib/widget/wtools.h index c2cbee12b6..510f3f51d3 100644 --- a/lib/widget/wtools.h +++ b/lib/widget/wtools.h @@ -84,9 +84,10 @@ gboolean mc_error_message (GError **mcerror, int *code); status_msg_t *status_msg_create (const char *title, double delay, status_msg_cb init_cb, status_msg_update_cb update_cb, status_msg_cb deinit_cb); void status_msg_destroy (status_msg_t *sm); -void status_msg_init (status_msg_t *sm, const char *title, double delay, status_msg_cb init_cb, - status_msg_update_cb update_cb, status_msg_cb deinit_cb); -void status_msg_deinit (status_msg_t *sm); +MC_MOCKABLE void status_msg_init (status_msg_t *sm, const char *title, double delay, + status_msg_cb init_cb, status_msg_update_cb update_cb, + status_msg_cb deinit_cb); +MC_MOCKABLE void status_msg_deinit (status_msg_t *sm); int status_msg_common_update (status_msg_t *sm); void simple_status_msg_init_cb (status_msg_t *sm); diff --git a/src/editor/editsearch.c b/src/editor/editsearch.c index 92f60bd0dc..2fdfe5fc36 100644 --- a/src/editor/editsearch.c +++ b/src/editor/editsearch.c @@ -47,29 +47,7 @@ /*** global variables ****************************************************************************/ -/*** file scope macro definitions ****************************************************************/ - -#define B_REPLACE_ALL (B_USER + 1) -#define B_REPLACE_ONE (B_USER + 2) -#define B_SKIP_REPLACE (B_USER + 3) - -/*** file scope type declarations ****************************************************************/ - -typedef struct edit_search_options_t -{ - mc_search_type_t type; - gboolean case_sens; - gboolean backwards; - gboolean only_in_selection; - gboolean whole_words; - gboolean all_codepages; -} edit_search_options_t; - -/*** forward declarations (file scope functions) *************************************************/ - -/*** file scope variables ************************************************************************/ - -static edit_search_options_t edit_search_options = { +edit_search_options_t edit_search_options = { .type = MC_SEARCH_T_NORMAL, .case_sens = FALSE, .backwards = FALSE, @@ -78,6 +56,21 @@ static edit_search_options_t edit_search_options = { .all_codepages = FALSE, }; +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** forward declarations (file scope functions) *************************************************/ + +MC_MOCKABLE void edit_dialog_replace_show (WEdit *edit, const char *search_default, + const char *replace_default, char **search_text, + char **replace_text); + +MC_MOCKABLE int edit_dialog_replace_prompt_show (WEdit *edit, char *from_text, char *to_text, + int xpos, int ypos); + +/*** file scope variables ************************************************************************/ + /* --------------------------------------------------------------------------------------------- */ /*** file scope functions ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ @@ -165,136 +158,6 @@ edit_dialog_search_show (WEdit *edit) /* --------------------------------------------------------------------------------------------- */ -static void -edit_dialog_replace_show (WEdit *edit, const char *search_default, const char *replace_default, - /*@out@ */ char **search_text, /*@out@ */ char **replace_text) -{ - size_t num_of_types = 0; - gchar **list_of_types; - - if ((search_default == NULL) || (*search_default == '\0')) - search_default = INPUT_LAST_TEXT; - - list_of_types = mc_search_get_types_strings_array (&num_of_types); - - { - quick_widget_t quick_widgets[] = { - // clang-format off - QUICK_LABELED_INPUT (N_ ("Enter search string:"), input_label_above, search_default, - MC_HISTORY_SHARED_SEARCH, search_text, NULL, FALSE, FALSE, - INPUT_COMPLETE_NONE), - QUICK_LABELED_INPUT (N_ ("Enter replacement string:"), input_label_above, - replace_default, "replace", replace_text, NULL, FALSE, FALSE, - INPUT_COMPLETE_NONE), - QUICK_SEPARATOR (TRUE), - QUICK_START_COLUMNS, - QUICK_RADIO (num_of_types, (const char **) list_of_types, - (int *) &edit_search_options.type, NULL), - QUICK_NEXT_COLUMN, - QUICK_CHECKBOX (N_ ("Cas&e sensitive"), &edit_search_options.case_sens, NULL), - QUICK_CHECKBOX (N_ ("&Backwards"), &edit_search_options.backwards, NULL), - QUICK_CHECKBOX (N_ ("In se&lection"), &edit_search_options.only_in_selection, NULL), - QUICK_CHECKBOX (N_ ("&Whole words"), &edit_search_options.whole_words, NULL), -#ifdef HAVE_CHARSET - QUICK_CHECKBOX (N_ ("&All charsets"), &edit_search_options.all_codepages, NULL), -#endif - QUICK_STOP_COLUMNS, - QUICK_BUTTONS_OK_CANCEL, - QUICK_END, - // clang-format on - }; - - WRect r = { -1, -1, 0, 58 }; - - quick_dialog_t qdlg = { - .rect = r, - .title = N_ ("Replace"), - .help = "[Input Line Keys]", - .widgets = quick_widgets, - .callback = NULL, - .mouse_callback = NULL, - }; - - if (quick_dialog (&qdlg) != B_CANCEL) - edit->replace_mode = 0; - else - { - *replace_text = NULL; - *search_text = NULL; - } - } - - g_strfreev (list_of_types); -} - -/* --------------------------------------------------------------------------------------------- */ - -static int -edit_dialog_replace_prompt_show (WEdit *edit, char *from_text, char *to_text, int xpos, int ypos) -{ - Widget *w = WIDGET (edit); - - // dialog size - int dlg_height = 10; - int dlg_width; - - char tmp[BUF_MEDIUM]; - char *repl_from, *repl_to; - int retval; - - if (xpos == -1) - xpos = w->rect.x + edit_options.line_state_width + 1; - if (ypos == -1) - ypos = w->rect.y + w->rect.lines / 2; - // Sometimes menu can hide replaced text. I don't like it - if ((edit->curs_row >= ypos - 1) && (edit->curs_row <= ypos + dlg_height - 1)) - ypos -= dlg_height; - - dlg_width = WIDGET (w->owner)->rect.cols - xpos - 1; - - g_snprintf (tmp, sizeof (tmp), "\"%s\"", from_text); - repl_from = g_strdup (str_trunc (tmp, dlg_width - 7)); - - g_snprintf (tmp, sizeof (tmp), "\"%s\"", to_text); - repl_to = g_strdup (str_trunc (tmp, dlg_width - 7)); - - { - quick_widget_t quick_widgets[] = { - // clang-format off - QUICK_LABEL (repl_from, NULL), - QUICK_LABEL (N_ ("Replace with:"), NULL), - QUICK_LABEL (repl_to, NULL), - QUICK_START_BUTTONS (TRUE, TRUE), - QUICK_BUTTON (N_ ("&Replace"), B_ENTER, NULL, NULL), - QUICK_BUTTON (N_ ("A&ll"), B_REPLACE_ALL, NULL, NULL), - QUICK_BUTTON (N_ ("&Skip"), B_SKIP_REPLACE, NULL, NULL), - QUICK_BUTTON (N_ ("&Cancel"), B_CANCEL, NULL, NULL), - QUICK_END, - // clang-format on - }; - - WRect r = { ypos, xpos, 0, -1 }; - - quick_dialog_t qdlg = { - .rect = r, - .title = N_ ("Confirm replace"), - .help = NULL, - .widgets = quick_widgets, - .callback = NULL, - .mouse_callback = NULL, - }; - - retval = quick_dialog (&qdlg); - } - - g_free (repl_from); - g_free (repl_to); - - return retval; -} - -/* --------------------------------------------------------------------------------------------- */ - /** * Get EOL symbol for searching. * @@ -824,6 +687,136 @@ edit_search_cmd (WEdit *edit, gboolean again) } } +/* --------------------------------------------------------------------------------------------- */ + +void +edit_dialog_replace_show (WEdit *edit, const char *search_default, const char *replace_default, + /*@out@ */ char **search_text, /*@out@ */ char **replace_text) +{ + size_t num_of_types = 0; + gchar **list_of_types; + + if ((search_default == NULL) || (*search_default == '\0')) + search_default = INPUT_LAST_TEXT; + + list_of_types = mc_search_get_types_strings_array (&num_of_types); + + { + quick_widget_t quick_widgets[] = { + // clang-format off + QUICK_LABELED_INPUT (N_ ("Enter search string:"), input_label_above, search_default, + MC_HISTORY_SHARED_SEARCH, search_text, NULL, FALSE, FALSE, + INPUT_COMPLETE_NONE), + QUICK_LABELED_INPUT (N_ ("Enter replacement string:"), input_label_above, + replace_default, "replace", replace_text, NULL, FALSE, FALSE, + INPUT_COMPLETE_NONE), + QUICK_SEPARATOR (TRUE), + QUICK_START_COLUMNS, + QUICK_RADIO (num_of_types, (const char **) list_of_types, + (int *) &edit_search_options.type, NULL), + QUICK_NEXT_COLUMN, + QUICK_CHECKBOX (N_ ("Cas&e sensitive"), &edit_search_options.case_sens, NULL), + QUICK_CHECKBOX (N_ ("&Backwards"), &edit_search_options.backwards, NULL), + QUICK_CHECKBOX (N_ ("In se&lection"), &edit_search_options.only_in_selection, NULL), + QUICK_CHECKBOX (N_ ("&Whole words"), &edit_search_options.whole_words, NULL), +#ifdef HAVE_CHARSET + QUICK_CHECKBOX (N_ ("&All charsets"), &edit_search_options.all_codepages, NULL), +#endif + QUICK_STOP_COLUMNS, + QUICK_BUTTONS_OK_CANCEL, + QUICK_END, + // clang-format on + }; + + WRect r = { -1, -1, 0, 58 }; + + quick_dialog_t qdlg = { + .rect = r, + .title = N_ ("Replace"), + .help = "[Input Line Keys]", + .widgets = quick_widgets, + .callback = NULL, + .mouse_callback = NULL, + }; + + if (quick_dialog (&qdlg) != B_CANCEL) + edit->replace_mode = 0; + else + { + *replace_text = NULL; + *search_text = NULL; + } + } + + g_strfreev (list_of_types); +} + +/* --------------------------------------------------------------------------------------------- */ + +int +edit_dialog_replace_prompt_show (WEdit *edit, char *from_text, char *to_text, int xpos, int ypos) +{ + Widget *w = WIDGET (edit); + + // dialog size + int dlg_height = 10; + int dlg_width; + + char tmp[BUF_MEDIUM]; + char *repl_from, *repl_to; + int retval; + + if (xpos == -1) + xpos = w->rect.x + edit_options.line_state_width + 1; + if (ypos == -1) + ypos = w->rect.y + w->rect.lines / 2; + // Sometimes menu can hide replaced text. I don't like it + if ((edit->curs_row >= ypos - 1) && (edit->curs_row <= ypos + dlg_height - 1)) + ypos -= dlg_height; + + dlg_width = WIDGET (w->owner)->rect.cols - xpos - 1; + + g_snprintf (tmp, sizeof (tmp), "\"%s\"", from_text); + repl_from = g_strdup (str_trunc (tmp, dlg_width - 7)); + + g_snprintf (tmp, sizeof (tmp), "\"%s\"", to_text); + repl_to = g_strdup (str_trunc (tmp, dlg_width - 7)); + + { + quick_widget_t quick_widgets[] = { + // clang-format off + QUICK_LABEL (repl_from, NULL), + QUICK_LABEL (N_ ("Replace with:"), NULL), + QUICK_LABEL (repl_to, NULL), + QUICK_START_BUTTONS (TRUE, TRUE), + QUICK_BUTTON (N_ ("&Replace"), B_ENTER, NULL, NULL), + QUICK_BUTTON (N_ ("A&ll"), B_REPLACE_ALL, NULL, NULL), + QUICK_BUTTON (N_ ("&Skip"), B_SKIP_REPLACE, NULL, NULL), + QUICK_BUTTON (N_ ("&Cancel"), B_CANCEL, NULL, NULL), + QUICK_END, + // clang-format on + }; + + WRect r = { ypos, xpos, 0, -1 }; + + quick_dialog_t qdlg = { + .rect = r, + .title = N_ ("Confirm replace"), + .help = NULL, + .widgets = quick_widgets, + .callback = NULL, + .mouse_callback = NULL, + }; + + retval = quick_dialog (&qdlg); + } + + g_free (repl_from); + g_free (repl_to); + + return retval; +} + /* --------------------------------------------------------------------------------------------- */ /** call with edit = 0 before shutdown to close memory leaks */ diff --git a/src/editor/editsearch.h b/src/editor/editsearch.h index f0947305df..08b23989da 100644 --- a/src/editor/editsearch.h +++ b/src/editor/editsearch.h @@ -3,10 +3,24 @@ /*** typedefs(not structures) and defined constants **********************************************/ +#define B_REPLACE_ALL (B_USER + 1) +#define B_REPLACE_ONE (B_USER + 2) +#define B_SKIP_REPLACE (B_USER + 3) + /*** enums ***************************************************************************************/ /*** structures declarations (and typedefs of structures)*****************************************/ +typedef struct edit_search_options_t +{ + mc_search_type_t type; + gboolean case_sens; + gboolean backwards; + gboolean only_in_selection; + gboolean whole_words; + gboolean all_codepages; +} edit_search_options_t; + typedef struct { simple_status_msg_t status_msg; // base class @@ -18,6 +32,8 @@ typedef struct /*** global variables defined in .c file *********************************************************/ +extern edit_search_options_t edit_search_options; + /*** declarations of public functions ************************************************************/ gboolean edit_search_init (WEdit *edit, const char *s); @@ -25,7 +41,8 @@ void edit_search_deinit (WEdit *edit); mc_search_cbret_t edit_search_cmd_callback (const void *user_data, off_t char_offset, int *current_char); -mc_search_cbret_t edit_search_update_callback (const void *user_data, off_t char_offset); +MC_MOCKABLE mc_search_cbret_t edit_search_update_callback (const void *user_data, + off_t char_offset); int edit_search_status_update_cb (status_msg_t *sm); void edit_search_cmd (WEdit *edit, gboolean again); diff --git a/src/setup.c b/src/setup.c index 52ae46293e..de95714dcc 100644 --- a/src/setup.c +++ b/src/setup.c @@ -211,7 +211,7 @@ int macro_index = -1; /* macro stuff */ struct macro_action_t record_macro_buf[MAX_MACRO_LENGTH]; -GArray *macros_list; +GArray *macros_list = NULL; #endif /*** file scope macro definitions ****************************************************************/ diff --git a/tests/src/editor/Makefile.am b/tests/src/editor/Makefile.am index 0f50e4400d..69d59c69c1 100644 --- a/tests/src/editor/Makefile.am +++ b/tests/src/editor/Makefile.am @@ -17,10 +17,14 @@ endif EXTRA_DIST = mc.charsets test-data.txt.in TESTS = \ - edit_complete_word_cmd + edit_complete_word_cmd \ + edit_replace_cmd check_PROGRAMS = $(TESTS) edit_complete_word_cmd_SOURCES = \ edit_complete_word_cmd.c +edit_replace_cmd_SOURCES = \ + edit_replace_cmd.c + diff --git a/tests/src/editor/edit_replace_cmd.c b/tests/src/editor/edit_replace_cmd.c new file mode 100644 index 0000000000..83f1c53232 --- /dev/null +++ b/tests/src/editor/edit_replace_cmd.c @@ -0,0 +1,356 @@ +/* + src/editor - tests for edit_replace_cmd() function + + Copyright (C) 2025 + Free Software Foundation, Inc. + + Written by: + Andrew Borodin , 2025 + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#define TEST_SUITE_NAME "/src/editor" + +#include "tests/mctest.h" + +#include + +#ifdef HAVE_CHARSET +# include "lib/charsets.h" +# include "src/selcodepage.h" +#endif +#include "src/editor/editwidget.h" +#include "src/editor/editmacros.h" // edit_load_macro_cmd() +#include "src/editor/editsearch.h" + +static WGroup owner; +static WEdit *test_edit; +static gboolean only_in_selection = FALSE; + +static const char *test_regex_in = "qwe\n" // + "qwe\n" // + "qwe\n" // + "qwe\n" // + "qwe\n" // + "qwe\n" // + "qwe\n" // + "qwe\n"; // +static const char *test_regex_out = "Xqwe\n" // + "Xqwe\n" // + "Xqwe\n" // + "Xqwe\n" // + "Xqwe\n" // + "Xqwe\n" // + "Xqwe\n" // + "Xqwe\n"; // + +static const char *test_regex_selected_in = "qwe\n" // + "qwe\n" // + "qwe\n" // selected, mark1 = 8 (begin of line) or 9 + "qwe\n" // selected + "qwe\n" // selected + "qwe\n" // mark2 = 20, begin of line + "qwe\n" // + "qwe\n"; // +static const char *test1_regex_selected_out = "qwe\n" // + "qwe\n" // + "Xqwe\n" // selected, mark1 = 8 (begin of line) + "Xqwe\n" // selected + "Xqwe\n" // selected + "qwe\n" // mark2 = 20, begin of line + "qwe\n" // + "qwe\n"; // +static const char *test2_regex_selected_out = "qwe\n" // + "qwe\n" // + "qwe\n" // selected, mark1 = 9 (not begin of line) + "Xqwe\n" // selected + "Xqwe\n" // selected + "qwe\n" // mark2 = 20, begin of line + "qwe\n" // + "qwe\n"; // + +static const char *replace_regex_from = "^.*"; +static const char *replace_regex_to = "X\\0"; + +/* --------------------------------------------------------------------------------------------- */ + +void edit_dialog_replace_show (WEdit *edit, const char *search_default, const char *replace_default, + char **search_text, char **replace_text); +int edit_dialog_replace_prompt_show (WEdit *edit, char *from_text, char *to_text, int xpos, + int ypos); + +/* --------------------------------------------------------------------------------------------- */ +/* @Mock */ +void +message (int flags, const char *title, const char *text, ...) +{ + (void) flags; + (void) title; + (void) text; +} + +/* --------------------------------------------------------------------------------------------- */ +/* @Mock */ +void +status_msg_init (status_msg_t *sm, const char *title, double delay, status_msg_cb init_cb, + status_msg_update_cb update_cb, status_msg_cb deinit_cb) +{ + (void) sm; + (void) title; + (void) delay; + (void) init_cb; + (void) update_cb; + (void) deinit_cb; +} + +/* --------------------------------------------------------------------------------------------- */ +/* @Mock */ +void +status_msg_deinit (status_msg_t *sm) +{ + (void) sm; +} + +/* --------------------------------------------------------------------------------------------- */ +/* @Mock */ +mc_search_cbret_t +edit_search_update_callback (const void *user_data, off_t char_offset) +{ + (void) user_data; + (void) char_offset; + + return MC_SEARCH_CB_OK; +} + +/* --------------------------------------------------------------------------------------------- */ +/* @Mock */ +void +edit_dialog_replace_show (WEdit *edit, const char *search_default, const char *replace_default, + char **search_text, char **replace_text) +{ + (void) edit; + (void) search_default; + (void) replace_default; + + *search_text = g_strdup (replace_regex_from); + *replace_text = g_strdup (replace_regex_to); + + edit_search_options.type = MC_SEARCH_T_REGEX; + edit_search_options.only_in_selection = only_in_selection; +} + +/* --------------------------------------------------------------------------------------------- */ +/* @Mock */ +int +edit_dialog_replace_prompt_show (WEdit *edit, char *from_text, char *to_text, int xpos, int ypos) +{ + (void) edit; + (void) from_text; + (void) to_text; + (void) xpos; + (void) ypos; + + return B_REPLACE_ALL; +} + +/* --------------------------------------------------------------------------------------------- */ +/* @Mock */ +void +edit_load_syntax (WEdit *edit, GPtrArray *pnames, const char *type) +{ + (void) edit; + (void) pnames; + (void) type; +} + +/* --------------------------------------------------------------------------------------------- */ + +/* @Mock */ +int +edit_get_syntax_color (WEdit *edit, off_t byte_index) +{ + (void) edit; + (void) byte_index; + + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +/* @Mock */ +gboolean +edit_load_macro_cmd (WEdit *edit) +{ + (void) edit; + + return FALSE; +} + +/* --------------------------------------------------------------------------------------------- */ + +/* @Before */ +static void +setup (void) +{ + WRect r; + + str_init_strings (NULL); + +#ifdef HAVE_CHARSET + mc_global.sysconfig_dir = (char *) TEST_SHARE_DIR; + load_codepages_list (); +#endif + + edit_options.filesize_threshold = (char *) "64M"; + + rect_init (&r, 0, 0, 24, 80); + test_edit = edit_init (NULL, &r, NULL); + memset (&owner, 0, sizeof (owner)); + group_add_widget (&owner, WIDGET (test_edit)); + + mc_global.source_codepage = 0; + mc_global.display_codepage = 0; +#ifdef HAVE_CHARSET + cp_source = "ASCII"; + cp_display = "ASCII"; +#endif + + do_set_codepage (0); + edit_set_codeset (test_edit); +} + +/* --------------------------------------------------------------------------------------------- */ + +/* @After */ +static void +teardown (void) +{ + edit_clean (test_edit); + group_remove_widget (test_edit); + g_free (test_edit); + +#ifdef HAVE_CHARSET + free_codepages_list (); +#endif + + str_uninit_strings (); +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +test_replace_check (const char *test_out) +{ + GString *actual_replaced_str; + + actual_replaced_str = g_string_new (""); + + for (off_t i = 0; i < test_edit->buffer.size; i++) + { + const int chr = edit_buffer_get_byte (&test_edit->buffer, i); + + g_string_append_c (actual_replaced_str, chr); + } + + mctest_assert_str_eq (actual_replaced_str->str, test_out); + g_string_free (actual_replaced_str, TRUE); +} + +/* --------------------------------------------------------------------------------------------- */ + +START_TEST (test_replace_regex) +{ + // given + only_in_selection = FALSE; + test_edit->mark1 = 0; + test_edit->mark2 = 0; + + for (const char *ti = test_regex_in; *ti != '\0'; ti++) + edit_buffer_insert (&test_edit->buffer, *ti); + + // when + edit_cursor_move (test_edit, 0); + edit_replace_cmd (test_edit, FALSE); + + // then + test_replace_check (test_regex_out); +} +END_TEST + +/* --------------------------------------------------------------------------------------------- */ + +START_TEST (test1_replace_regex_in_selection) +{ + // given + only_in_selection = TRUE; + test_edit->mark1 = 8; + test_edit->mark2 = 20; + + for (const char *ti = test_regex_selected_in; *ti != '\0'; ti++) + edit_buffer_insert (&test_edit->buffer, *ti); + + // when + edit_cursor_move (test_edit, 0); + edit_replace_cmd (test_edit, FALSE); + + // then + test_replace_check (test1_regex_selected_out); +} +END_TEST + +/* --------------------------------------------------------------------------------------------- */ + +START_TEST (test2_replace_regex_in_selection) +{ + // given + only_in_selection = TRUE; + test_edit->mark1 = 9; + test_edit->mark2 = 20; + + for (const char *ti = test_regex_selected_in; *ti != '\0'; ti++) + edit_buffer_insert (&test_edit->buffer, *ti); + + // when + edit_cursor_move (test_edit, 0); + edit_replace_cmd (test_edit, FALSE); + + // then + test_replace_check (test2_regex_selected_out); +} +END_TEST + +/* --------------------------------------------------------------------------------------------- */ + +int +main (void) +{ + TCase *tc_core; + + tc_core = tcase_create ("Core"); + + tcase_add_checked_fixture (tc_core, setup, teardown); + + // Add new tests here: *************** + tcase_add_test (tc_core, test_replace_regex); + tcase_add_test (tc_core, test1_replace_regex_in_selection); + tcase_add_test (tc_core, test2_replace_regex_in_selection); + // *********************************** + + return mctest_run_all (tc_core); +} + +/* --------------------------------------------------------------------------------------------- */ diff --git a/tests/src/editor/mc.charsets b/tests/src/editor/mc.charsets index 7b27d61824..dc442ab7ef 100644 --- a/tests/src/editor/mc.charsets +++ b/tests/src/editor/mc.charsets @@ -1,2 +1,3 @@ +ASCII 7-bit ASCII KOI8-R KOI8-R UTF-8 UTF-8