diff --git a/src/editor/Makefile.am b/src/editor/Makefile.am index dc1dd56aa..9999dad81 100644 --- a/src/editor/Makefile.am +++ b/src/editor/Makefile.am @@ -18,6 +18,7 @@ libedit_la_SOURCES = \ editmenu.c \ editoptions.c \ editwidget.c editwidget.h \ + event.c event.h \ etags.c etags.h \ format.c \ macro.c macro.h \ @@ -27,6 +28,7 @@ if USE_ASPELL if HAVE_GMODULE libedit_la_SOURCES += \ spell.c spell.h \ + spell_cmd.c \ spell_dialogs.c spell_dialogs.h endif endif diff --git a/src/editor/choosesyntax.c b/src/editor/choosesyntax.c index af62818c9..80b9197bb 100644 --- a/src/editor/choosesyntax.c +++ b/src/editor/choosesyntax.c @@ -42,6 +42,7 @@ #include "edit-impl.h" #include "editwidget.h" +#include "event.h" /*** global variables ****************************************************************************/ @@ -93,12 +94,18 @@ exec_edit_syntax_dialog (const GPtrArray * names, const char *current_syntax) /* --------------------------------------------------------------------------------------------- */ /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -void -edit_syntax_dialog (WEdit * edit) +gboolean +mc_editor_cmd_syntax_show_dialog (event_info_t * event_info, gpointer data, GError ** error) { GPtrArray *names; int syntax; + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + names = g_ptr_array_new (); @@ -143,6 +150,8 @@ edit_syntax_dialog (WEdit * edit) g_ptr_array_foreach (names, (GFunc) g_free, NULL); g_ptr_array_free (names, TRUE); + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ diff --git a/src/editor/edit-impl.h b/src/editor/edit-impl.h index 50ad4e779..5a5d4a125 100644 --- a/src/editor/edit-impl.h +++ b/src/editor/edit-impl.h @@ -115,6 +115,7 @@ typedef struct edit_stack_type struct Widget; struct WMenuBar; +struct edit_buffer_struct; /*** global variables defined in .c file *********************************************************/ @@ -150,7 +151,7 @@ WEdit *find_editor (const WDialog * h); gboolean edit_widget_is_editor (const Widget * w); gboolean edit_drop_hotkey_menu (WDialog * h, int key); void edit_menu_cmd (WDialog * h); -void user_menu (WEdit * edit, const char *menu_file, int selected_entry); +void mc_editor_call_event_user_menu (WEdit * edit, const char *menu_file, int selected_entry); void edit_init_menu (struct WMenuBar *menubar); void edit_save_mode_cmd (void); off_t edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto); @@ -170,10 +171,7 @@ void edit_find_bracket (WEdit * edit); gboolean edit_reload_line (WEdit * edit, const vfs_path_t * filename_vpath, long line); void edit_set_codeset (WEdit * edit); -void edit_block_copy_cmd (WEdit * edit); -void edit_block_move_cmd (WEdit * edit); -int edit_block_delete_cmd (WEdit * edit); -void edit_delete_line (WEdit * edit); +int mc_editor_call_event_block_delete (WEdit * edit); int edit_delete (WEdit * edit, gboolean byte_delete); int edit_backspace (WEdit * edit, gboolean byte_delete); @@ -187,8 +185,7 @@ void edit_insert_ahead (WEdit * edit, int c); off_t edit_write_stream (WEdit * edit, FILE * f); char *edit_get_write_filter (const vfs_path_t * write_name_vpath, const vfs_path_t * filename_vpath); -gboolean edit_save_confirm_cmd (WEdit * edit); -gboolean edit_save_as_cmd (WEdit * edit); +gboolean mc_editor_call_event_save_as (WEdit * edit); WEdit *edit_init (WEdit * edit, int y, int x, int lines, int cols, const vfs_path_t * filename_vpath, long line); gboolean edit_clean (WEdit * edit); @@ -202,28 +199,15 @@ void edit_mark_current_word_cmd (WEdit * edit); void edit_mark_current_line_cmd (WEdit * edit); void edit_set_markers (WEdit * edit, off_t m1, off_t m2, long c1, long c2); void edit_push_markers (WEdit * edit); -void edit_replace_cmd (WEdit * edit, int again); -void edit_search_cmd (WEdit * edit, gboolean again); mc_search_cbret_t edit_search_cmd_callback (const void *user_data, gsize char_offset, int *current_char); mc_search_cbret_t edit_search_update_callback (const void *user_data, gsize char_offset); void edit_complete_word_cmd (WEdit * edit); -void edit_get_match_keyword_cmd (WEdit * edit); - -#ifdef HAVE_ASPELL -int edit_suggest_current_word (WEdit * edit); -void edit_spellcheck_file (WEdit * edit); -void edit_set_spell_lang (void); -#endif gboolean edit_save_block (WEdit * edit, const char *filename, off_t start, off_t finish); -gboolean edit_save_block_cmd (WEdit * edit); -gboolean edit_insert_file_cmd (WEdit * edit); off_t edit_insert_file (WEdit * edit, const vfs_path_t * filename_vpath); -gboolean edit_load_back_cmd (WEdit * edit); -gboolean edit_load_forward_cmd (WEdit * edit); void edit_block_process_cmd (WEdit * edit, int macro_number); void edit_refresh_cmd (void); void edit_syntax_onoff_cmd (WDialog * h); @@ -231,28 +215,15 @@ void edit_show_tabs_tws_cmd (WDialog * h); void edit_show_margin_cmd (WDialog * h); void edit_show_numbers_cmd (WDialog * h); void edit_date_cmd (WEdit * edit); -void edit_goto_cmd (WEdit * edit); gboolean eval_marks (WEdit * edit, off_t * start_mark, off_t * end_mark); void edit_status (WEdit * edit, gboolean active); void edit_execute_key_command (WEdit * edit, unsigned long command, int char_for_insertion); void edit_update_screen (WEdit * edit); void edit_save_size (WEdit * edit); gboolean edit_handle_move_resize (WEdit * edit, unsigned long command); -void edit_toggle_fullscreen (WEdit * edit); void edit_move_to_line (WEdit * e, long line); void edit_move_display (WEdit * e, long line); void edit_word_wrap (WEdit * edit); -int edit_sort_cmd (WEdit * edit); -int edit_ext_cmd (WEdit * edit); - -gboolean edit_copy_to_X_buf_cmd (WEdit * edit); -gboolean edit_cut_to_X_buf_cmd (WEdit * edit); -gboolean edit_paste_from_X_buf_cmd (WEdit * edit); - -void edit_select_codepage_cmd (WEdit * edit); -void edit_insert_literal_cmd (WEdit * edit); - -void edit_paste_from_history (WEdit * edit); void edit_set_filename (WEdit * edit, const vfs_path_t * name_vpath); @@ -273,9 +244,6 @@ void book_mark_restore (WEdit * edit, int color); gboolean edit_line_is_blank (WEdit * edit, long line); gboolean is_break_char (char c); void edit_options_dialog (WDialog * h); -void edit_syntax_dialog (WEdit * edit); -void edit_mail_dialog (WEdit * edit); -void format_paragraph (WEdit * edit, gboolean force); /* either command or char_for_insertion must be passed as -1 */ void edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion); diff --git a/src/editor/edit.c b/src/editor/edit.c index 165e575e5..b66395d4b 100644 --- a/src/editor/edit.c +++ b/src/editor/edit.c @@ -46,6 +46,7 @@ #include "lib/global.h" +#include "lib/event.h" #include "lib/tty/color.h" #include "lib/tty/tty.h" /* attrset() */ #include "lib/tty/key.h" /* is_idle() */ @@ -73,6 +74,7 @@ #include "spell.h" #endif #include "macro.h" +#include "event.h" /*** global variables ****************************************************************************/ @@ -1089,46 +1091,6 @@ edit_move_updown (WEdit * edit, long lines, gboolean do_scroll, gboolean directi edit->found_len = 0; } -/* --------------------------------------------------------------------------------------------- */ - -static void -edit_right_delete_word (WEdit * edit) -{ - while (edit->buffer.curs1 < edit->buffer.size) - { - int c1, c2; - - c1 = edit_delete (edit, TRUE); - c2 = edit_buffer_get_current_byte (&edit->buffer); - if (c1 == '\n' || c2 == '\n') - break; - if ((isspace (c1) == 0) != (isspace (c2) == 0)) - break; - if ((my_type_of (c1) & my_type_of (c2)) == 0) - break; - } -} - -/* --------------------------------------------------------------------------------------------- */ - -static void -edit_left_delete_word (WEdit * edit) -{ - while (edit->buffer.curs1 > 0) - { - int c1, c2; - - c1 = edit_backspace (edit, TRUE); - c2 = edit_buffer_get_previous_byte (&edit->buffer); - if (c1 == '\n' || c2 == '\n') - break; - if ((isspace (c1) == 0) != (isspace (c2) == 0)) - break; - if ((my_type_of (c1) & my_type_of (c2)) == 0) - break; - } -} - /* --------------------------------------------------------------------------------------------- */ /** the start column position is not recorded, and hence does not @@ -1318,24 +1280,6 @@ edit_group_undo (WEdit * edit) /* --------------------------------------------------------------------------------------------- */ -static void -edit_delete_to_line_end (WEdit * edit) -{ - while (edit_buffer_get_current_byte (&edit->buffer) != '\n' && edit->buffer.curs2 != 0) - edit_delete (edit, TRUE); -} - -/* --------------------------------------------------------------------------------------------- */ - -static void -edit_delete_to_line_begin (WEdit * edit) -{ - while (edit_buffer_get_previous_byte (&edit->buffer) != '\n' && edit->buffer.curs1 != 0) - edit_backspace (edit, TRUE); -} - -/* --------------------------------------------------------------------------------------------- */ - static gboolean is_aligned_on_a_tab (WEdit * edit) { @@ -1556,106 +1500,6 @@ edit_get_bracket (WEdit * edit, gboolean in_screen, unsigned long furthest_brack /* --------------------------------------------------------------------------------------------- */ -static inline void -edit_goto_matching_bracket (WEdit * edit) -{ - off_t q; - - q = edit_get_bracket (edit, 0, 0); - if (q >= 0) - { - edit->bracket = edit->buffer.curs1; - edit->force |= REDRAW_PAGE; - edit_cursor_move (edit, q - edit->buffer.curs1); - } -} - -/* --------------------------------------------------------------------------------------------- */ - -static void -edit_move_block_to_right (WEdit * edit) -{ - off_t start_mark, end_mark; - long cur_bol, start_bol; - - if (!eval_marks (edit, &start_mark, &end_mark)) - return; - - start_bol = edit_buffer_get_bol (&edit->buffer, start_mark); - cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1); - - do - { - edit_cursor_move (edit, cur_bol - edit->buffer.curs1); - if (!edit_line_is_blank (edit, edit->buffer.curs_line)) - { - if (option_fill_tabs_with_spaces) - insert_spaces_tab (edit, option_fake_half_tabs); - else - edit_insert (edit, '\t'); - edit_cursor_move (edit, - edit_buffer_get_bol (&edit->buffer, cur_bol) - edit->buffer.curs1); - } - - if (cur_bol == 0) - break; - - cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1); - } - while (cur_bol >= start_bol); - - edit->force |= REDRAW_PAGE; -} - -/* --------------------------------------------------------------------------------------------- */ - -static void -edit_move_block_to_left (WEdit * edit) -{ - off_t start_mark, end_mark; - off_t cur_bol, start_bol; - int i; - - if (!eval_marks (edit, &start_mark, &end_mark)) - return; - - start_bol = edit_buffer_get_bol (&edit->buffer, start_mark); - cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1); - - do - { - int del_tab_width; - int next_char; - - edit_cursor_move (edit, cur_bol - edit->buffer.curs1); - - if (option_fake_half_tabs) - del_tab_width = HALF_TAB_SIZE; - else - del_tab_width = option_tab_spacing; - - next_char = edit_buffer_get_current_byte (&edit->buffer); - if (next_char == '\t') - edit_delete (edit, TRUE); - else if (next_char == ' ') - for (i = 1; i <= del_tab_width; i++) - { - if (next_char == ' ') - edit_delete (edit, TRUE); - next_char = edit_buffer_get_current_byte (&edit->buffer); - } - - if (cur_bol == 0) - break; - - cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1); - } - while (cur_bol >= start_bol); - - edit->force |= REDRAW_PAGE; -} - -/* --------------------------------------------------------------------------------------------- */ /** * prints at the cursor * @return number of chars printed @@ -1667,7 +1511,14 @@ edit_print_string (WEdit * e, const char *s) size_t i = 0; while (s[i] != '\0') - edit_execute_cmd (e, CK_InsertChar, (unsigned char) s[i++]); + { + mc_editor_event_data_insert_char_t event_data = { + .editor = e, + .char_for_insertion = (unsigned char) s[i++], + }; + /* Raw call og event callback for speedup. */ + mc_editor_cmd_insert_char (NULL, &event_data, NULL); + } e->force |= REDRAW_COMPLETELY; edit_update_screen (e); return i; @@ -1742,15 +1593,86 @@ edit_insert_column_from_file (WEdit * edit, int file, off_t * start_pos, off_t * return blocklen; } +/* --------------------------------------------------------------------------------------------- */ + +static void +mc_edit_switch_off_selection (WEdit * edit) +{ + if (!option_persistent_selections && edit->mark2 >= 0) + { + if (edit->column_highlight) + edit_push_undo_action (edit, COLUMN_ON); + edit->column_highlight = 0; + edit_mark_cmd (edit, TRUE); + } +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +mc_edit_go_left_cmd (WEdit * edit) +{ + + if (option_fake_half_tabs && is_in_indent (&edit->buffer) && right_of_four_spaces (edit)) + { + if (option_cursor_beyond_eol && edit->over_col > 0) + edit->over_col--; + else + edit_cursor_move (edit, -HALF_TAB_SIZE); + edit->force &= (0xFFF - REDRAW_CHAR_ONLY); + } + else + edit_left_char_move_cmd (edit); + +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +mc_edit_go_right_cmd (WEdit * edit) +{ + if (option_fake_half_tabs && is_in_indent (&edit->buffer) && left_of_four_spaces (edit)) + { + edit_cursor_move (edit, HALF_TAB_SIZE); + edit->force &= (0xFFF - REDRAW_CHAR_ONLY); + } + else + edit_right_char_move_cmd (edit); +} + /* --------------------------------------------------------------------------------------------- */ /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ -/** User edit menu, like user menu (F2) but only in editor. */ +/** + * The proxy function for calling "save_as" event. + */ void -user_menu (WEdit * edit, const char *menu_file, int selected_entry) +mc_editor_call_event_user_menu (WEdit * edit, const char *menu_file, int selected_entry) { + mc_editor_event_data_user_menu_t event_data = { + .editor = edit, + .menu_file = menu_file, + .selected_entry = selected_entry + }; + + mc_event_raise (MCEVENT_GROUP_EDITOR, "user_menu", &event_data, NULL); +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ +/** User edit menu, like user menu (F2) but only in editor. */ +/* event callback */ + +gboolean +mc_editor_cmd_user_menu (event_info_t * event_info, gpointer data, GError ** error) +{ + mc_editor_event_data_user_menu_t *event_data = (mc_editor_event_data_user_menu_t *) data; + WEdit *edit = event_data->editor; + const char *menu_file = event_data->menu_file; + int selected_entry = event_data->selected_entry; + char *block_file; gboolean nomark; off_t curs; @@ -1758,6 +1680,9 @@ user_menu (WEdit * edit, const char *menu_file, int selected_entry) struct stat status; vfs_path_t *block_file_vpath; + (void) event_info; + (void) error; + block_file = mc_config_get_full_path (EDIT_BLOCK_FILE); block_file_vpath = vfs_path_from_str (block_file); curs = edit->buffer.curs1; @@ -1774,7 +1699,7 @@ user_menu (WEdit * edit, const char *menu_file, int selected_entry) /* i.e. we have marked block */ if (!nomark) - rc = edit_block_delete_cmd (edit); + rc = mc_editor_call_event_block_delete (edit); if (rc == 0) { @@ -1795,6 +1720,8 @@ user_menu (WEdit * edit, const char *menu_file, int selected_entry) edit_cursor_move (edit, curs - edit->buffer.curs1); edit->force |= REDRAW_PAGE; widget_redraw (WIDGET (edit)); + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ @@ -3118,31 +3045,6 @@ edit_mark_current_line_cmd (WEdit * edit) /* --------------------------------------------------------------------------------------------- */ -void -edit_delete_line (WEdit * edit) -{ - /* - * Delete right part of the line. - * Note that edit_buffer_get_byte() returns '\n' when byte position is - * beyond EOF. - */ - while (edit_buffer_get_current_byte (&edit->buffer) != '\n') - (void) edit_delete (edit, TRUE); - - /* - * Delete '\n' char. - * Note that edit_delete() will not corrupt anything if called while - * cursor position is EOF. - */ - (void) edit_delete (edit, TRUE); - - /* - * Delete left part of the line. - * Note, that edit_buffer_get_byte() returns '\n' when byte position is < 0. - */ - while (edit_buffer_get_previous_byte (&edit->buffer) != '\n') - (void) edit_backspace (edit, TRUE); -} /* --------------------------------------------------------------------------------------------- */ @@ -3169,86 +3071,12 @@ edit_find_bracket (WEdit * edit) } /* --------------------------------------------------------------------------------------------- */ -/** - * This executes a command as though the user initiated it through a key - * press. Callback with MSG_KEY as a message calls this after - * translating the key press. This function can be used to pass any - * command to the editor. Note that the screen wouldn't update - * automatically. Either of command or char_for_insertion must be - * passed as -1. Commands are executed, and char_for_insertion is - * inserted at the cursor. - */ -void -edit_execute_key_command (WEdit * edit, unsigned long command, int char_for_insertion) +static void +edit_process_highlight_cmd (WEdit * edit, unsigned long command) { - if (command == CK_MacroStartRecord || command == CK_RepeatStartRecord - || (macro_index < 0 - && (command == CK_MacroStartStopRecord || command == CK_RepeatStartStopRecord))) - { - macro_index = 0; - edit->force |= REDRAW_CHAR_ONLY | REDRAW_LINE; - return; - } - if (macro_index != -1) - { - edit->force |= REDRAW_COMPLETELY; - if (command == CK_MacroStopRecord || command == CK_MacroStartStopRecord) - { - edit_store_macro_cmd (edit); - macro_index = -1; - return; - } - if (command == CK_RepeatStopRecord || command == CK_RepeatStartStopRecord) - { - edit_repeat_macro_cmd (edit); - macro_index = -1; - return; - } - } - - if (macro_index >= 0 && macro_index < MAX_MACRO_LENGTH - 1) - { - record_macro_buf[macro_index].action = command; - record_macro_buf[macro_index++].ch = char_for_insertion; - } - /* record the beginning of a set of editing actions initiated by a key press */ - if (command != CK_Undo && command != CK_ExtendedKeyMap) - edit_push_key_press (edit); - - edit_execute_cmd (edit, command, char_for_insertion); - if (edit->column_highlight) - edit->force |= REDRAW_PAGE; -} - -/* --------------------------------------------------------------------------------------------- */ -/** - This executes a command at a lower level than macro recording. - It also does not push a key_press onto the undo stack. This means - that if it is called many times, a single undo command will undo - all of them. It also does not check for the Undo command. - */ -void -edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) -{ - Widget *w = WIDGET (edit); - if (command == CK_WindowFullscreen) - { - edit_toggle_fullscreen (edit); return; - } - - /* handle window state */ - if (edit_handle_move_resize (edit, command)) - return; - - edit->force |= REDRAW_LINE; - - /* The next key press will unhighlight the found string, so update - * the whole page */ - if (edit->found_len || edit->column_highlight) - edit->force |= REDRAW_PAGE; switch (command) { @@ -3290,686 +3118,647 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) } edit->highlight = 1; break; - - /* any other command */ default: if (edit->highlight) edit_mark_cmd (edit, FALSE); /* clear */ edit->highlight = 0; } +} - /* first check for undo */ - if (command == CK_Undo) +/* --------------------------------------------------------------------------------------------- */ +/** + * This executes a command as though the user initiated it through a key + * press.7 Callback with MSG_KEY as a message calls this after + * translating the key press. This function can be used to pass any + * command to the editor. Note that the screen wouldn't update + * automatically. Either of command or char_for_insertion must be + * passed as -1. Commands are executed, and char_for_insertion is + * inserted at the cursor. + */ + +void +edit_execute_key_command (WEdit * edit, unsigned long command, int char_for_insertion) +{ + if (command == CK_MacroStartRecord || command == CK_RepeatStartRecord + || (macro_index < 0 + && (command == CK_MacroStartStopRecord || command == CK_RepeatStartStopRecord))) { - edit->redo_stack_reset = 0; - edit_group_undo (edit); - edit->found_len = 0; - edit->prev_col = edit_get_col (edit); - edit->search_start = edit->buffer.curs1; + macro_index = 0; + edit->force |= REDRAW_CHAR_ONLY | REDRAW_LINE; return; } - /* check for redo */ - if (command == CK_Redo) + if (macro_index != -1) { - edit->redo_stack_reset = 0; - edit_do_redo (edit); - edit->found_len = 0; - edit->prev_col = edit_get_col (edit); - edit->search_start = edit->buffer.curs1; - return; + edit->force |= REDRAW_COMPLETELY; + if (command == CK_MacroStopRecord || command == CK_MacroStartStopRecord) + { + mc_event_raise (MCEVENT_GROUP_EDITOR, "macro_store", edit, NULL); + macro_index = -1; + return; + } + if (command == CK_RepeatStopRecord || command == CK_RepeatStartStopRecord) + { + mc_event_raise (MCEVENT_GROUP_EDITOR, "macro_repeat", edit, NULL); + macro_index = -1; + return; + } } - edit->redo_stack_reset = 1; - - /* An ordinary key press */ - if (char_for_insertion >= 0) + if (macro_index >= 0 && macro_index < MAX_MACRO_LENGTH - 1) { - /* if non persistent selection and text selected */ - if (!option_persistent_selections && edit->mark1 != edit->mark2) - edit_block_delete_cmd (edit); - - if (edit->overwrite) - { - /* remove char only one time, after input first byte, multibyte chars */ -#ifdef HAVE_CHARSET - if (!mc_global.utf8_display || edit->charpoint == 0) -#endif - if (edit_buffer_get_current_byte (&edit->buffer) != '\n') - - edit_delete (edit, FALSE); - } - if (option_cursor_beyond_eol && edit->over_col > 0) - edit_insert_over (edit); -#ifdef HAVE_CHARSET - if (char_for_insertion > 255 && !mc_global.utf8_display) - { - unsigned char str[UTF8_CHAR_LEN + 1]; - size_t i = 0; - int res; - - res = g_unichar_to_utf8 (char_for_insertion, (char *) str); - if (res == 0) - { - str[0] = '.'; - str[1] = '\0'; - } - else - { - str[res] = '\0'; - } - while (i <= UTF8_CHAR_LEN && str[i] != '\0') - { - char_for_insertion = str[i]; - edit_insert (edit, char_for_insertion); - i++; - } - } - else -#endif - edit_insert (edit, char_for_insertion); - - if (option_auto_para_formatting) - { - format_paragraph (edit, FALSE); - edit->force |= REDRAW_PAGE; - } - else - check_and_wrap_line (edit); - edit->found_len = 0; - edit->prev_col = edit_get_col (edit); - edit->search_start = edit->buffer.curs1; - edit_find_bracket (edit); - return; + record_macro_buf[macro_index].action = command; + record_macro_buf[macro_index++].ch = char_for_insertion; } + /* record the beginning of a set of editing actions initiated by a key press */ + if (command != CK_Undo && command != CK_ExtendedKeyMap) + edit_push_key_press (edit); + + edit_execute_cmd (edit, command, char_for_insertion); + + if (edit->column_highlight) + edit->force |= REDRAW_PAGE; +} + +/* --------------------------------------------------------------------------------------------- */ + +/** + This executes a command at a lower level than macro recording. + It also does not push a key_press onto the undo stack. This means + that if it is called many times, a single undo command will undo + all of them. It also does not check for the Undo command. + */ +void +edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) +{ + const char *event_name = NULL; + void *event_data; + mc_editor_event_data_insert_char_t insert_event_data = { + .editor = edit, + .char_for_insertion = char_for_insertion + }; + + mc_editor_event_data_move_cursor_t cursor_event_data = { + .editor = edit, + .is_mark = FALSE, + .is_column = FALSE + }; + mc_editor_event_data_ret_boolean_t ret_boolean_event_data = { + .editor = edit, + }; + mc_editor_event_data_user_menu_t user_menu_event_data = { + .editor = edit, + }; + + edit->is_cursor_moved = FALSE; switch (command) { - case CK_TopOnScreen: case CK_BottomOnScreen: - case CK_Top: - case CK_Bottom: - case CK_PageUp: - case CK_PageDown: - case CK_Home: - case CK_End: - case CK_Up: case CK_Down: + case CK_End: + case CK_Home: case CK_Left: - case CK_Right: - case CK_WordLeft: - case CK_WordRight: - if (!option_persistent_selections && edit->mark2 >= 0) - { - if (edit->column_highlight) - edit_push_undo_action (edit, COLUMN_ON); - edit->column_highlight = 0; - edit_mark_cmd (edit, TRUE); - } - } - - switch (command) - { - case CK_TopOnScreen: - case CK_BottomOnScreen: + case CK_MarkColumnDown: + case CK_MarkColumnLeft: + case CK_MarkColumnPageDown: + case CK_MarkColumnPageUp: + case CK_MarkColumnParagraphDown: + case CK_MarkColumnParagraphUp: + case CK_MarkColumnRight: + case CK_MarkColumnScrollDown: + case CK_MarkColumnScrollUp: + case CK_MarkColumnUp: + case CK_MarkDown: + case CK_MarkLeft: + case CK_MarkPageDown: + case CK_MarkPageUp: + case CK_MarkParagraphDown: + case CK_MarkToFileBegin: + case CK_MarkParagraphUp: + case CK_MarkRight: + case CK_MarkScrollDown: + case CK_MarkScrollUp: + case CK_MarkToEnd: + case CK_MarkToHome: case CK_MarkToPageBegin: case CK_MarkToPageEnd: - case CK_Up: - case CK_Down: - case CK_WordLeft: - case CK_WordRight: case CK_MarkToWordBegin: case CK_MarkToWordEnd: case CK_MarkUp: - case CK_MarkDown: - case CK_MarkColumnUp: - case CK_MarkColumnDown: - if (edit->mark2 == -1) - break; /*marking is following the cursor: may need to highlight a whole line */ - case CK_Left: + case CK_PageDown: + case CK_PageUp: + case CK_ParagraphDown: + case CK_ParagraphUp: case CK_Right: - case CK_MarkLeft: - case CK_MarkRight: - edit->force |= REDRAW_CHAR_ONLY; + case CK_ScrollDown: + case CK_ScrollUp: + case CK_Top: + case CK_TopOnScreen: + case CK_Up: + case CK_WordLeft: + case CK_WordRight: + case CK_Bottom: + case CK_MarkToFileEnd: + event_data = &cursor_event_data; + break; + case CK_Remove: + case CK_SaveAs: + event_data = &ret_boolean_event_data; + break; + case CK_InsertChar: + case CK_Return: + event_data = &insert_event_data; + break; + case CK_UserMenu: + event_data = &user_menu_event_data; + break; + default: + event_data = edit; + } + + if (command != CK_WindowFullscreen) + { + /* handle window state */ + if (edit_handle_move_resize (edit, command)) + return; + + edit->force |= REDRAW_LINE; + + /* The next key press will unhighlight the found string, so update + * the whole page */ + if (edit->found_len || edit->column_highlight) + edit->force |= REDRAW_PAGE; + + edit_process_highlight_cmd (edit, command); + + if (!(command == CK_Redo || command == CK_Undo)) + edit->redo_stack_reset = 1; } /* basic cursor key commands */ switch (command) { + case CK_WindowFullscreen: + event_name = "toggle_fullscreen"; + case CK_Undo: + event_name = "undo"; + break; + case CK_Redo: + event_name = "redo"; + break; + case CK_InsertChar: + event_name = "insert_char"; + break; case CK_BackSpace: - /* if non persistent selection and text selected */ - if (!option_persistent_selections && edit->mark1 != edit->mark2) - edit_block_delete_cmd (edit); - else if (option_cursor_beyond_eol && edit->over_col > 0) - edit->over_col--; - else if (option_backspace_through_tabs && is_in_indent (&edit->buffer)) - { - while (edit_buffer_get_previous_byte (&edit->buffer) != '\n' && edit->buffer.curs1 > 0) - edit_backspace (edit, TRUE); - } - else if (option_fake_half_tabs && is_in_indent (&edit->buffer) - && right_of_four_spaces (edit)) - { - int i; - - for (i = 0; i < HALF_TAB_SIZE; i++) - edit_backspace (edit, TRUE); - } - else - edit_backspace (edit, FALSE); + event_name = "backspace"; break; case CK_Delete: - /* if non persistent selection and text selected */ - if (!option_persistent_selections && edit->mark1 != edit->mark2) - edit_block_delete_cmd (edit); - else - { - if (option_cursor_beyond_eol && edit->over_col > 0) - edit_insert_over (edit); - - if (option_fake_half_tabs && is_in_indent (&edit->buffer) && left_of_four_spaces (edit)) - { - int i; - - for (i = 1; i <= HALF_TAB_SIZE; i++) - edit_delete (edit, TRUE); - } - else - edit_delete (edit, FALSE); - } + event_name = "delete"; break; case CK_DeleteToWordBegin: - edit->over_col = 0; - edit_left_delete_word (edit); + event_name = "delete_word_left"; break; case CK_DeleteToWordEnd: - if (option_cursor_beyond_eol && edit->over_col > 0) - edit_insert_over (edit); - - edit_right_delete_word (edit); + event_name = "delete_word_right"; break; case CK_DeleteLine: - edit_delete_line (edit); + event_name = "delete_line"; break; case CK_DeleteToHome: - edit_delete_to_line_begin (edit); + event_name = "delete_line_to_begin"; break; case CK_DeleteToEnd: - edit_delete_to_line_end (edit); + event_name = "delete_line_to_end"; break; case CK_Enter: - edit->over_col = 0; - if (option_auto_para_formatting) - { - edit_double_newline (edit); - if (option_return_does_auto_indent && !bracketed_pasting_in_progress) - edit_auto_indent (edit); - format_paragraph (edit, FALSE); - } - else - { - edit_insert (edit, '\n'); - if (option_return_does_auto_indent && !bracketed_pasting_in_progress) - edit_auto_indent (edit); - } + event_name = "enter"; break; case CK_Return: - edit_insert (edit, '\n'); + insert_event_data.char_for_insertion = '\n'; + event_name = "insert_char_raw"; break; - case CK_MarkColumnPageUp: - edit->column_highlight = 1; + cursor_event_data.direction = TO_PAGE_UP; + cursor_event_data.is_mark = TRUE; + cursor_event_data.is_column = TRUE; + event_name = "move_cursor"; + break; case CK_PageUp: + cursor_event_data.direction = TO_PAGE_UP; + event_name = "move_cursor"; + break; case CK_MarkPageUp: - edit_move_up (edit, w->lines - 1, 1); + cursor_event_data.direction = TO_PAGE_UP; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_MarkColumnPageDown: - edit->column_highlight = 1; + cursor_event_data.direction = TO_PAGE_DOWN; + cursor_event_data.is_mark = TRUE; + cursor_event_data.is_column = TRUE; + event_name = "move_cursor"; + break; case CK_PageDown: + cursor_event_data.direction = TO_PAGE_DOWN; + event_name = "move_cursor"; + break; case CK_MarkPageDown: - edit_move_down (edit, w->lines - 1, 1); + cursor_event_data.direction = TO_PAGE_DOWN; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_MarkColumnLeft: - edit->column_highlight = 1; - case CK_Left: + cursor_event_data.direction = TO_LEFT; + cursor_event_data.is_mark = TRUE; + cursor_event_data.is_column = TRUE; + event_name = "move_cursor"; + break; case CK_MarkLeft: - if (option_fake_half_tabs && is_in_indent (&edit->buffer) && right_of_four_spaces (edit)) - { - if (option_cursor_beyond_eol && edit->over_col > 0) - edit->over_col--; - else - edit_cursor_move (edit, -HALF_TAB_SIZE); - edit->force &= (0xFFF - REDRAW_CHAR_ONLY); - } - else - edit_left_char_move_cmd (edit); + cursor_event_data.direction = TO_LEFT; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; + break; + case CK_Left: + cursor_event_data.direction = TO_LEFT; + edit->force |= REDRAW_CHAR_ONLY; + event_name = "move_cursor"; break; case CK_MarkColumnRight: - edit->column_highlight = 1; + cursor_event_data.direction = TO_RIGHT; + cursor_event_data.is_mark = TRUE; + cursor_event_data.is_column = TRUE; + event_name = "move_cursor"; + break; case CK_Right: + cursor_event_data.direction = TO_RIGHT; + event_name = "move_cursor"; + break; case CK_MarkRight: - if (option_fake_half_tabs && is_in_indent (&edit->buffer) && left_of_four_spaces (edit)) - { - edit_cursor_move (edit, HALF_TAB_SIZE); - edit->force &= (0xFFF - REDRAW_CHAR_ONLY); - } - else - edit_right_char_move_cmd (edit); + cursor_event_data.direction = TO_RIGHT; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_TopOnScreen: + cursor_event_data.direction = TO_PAGE_BEGIN; + event_name = "move_cursor"; + break; case CK_MarkToPageBegin: - edit_begin_page (edit); + cursor_event_data.direction = TO_PAGE_BEGIN; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_BottomOnScreen: + cursor_event_data.direction = TO_PAGE_END; + event_name = "move_cursor"; + break; case CK_MarkToPageEnd: - edit_end_page (edit); + cursor_event_data.direction = TO_PAGE_END; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_WordLeft: + cursor_event_data.direction = TO_WORD_BEGIN; + event_name = "move_cursor"; + break; case CK_MarkToWordBegin: - edit->over_col = 0; - edit_left_word_move_cmd (edit); + cursor_event_data.direction = TO_WORD_BEGIN; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_WordRight: + cursor_event_data.direction = TO_WORD_END; + event_name = "move_cursor"; + break; case CK_MarkToWordEnd: - edit->over_col = 0; - edit_right_word_move_cmd (edit); + cursor_event_data.direction = TO_WORD_END; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_MarkColumnUp: - edit->column_highlight = 1; + cursor_event_data.direction = TO_UP; + cursor_event_data.is_mark = TRUE; + cursor_event_data.is_column = TRUE; + event_name = "move_cursor"; + break; case CK_Up: + cursor_event_data.direction = TO_UP; + event_name = "move_cursor"; + break; case CK_MarkUp: - edit_move_up (edit, 1, 0); + cursor_event_data.direction = TO_UP; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_MarkColumnDown: - edit->column_highlight = 1; + cursor_event_data.direction = TO_DOWN; + cursor_event_data.is_mark = TRUE; + cursor_event_data.is_column = TRUE; + event_name = "move_cursor"; + break; case CK_Down: + cursor_event_data.direction = TO_DOWN; + event_name = "move_cursor"; + break; case CK_MarkDown: - edit_move_down (edit, 1, 0); + cursor_event_data.direction = TO_DOWN; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_MarkColumnParagraphUp: - edit->column_highlight = 1; + cursor_event_data.direction = TO_PARAGRAPH_UP; + cursor_event_data.is_mark = TRUE; + cursor_event_data.is_column = TRUE; + event_name = "move_cursor"; + break; case CK_ParagraphUp: + cursor_event_data.direction = TO_PARAGRAPH_UP; + event_name = "move_cursor"; + break; case CK_MarkParagraphUp: - edit_move_up_paragraph (edit, 0); + cursor_event_data.direction = TO_PARAGRAPH_UP; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_MarkColumnParagraphDown: - edit->column_highlight = 1; + cursor_event_data.direction = TO_PARAGRAPH_DOWN; + cursor_event_data.is_mark = TRUE; + cursor_event_data.is_column = TRUE; + event_name = "move_cursor"; + break; case CK_ParagraphDown: + cursor_event_data.direction = TO_PARAGRAPH_DOWN; + event_name = "move_cursor"; + break; case CK_MarkParagraphDown: - edit_move_down_paragraph (edit, 0); + cursor_event_data.direction = TO_PARAGRAPH_DOWN; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_MarkColumnScrollUp: - edit->column_highlight = 1; + cursor_event_data.direction = TO_SCROLL_UP; + cursor_event_data.is_mark = TRUE; + cursor_event_data.is_column = TRUE; + event_name = "move_cursor"; + break; case CK_ScrollUp: + cursor_event_data.direction = TO_SCROLL_UP; + event_name = "move_cursor"; + break; case CK_MarkScrollUp: - edit_move_up (edit, 1, 1); + cursor_event_data.direction = TO_SCROLL_UP; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_MarkColumnScrollDown: - edit->column_highlight = 1; + cursor_event_data.direction = TO_SCROLL_DOWN; + cursor_event_data.is_mark = TRUE; + cursor_event_data.is_column = TRUE; + event_name = "move_cursor"; + break; case CK_ScrollDown: + cursor_event_data.direction = TO_SCROLL_DOWN; + event_name = "move_cursor"; + break; case CK_MarkScrollDown: - edit_move_down (edit, 1, 1); + cursor_event_data.direction = TO_SCROLL_DOWN; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_Home: + cursor_event_data.direction = TO_LINE_BEGIN; + event_name = "move_cursor"; + break; case CK_MarkToHome: - edit_cursor_to_bol (edit); + cursor_event_data.direction = TO_LINE_BEGIN; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_End: + cursor_event_data.direction = TO_LINE_END; + event_name = "move_cursor"; + break; case CK_MarkToEnd: - edit_cursor_to_eol (edit); + cursor_event_data.direction = TO_LINE_END; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; + break; + case CK_Top: + cursor_event_data.direction = TO_FILE_BEGIN; + event_name = "move_cursor"; + break; + case CK_MarkToFileBegin: + cursor_event_data.direction = TO_FILE_BEGIN; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; + break; + case CK_Bottom: + cursor_event_data.direction = TO_FILE_END; + event_name = "move_cursor"; + break; + case CK_MarkToFileEnd: + cursor_event_data.direction = TO_FILE_END; + cursor_event_data.is_mark = TRUE; + event_name = "move_cursor"; break; case CK_Tab: - /* if text marked shift block */ - if (edit->mark1 != edit->mark2 && !option_persistent_selections) - { - if (edit->mark2 < 0) - edit_mark_cmd (edit, FALSE); - edit_move_block_to_right (edit); - } - else - { - if (option_cursor_beyond_eol) - edit_insert_over (edit); - edit_tab_cmd (edit); - if (option_auto_para_formatting) - { - format_paragraph (edit, FALSE); - edit->force |= REDRAW_PAGE; - } - else - check_and_wrap_line (edit); - } + event_name = "tab"; break; - case CK_InsertOverwrite: + event_name = "switch_insert_overwrite"; edit->overwrite = !edit->overwrite; break; - case CK_Mark: - if (edit->mark2 >= 0) - { - if (edit->column_highlight) - edit_push_undo_action (edit, COLUMN_ON); - edit->column_highlight = 0; - } - edit_mark_cmd (edit, FALSE); + event_name = "mark"; break; case CK_MarkColumn: - if (!edit->column_highlight) - edit_push_undo_action (edit, COLUMN_OFF); - edit->column_highlight = 1; - edit_mark_cmd (edit, FALSE); + event_name = "mark_column"; break; case CK_MarkAll: - edit_set_markers (edit, 0, edit->buffer.size, 0, 0); - edit->force |= REDRAW_PAGE; + event_name = "mark_all"; break; case CK_Unmark: - if (edit->column_highlight) - edit_push_undo_action (edit, COLUMN_ON); - edit->column_highlight = 0; - edit_mark_cmd (edit, TRUE); + event_name = "unmark"; break; case CK_MarkWord: - if (edit->column_highlight) - edit_push_undo_action (edit, COLUMN_ON); - edit->column_highlight = 0; - edit_mark_current_word_cmd (edit); + event_name = "mark_word"; break; case CK_MarkLine: - if (edit->column_highlight) - edit_push_undo_action (edit, COLUMN_ON); - edit->column_highlight = 0; - edit_mark_current_line_cmd (edit); + event_name = "mark_line"; break; case CK_Bookmark: - book_mark_clear (edit, edit->buffer.curs_line, BOOK_MARK_FOUND_COLOR); - if (book_mark_query_color (edit, edit->buffer.curs_line, BOOK_MARK_COLOR)) - book_mark_clear (edit, edit->buffer.curs_line, BOOK_MARK_COLOR); - else - book_mark_insert (edit, edit->buffer.curs_line, BOOK_MARK_COLOR); + event_name = "bookmark_toggle"; break; case CK_BookmarkFlush: - book_mark_flush (edit, BOOK_MARK_COLOR); - book_mark_flush (edit, BOOK_MARK_FOUND_COLOR); - edit->force |= REDRAW_PAGE; + event_name = "bookmark_flush"; break; case CK_BookmarkNext: - if (edit->book_mark != NULL) - { - edit_book_mark_t *p; - - p = book_mark_find (edit, edit->buffer.curs_line); - if (p->next != NULL) - { - p = p->next; - if (p->line >= edit->start_line + w->lines || p->line < edit->start_line) - edit_move_display (edit, p->line - w->lines / 2); - edit_move_to_line (edit, p->line); - } - } + event_name = "bookmark_next"; break; case CK_BookmarkPrev: - if (edit->book_mark != NULL) - { - edit_book_mark_t *p; - - p = book_mark_find (edit, edit->buffer.curs_line); - while (p->line == edit->buffer.curs_line) - if (p->prev != NULL) - p = p->prev; - if (p->line >= 0) - { - if (p->line >= edit->start_line + w->lines || p->line < edit->start_line) - edit_move_display (edit, p->line - w->lines / 2); - edit_move_to_line (edit, p->line); - } - } - break; - - case CK_Top: - case CK_MarkToFileBegin: - edit_move_to_top (edit); - break; - case CK_Bottom: - case CK_MarkToFileEnd: - edit_move_to_bottom (edit); + event_name = "bookmark_prev"; break; case CK_Copy: - if (option_cursor_beyond_eol && edit->over_col > 0) - edit_insert_over (edit); - edit_block_copy_cmd (edit); + event_name = "block_copy"; break; case CK_Remove: - edit_block_delete_cmd (edit); + event_name = "block_delete"; break; case CK_Move: - edit_block_move_cmd (edit); + event_name = "block_move"; break; case CK_BlockShiftLeft: - if (edit->mark1 != edit->mark2) - edit_move_block_to_left (edit); + event_name = "block_move_to_left"; break; case CK_BlockShiftRight: - if (edit->mark1 != edit->mark2) - edit_move_block_to_right (edit); + event_name = "block_move_to_right"; break; case CK_Store: - edit_copy_to_X_buf_cmd (edit); + event_name = "ext_clip_copy"; break; case CK_Cut: - edit_cut_to_X_buf_cmd (edit); + event_name = "ext_clip_cut"; break; case CK_Paste: - /* if non persistent selection and text selected */ - if (!option_persistent_selections && edit->mark1 != edit->mark2) - edit_block_delete_cmd (edit); - if (option_cursor_beyond_eol && edit->over_col > 0) - edit_insert_over (edit); - edit_paste_from_X_buf_cmd (edit); - if (!option_persistent_selections && edit->mark2 >= 0) - { - if (edit->column_highlight) - edit_push_undo_action (edit, COLUMN_ON); - edit->column_highlight = 0; - edit_mark_cmd (edit, TRUE); - } + event_name = "ext_clip_paste"; break; case CK_History: - edit_paste_from_history (edit); + event_name = "paste_from_history"; break; case CK_SaveAs: - edit_save_as_cmd (edit); + event_name = "save_as"; break; case CK_Save: - edit_save_confirm_cmd (edit); + event_name = "save_confirm"; break; case CK_BlockSave: - edit_save_block_cmd (edit); + event_name = "save_block"; break; case CK_InsertFile: - edit_insert_file_cmd (edit); + event_name = "insert_file"; break; case CK_FilePrev: - edit_load_back_cmd (edit); + event_name = "file_load_prev"; break; case CK_FileNext: - edit_load_forward_cmd (edit); + event_name = "file_load_next"; break; case CK_SyntaxChoose: - edit_syntax_dialog (edit); + event_name = "syntax_show_dialog"; break; case CK_Search: - edit_search_cmd (edit, FALSE); + event_name = "search"; break; case CK_SearchContinue: - edit_search_cmd (edit, TRUE); + event_name = "search_continue"; break; case CK_Replace: - edit_replace_cmd (edit, 0); + event_name = "replace"; break; case CK_ReplaceContinue: - edit_replace_cmd (edit, 1); + event_name = "replace_continue"; break; case CK_Complete: - /* if text marked shift block */ - if (edit->mark1 != edit->mark2 && !option_persistent_selections) - edit_move_block_to_left (edit); - else - edit_complete_word_cmd (edit); + event_name = "complete"; break; case CK_Find: - edit_get_match_keyword_cmd (edit); + event_name = "match_keyword"; break; + case CK_Date: + event_name = "print_current_date"; + break; + case CK_Goto: + event_name = "goto_line"; + break; + case CK_ParagraphFormat: + event_name = "format_paragraph_force"; + break; + case CK_MacroDelete: + event_name = "macro_delete"; + break; + case CK_MatchBracket: + event_name = "goto_matching_bracket"; + break; + case CK_UserMenu: + user_menu_event_data.menu_file = NULL; + user_menu_event_data.selected_entry = -1; + event_name = "user_menu"; + break; + case CK_Sort: + event_name = "sort"; + break; + case CK_ExternalCommand: + event_name = "run_external_command"; + break; + case CK_Mail: + event_name = "mail"; + break; + case CK_InsertLiteral: + event_name = "insert_literal"; + break; + case CK_MacroStartStopRecord: + event_name = "macro_record_start_stop"; + break; + case CK_RepeatStartStopRecord: + event_name = "macro_repeat_start_stop"; + break; + case CK_ExtendedKeyMap: + /* the action will be removed */ + edit->extmod = TRUE; + break; + +#ifdef HAVE_CHARSET + case CK_SelectCodepage: + event_name = "select_codepage"; + break; +#endif #ifdef HAVE_ASPELL case CK_SpellCheckCurrentWord: - edit_suggest_current_word (edit); + event_name = "spell_suggest_word"; break; case CK_SpellCheck: - edit_spellcheck_file (edit); + event_name = "spell_check"; break; case CK_SpellCheckSelectLang: - edit_set_spell_lang (); + event_name = "spell_set_language"; break; #endif - case CK_Date: - { - char s[BUF_MEDIUM]; - /* fool gcc to prevent a Y2K warning */ - char time_format[] = "_c"; - time_format[0] = '%'; - - FMT_LOCALTIME_CURRENT (s, sizeof (s), time_format); - edit_print_string (edit, s); - edit->force |= REDRAW_PAGE; - } - break; - case CK_Goto: - edit_goto_cmd (edit); - break; - case CK_ParagraphFormat: - format_paragraph (edit, TRUE); - edit->force |= REDRAW_PAGE; - break; - case CK_MacroDelete: - edit_delete_macro_cmd (edit); - break; - case CK_MatchBracket: - edit_goto_matching_bracket (edit); - break; - case CK_UserMenu: - user_menu (edit, NULL, -1); - break; - case CK_Sort: - edit_sort_cmd (edit); - break; - case CK_ExternalCommand: - edit_ext_cmd (edit); - break; - case CK_Mail: - edit_mail_dialog (edit); - break; -#ifdef HAVE_CHARSET - case CK_SelectCodepage: - edit_select_codepage_cmd (edit); - break; -#endif - case CK_InsertLiteral: - edit_insert_literal_cmd (edit); - break; - case CK_MacroStartStopRecord: - edit_begin_end_macro_cmd (edit); - break; - case CK_RepeatStartStopRecord: - edit_begin_end_repeat_cmd (edit); - break; - case CK_ExtendedKeyMap: - edit->extmod = TRUE; - break; default: break; } - /* CK_PipeBlock */ - if ((command / CK_PipeBlock (0)) == 1) - edit_block_process_cmd (edit, command - CK_PipeBlock (0)); - - /* keys which must set the col position, and the search vars */ - switch (command) + if (command != CK_WindowFullscreen) { - case CK_Search: - case CK_SearchContinue: - case CK_Replace: - case CK_ReplaceContinue: - case CK_Complete: - edit->prev_col = edit_get_col (edit); - break; - case CK_Up: - case CK_MarkUp: - case CK_MarkColumnUp: - case CK_Down: - case CK_MarkDown: - case CK_MarkColumnDown: - case CK_PageUp: - case CK_MarkPageUp: - case CK_MarkColumnPageUp: - case CK_PageDown: - case CK_MarkPageDown: - case CK_MarkColumnPageDown: - case CK_Top: - case CK_MarkToFileBegin: - case CK_Bottom: - case CK_MarkToFileEnd: - case CK_ParagraphUp: - case CK_MarkParagraphUp: - case CK_MarkColumnParagraphUp: - case CK_ParagraphDown: - case CK_MarkParagraphDown: - case CK_MarkColumnParagraphDown: - case CK_ScrollUp: - case CK_MarkScrollUp: - case CK_MarkColumnScrollUp: - case CK_ScrollDown: - case CK_MarkScrollDown: - case CK_MarkColumnScrollDown: - edit->search_start = edit->buffer.curs1; - edit->found_len = 0; - break; - default: - edit->found_len = 0; - edit->prev_col = edit_get_col (edit); - edit->search_start = edit->buffer.curs1; - } - edit_find_bracket (edit); + /* CK_PipeBlock */ + if ((command / CK_PipeBlock (0)) == 1) + edit_block_process_cmd (edit, command - CK_PipeBlock (0)); - if (option_auto_para_formatting) - { - switch (command) + edit->found_len = 0; + if (!edit->is_cursor_moved) { - case CK_BackSpace: - case CK_Delete: - case CK_DeleteToWordBegin: - case CK_DeleteToWordEnd: - case CK_DeleteToHome: - case CK_DeleteToEnd: - format_paragraph (edit, FALSE); - edit->force |= REDRAW_PAGE; + edit->prev_col = edit_get_col (edit); } + + edit_find_bracket (edit); } + + if (event_name != NULL) + mc_event_raise (MCEVENT_GROUP_EDITOR, event_name, event_data, NULL); + } /* --------------------------------------------------------------------------------------------- */ void -edit_stack_init (void) +mc_editor_init (GError ** error) { for (edit_stack_iterator = 0; edit_stack_iterator < MAX_HISTORY_MOVETO; edit_stack_iterator++) { @@ -3978,13 +3767,17 @@ edit_stack_init (void) } edit_stack_iterator = 0; + + mc_editor_init_events (error); } /* --------------------------------------------------------------------------------------------- */ void -edit_stack_free (void) +mc_editor_deinit (GError ** error) { + (void) error; + for (edit_stack_iterator = 0; edit_stack_iterator < MAX_HISTORY_MOVETO; edit_stack_iterator++) vfs_path_free (edit_history_moveto[edit_stack_iterator].filename_vpath); } @@ -4008,3 +3801,842 @@ edit_move_down (WEdit * edit, long i, gboolean do_scroll) } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_backspace (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + /* if non persistent selection and text selected */ + if (!option_persistent_selections && edit->mark1 != edit->mark2) + mc_editor_call_event_block_delete (edit); + else if (option_cursor_beyond_eol && edit->over_col > 0) + edit->over_col--; + else if (option_backspace_through_tabs && is_in_indent (&edit->buffer)) + { + while (edit_buffer_get_previous_byte (&edit->buffer) != '\n' && edit->buffer.curs1 > 0) + edit_backspace (edit, TRUE); + } + else if (option_fake_half_tabs && is_in_indent (&edit->buffer) && right_of_four_spaces (edit)) + { + int i; + + for (i = 0; i < HALF_TAB_SIZE; i++) + edit_backspace (edit, TRUE); + } + else + edit_backspace (edit, FALSE); + + mc_event_raise (MCEVENT_GROUP_EDITOR, "format_paragraph_auto", edit, NULL); + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_delete (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + /* if non persistent selection and text selected */ + if (!option_persistent_selections && edit->mark1 != edit->mark2) + mc_editor_call_event_block_delete (edit); + else + { + if (option_cursor_beyond_eol && edit->over_col > 0) + edit_insert_over (edit); + + if (option_fake_half_tabs && is_in_indent (&edit->buffer) && left_of_four_spaces (edit)) + { + int i; + + for (i = 1; i <= HALF_TAB_SIZE; i++) + edit_delete (edit, TRUE); + } + else + edit_delete (edit, FALSE); + } + + mc_event_raise (MCEVENT_GROUP_EDITOR, "format_paragraph_auto", edit, NULL); + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_delete_word (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + mc_editor_event_direction_t event_direction = + (mc_editor_event_direction_t) event_info->init_data; + + (void) error; + + if (event_direction == TO_LEFT) + edit->over_col = 0; + else if (option_cursor_beyond_eol && edit->over_col > 0) + edit_insert_over (edit); + + while (edit->buffer.curs1 > 0) + { + int c1, c2; + if (event_direction == TO_LEFT) + c1 = edit_backspace (edit, TRUE); + else + c1 = edit_delete (edit, TRUE); + + c2 = edit_buffer_get_previous_byte (&edit->buffer); + if (c1 == '\n' || c2 == '\n') + break; + if ((isspace (c1) == 0) != (isspace (c2) == 0)) + break; + if ((my_type_of (c1) & my_type_of (c2)) == 0) + break; + } + + mc_event_raise (MCEVENT_GROUP_EDITOR, "format_paragraph_auto", edit, NULL); + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_delete_line (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + mc_editor_event_direction_t event_direction = + (mc_editor_event_direction_t) event_info->init_data; + + (void) error; + + switch (event_direction) + { + case TO_LINE_BEGIN: + while (edit_buffer_get_previous_byte (&edit->buffer) != '\n' && edit->buffer.curs1 != 0) + edit_backspace (edit, TRUE); + mc_event_raise (MCEVENT_GROUP_EDITOR, "format_paragraph_auto", edit, NULL); + break; + case TO_LINE_END: + while (edit_buffer_get_current_byte (&edit->buffer) != '\n' && edit->buffer.curs2 != 0) + edit_delete (edit, TRUE); + mc_event_raise (MCEVENT_GROUP_EDITOR, "format_paragraph_auto", edit, NULL); + break; + default: + + /* + * Delete right part of the line. + * Note that edit_buffer_get_byte() returns '\n' when byte position is + * beyond EOF. + */ + while (edit_buffer_get_current_byte (&edit->buffer) != '\n') + (void) edit_delete (edit, TRUE); + + /* + * Delete '\n' char. + * Note that edit_delete() will not corrupt anything if called while + * cursor position is EOF. + */ + (void) edit_delete (edit, TRUE); + + /* + * Delete left part of the line. + * Note, that edit_buffer_get_byte() returns '\n' when byte position is < 0. + */ + while (edit_buffer_get_previous_byte (&edit->buffer) != '\n') + (void) edit_backspace (edit, TRUE); + + } + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_enter (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + edit->over_col = 0; + if (option_auto_para_formatting) + { + edit_double_newline (edit); + if (option_return_does_auto_indent && !bracketed_pasting_in_progress) + edit_auto_indent (edit); + } + else + { + edit_insert (edit, '\n'); + if (option_return_does_auto_indent && !bracketed_pasting_in_progress) + edit_auto_indent (edit); + } + mc_event_raise (MCEVENT_GROUP_EDITOR, "format_paragraph_auto", edit, NULL); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_insert_char_raw (event_info_t * event_info, gpointer data, GError ** error) +{ + mc_editor_event_data_insert_char_t *event_data = (mc_editor_event_data_insert_char_t *) data; + WEdit *edit = event_data->editor; + + (void) event_info; + (void) error; + + edit_insert (edit, event_data->char_for_insertion); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_insert_char (event_info_t * event_info, gpointer data, GError ** error) +{ + mc_editor_event_data_insert_char_t *event_data = (mc_editor_event_data_insert_char_t *) data; + WEdit *edit = event_data->editor; + + (void) event_info; + (void) error; + + /* An ordinary key press */ + if (event_data->char_for_insertion < 0) + return TRUE; + + /* if non persistent selection and text selected */ + if (!option_persistent_selections && edit->mark1 != edit->mark2) + mc_editor_call_event_block_delete (edit); + + if (edit->overwrite) + { + /* remove char only one time, after input first byte, multibyte chars */ +#ifdef HAVE_CHARSET + if (!mc_global.utf8_display || edit->charpoint == 0) +#endif + if (edit_buffer_get_current_byte (&edit->buffer) != '\n') + + edit_delete (edit, FALSE); + } + if (option_cursor_beyond_eol && edit->over_col > 0) + edit_insert_over (edit); +#ifdef HAVE_CHARSET + if (event_data->char_for_insertion > 255 && !mc_global.utf8_display) + { + unsigned char str[UTF8_CHAR_LEN + 1]; + size_t i = 0; + int res; + + res = g_unichar_to_utf8 (event_data->char_for_insertion, (char *) str); + if (res == 0) + { + str[0] = '.'; + str[1] = '\0'; + } + else + { + str[res] = '\0'; + } + while (i <= UTF8_CHAR_LEN && str[i] != '\0') + { + event_data->char_for_insertion = str[i]; + edit_insert (edit, event_data->char_for_insertion); + i++; + } + } + else +#endif + edit_insert (edit, event_data->char_for_insertion); + + mc_event_raise (MCEVENT_GROUP_EDITOR, "format_paragraph_auto", edit, NULL); + + if (!option_auto_para_formatting) + check_and_wrap_line (edit); + + edit->found_len = 0; + edit->prev_col = edit_get_col (edit); + edit->search_start = edit->buffer.curs1; + edit_find_bracket (edit); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_undo (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + edit->redo_stack_reset = 0; + edit_group_undo (edit); + edit->found_len = 0; + edit->prev_col = edit_get_col (edit); + edit->search_start = edit->buffer.curs1; + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_redo (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + edit->redo_stack_reset = 0; + edit_do_redo (edit); + edit->found_len = 0; + edit->prev_col = edit_get_col (edit); + edit->search_start = edit->buffer.curs1; + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_move_cursor (event_info_t * event_info, gpointer data, GError ** error) +{ + mc_editor_event_data_move_cursor_t *event_data = (mc_editor_event_data_move_cursor_t *) data; + WEdit *edit = event_data->editor; + Widget *w = WIDGET (edit); + + (void) event_info; + (void) error; + + + if (!event_data->is_mark) + mc_edit_switch_off_selection (edit); + + if (event_data->is_column) + edit->column_highlight = 1; + + if (edit->mark2 != -1) + edit->force |= REDRAW_CHAR_ONLY; + + switch (event_data->direction) + { + case TO_PAGE_UP: + edit_move_up (edit, w->lines - 1, 1); + break; + case TO_PAGE_DOWN: + edit_move_down (edit, w->lines - 1, 1); + break; + case TO_LEFT: + mc_edit_go_left_cmd (edit); + break; + case TO_RIGHT: + mc_edit_go_right_cmd (edit); + break; + case TO_PAGE_BEGIN: + edit_begin_page (edit); + break; + case TO_PAGE_END: + edit_end_page (edit); + break; + case TO_WORD_BEGIN: + edit->over_col = 0; + edit_left_word_move_cmd (edit); + break; + case TO_WORD_END: + edit->over_col = 0; + edit_right_word_move_cmd (edit); + break; + case TO_UP: + edit_move_up (edit, 1, 0); + break; + case TO_DOWN: + edit_move_down (edit, 1, 0); + break; + case TO_PARAGRAPH_UP: + edit_move_up_paragraph (edit, 0); + break; + case TO_PARAGRAPH_DOWN: + edit_move_down_paragraph (edit, 0); + break; + case TO_SCROLL_UP: + edit_move_up (edit, 1, 1); + break; + case TO_SCROLL_DOWN: + edit_move_down (edit, 1, 1); + break; + case TO_LINE_BEGIN: + edit_cursor_to_bol (edit); + break; + case TO_LINE_END: + edit_cursor_to_eol (edit); + break; + case TO_FILE_BEGIN: + edit_move_to_top (edit); + break; + case TO_FILE_END: + edit_move_to_bottom (edit); + break; + + default:; + } + + edit->is_cursor_moved = TRUE; + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_tab (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + /* if text marked shift block */ + if (edit->mark1 != edit->mark2 && !option_persistent_selections) + { + if (edit->mark2 < 0) + edit_mark_cmd (edit, FALSE); + mc_event_raise (MCEVENT_GROUP_EDITOR, "block_move_to_right", edit, NULL); + + } + else + { + if (option_cursor_beyond_eol) + edit_insert_over (edit); + edit_tab_cmd (edit); + mc_event_raise (MCEVENT_GROUP_EDITOR, "format_paragraph_auto", edit, NULL); + + if (!option_auto_para_formatting) + check_and_wrap_line (edit); + } + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_switch_insert_overwrite (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + edit->overwrite = !edit->overwrite; + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_mark (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + if (edit->mark2 >= 0) + { + if (edit->column_highlight) + edit_push_undo_action (edit, COLUMN_ON); + edit->column_highlight = 0; + } + edit_mark_cmd (edit, FALSE); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_mark_column (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + if (!edit->column_highlight) + edit_push_undo_action (edit, COLUMN_OFF); + edit->column_highlight = 1; + edit_mark_cmd (edit, FALSE); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_mark_all (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + edit_set_markers (edit, 0, edit->buffer.size, 0, 0); + edit->force |= REDRAW_PAGE; + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_unmark (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + if (edit->column_highlight) + edit_push_undo_action (edit, COLUMN_ON); + edit->column_highlight = 0; + edit_mark_cmd (edit, TRUE); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_mark_word (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + if (edit->column_highlight) + edit_push_undo_action (edit, COLUMN_ON); + edit->column_highlight = 0; + edit_mark_current_word_cmd (edit); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_mark_line (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + if (edit->column_highlight) + edit_push_undo_action (edit, COLUMN_ON); + edit->column_highlight = 0; + edit_mark_current_line_cmd (edit); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_bookmark_toggle (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + book_mark_clear (edit, edit->buffer.curs_line, BOOK_MARK_FOUND_COLOR); + if (book_mark_query_color (edit, edit->buffer.curs_line, BOOK_MARK_COLOR)) + book_mark_clear (edit, edit->buffer.curs_line, BOOK_MARK_COLOR); + else + book_mark_insert (edit, edit->buffer.curs_line, BOOK_MARK_COLOR); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_bookmark_flush (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + book_mark_flush (edit, BOOK_MARK_COLOR); + book_mark_flush (edit, BOOK_MARK_FOUND_COLOR); + edit->force |= REDRAW_PAGE; + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_bookmark_next (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + Widget *w = WIDGET (edit); + + (void) event_info; + (void) error; + + if (edit->book_mark != NULL) + { + edit_book_mark_t *p; + + p = book_mark_find (edit, edit->buffer.curs_line); + if (p->next != NULL) + { + p = p->next; + if (p->line >= edit->start_line + w->lines || p->line < edit->start_line) + edit_move_display (edit, p->line - w->lines / 2); + edit_move_to_line (edit, p->line); + } + } + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_bookmark_prev (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + Widget *w = WIDGET (edit); + + (void) event_info; + (void) error; + + if (edit->book_mark != NULL) + { + edit_book_mark_t *p; + + p = book_mark_find (edit, edit->buffer.curs_line); + while (p->line == edit->buffer.curs_line) + if (p->prev != NULL) + p = p->prev; + if (p->line >= 0) + { + if (p->line >= edit->start_line + w->lines || p->line < edit->start_line) + edit_move_display (edit, p->line - w->lines / 2); + edit_move_to_line (edit, p->line); + } + } + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_block_move_to_left (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + off_t start_mark, end_mark; + off_t cur_bol, start_bol; + int i; + + (void) event_info; + (void) error; + + if (edit->mark1 == edit->mark2 || !eval_marks (edit, &start_mark, &end_mark)) + return TRUE; + + start_bol = edit_buffer_get_bol (&edit->buffer, start_mark); + cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1); + + do + { + int del_tab_width; + int next_char; + + edit_cursor_move (edit, cur_bol - edit->buffer.curs1); + + if (option_fake_half_tabs) + del_tab_width = HALF_TAB_SIZE; + else + del_tab_width = option_tab_spacing; + + next_char = edit_buffer_get_current_byte (&edit->buffer); + if (next_char == '\t') + edit_delete (edit, TRUE); + else if (next_char == ' ') + for (i = 1; i <= del_tab_width; i++) + { + if (next_char == ' ') + edit_delete (edit, TRUE); + next_char = edit_buffer_get_current_byte (&edit->buffer); + } + + if (cur_bol == 0) + break; + + cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1); + } + while (cur_bol >= start_bol); + + edit->force |= REDRAW_PAGE; + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_block_move_to_right (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + off_t start_mark, end_mark; + long cur_bol, start_bol; + + (void) event_info; + (void) error; + + if (edit->mark1 == edit->mark2 || !eval_marks (edit, &start_mark, &end_mark)) + return TRUE; + + start_bol = edit_buffer_get_bol (&edit->buffer, start_mark); + cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1); + + do + { + edit_cursor_move (edit, cur_bol - edit->buffer.curs1); + if (!edit_line_is_blank (edit, edit->buffer.curs_line)) + { + if (option_fill_tabs_with_spaces) + insert_spaces_tab (edit, option_fake_half_tabs); + else + edit_insert (edit, '\t'); + edit_cursor_move (edit, + edit_buffer_get_bol (&edit->buffer, cur_bol) - edit->buffer.curs1); + } + + if (cur_bol == 0) + break; + + cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1); + } + while (cur_bol >= start_bol); + + edit->force |= REDRAW_PAGE; + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_complete (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + /* if text marked shift block */ + if (!option_persistent_selections) + mc_event_raise (MCEVENT_GROUP_EDITOR, "block_move_to_left", edit, NULL); + else + edit_complete_word_cmd (edit); + edit->prev_col = edit_get_col (edit); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ +/* TODO: should be implemented as plugin? */ +gboolean +mc_editor_cmd_print_current_date (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + char s[BUF_MEDIUM]; + /* fool gcc to prevent a Y2K warning */ + char time_format[] = "_c"; + + (void) event_info; + (void) error; + time_format[0] = '%'; + + FMT_LOCALTIME_CURRENT (s, sizeof (s), time_format); + edit_print_string (edit, s); + edit->force |= REDRAW_PAGE; + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_goto_matching_bracket (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + off_t q; + + (void) event_info; + (void) error; + + q = edit_get_bracket (edit, 0, 0); + if (q >= 0) + { + edit->bracket = edit->buffer.curs1; + edit->force |= REDRAW_PAGE; + edit_cursor_move (edit, q - edit->buffer.curs1); + } + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/editor/edit.h b/src/editor/edit.h index 0ff0af438..08250e0b1 100644 --- a/src/editor/edit.h +++ b/src/editor/edit.h @@ -63,8 +63,8 @@ extern int show_right_margin; /*** declarations of public functions ************************************************************/ /* used in main() */ -void edit_stack_init (void); -void edit_stack_free (void); +void mc_editor_init (GError ** error); +void mc_editor_deinit (GError ** error); gboolean edit_file (const vfs_path_t * file_vpath, long line); gboolean edit_files (const GList * files); diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c index b0a7f0759..06f56bd8d 100644 --- a/src/editor/editcmd.c +++ b/src/editor/editcmd.c @@ -76,11 +76,8 @@ #include "edit-impl.h" #include "editwidget.h" #include "editcmd_dialogs.h" -#ifdef HAVE_ASPELL -#include "spell.h" -#include "spell_dialogs.h" -#endif #include "etags.h" +#include "event.h" /*** global variables ****************************************************************************/ @@ -504,7 +501,7 @@ edit_save_cmd (WEdit * edit) /* On failure try 'save as', it does locking on its own */ if (res == 0) - return edit_save_as_cmd (edit); + return mc_editor_call_event_save_as (edit); edit->force |= REDRAW_COMPLETELY; if (res > 0) { @@ -574,78 +571,6 @@ edit_delete_column_of_text (WEdit * edit) } } -/* --------------------------------------------------------------------------------------------- */ -/** if success return 0 */ - -static int -edit_block_delete (WEdit * edit) -{ - off_t start_mark, end_mark; - off_t curs_pos; - long curs_line, c1, c2; - - if (!eval_marks (edit, &start_mark, &end_mark)) - return 0; - - if (edit->column_highlight && edit->mark2 < 0) - edit_mark_cmd (edit, FALSE); - if ((end_mark - start_mark) > option_max_undo / 2) - { - /* Warning message with a query to continue or cancel the operation */ - if (edit_query_dialog2 - (_("Warning"), - _ - ("Block is large, you may not be able to undo this action"), - _("C&ontinue"), _("&Cancel"))) - { - return 1; - } - } - c1 = min (edit->column1, edit->column2); - c2 = max (edit->column1, edit->column2); - edit->column1 = c1; - edit->column2 = c2; - - edit_push_markers (edit); - - curs_line = edit->buffer.curs_line; - - curs_pos = edit->curs_col + edit->over_col; - - /* move cursor to start of selection */ - edit_cursor_move (edit, start_mark - edit->buffer.curs1); - edit_scroll_screen_over_cursor (edit); - - if (start_mark < end_mark) - { - if (edit->column_highlight) - { - off_t line_width; - - if (edit->mark2 < 0) - edit_mark_cmd (edit, FALSE); - edit_delete_column_of_text (edit); - /* move cursor to the saved position */ - edit_move_to_line (edit, curs_line); - /* calculate line width and cursor position before cut */ - line_width = edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, - edit_buffer_get_current_eol (&edit->buffer)); - if (option_cursor_beyond_eol && curs_pos > line_width) - edit->over_col = curs_pos - line_width; - } - else - { - off_t count; - - for (count = start_mark; count < end_mark; count++) - edit_delete (edit, TRUE); - } - } - edit_set_markers (edit, 0, 0, 0, 0); - edit->force |= REDRAW_PAGE; - return 0; -} - /* --------------------------------------------------------------------------------------------- */ /** * Get EOL symbol for searching. @@ -1595,20 +1520,51 @@ edit_set_filename (WEdit * edit, const vfs_path_t * name_vpath) } /* --------------------------------------------------------------------------------------------- */ -/* Here we want to warn the users of overwriting an existing file, - but only if they have made a change to the filename */ -/* returns TRUE on success */ +/** + * The proxy function for calling "save_as" event. + */ + gboolean -edit_save_as_cmd (WEdit * edit) +mc_editor_call_event_save_as (WEdit * edit) { - /* This heads the 'Save As' dialog box */ + mc_editor_event_data_ret_boolean_t event_data = { + .editor = edit + }; + + mc_event_raise (MCEVENT_GROUP_EDITOR, "save_as", &event_data, NULL); + return event_data.return_value; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ +/** + * Here we want to warn the users of overwriting an existing file, + * but only if they have made a change to the filename + * + * return value stored to mc_editor_event_data_ret_boolean_t->return_value + * returns TRUE on success + */ + +gboolean +mc_editor_cmd_save_as (event_info_t * event_info, gpointer data, GError ** error) +{ + mc_editor_event_data_ret_boolean_t *event_data = (mc_editor_event_data_ret_boolean_t *) data; + WEdit *edit = (WEdit *) event_data->editor; + vfs_path_t *exp_vpath; int save_lock = 0; int different_filename = 0; - if (!edit_check_newline (&edit->buffer)) - return FALSE; + (void) event_info; + (void) error; + /* This heads the 'Save As' dialog box */ + + if (!edit_check_newline (&edit->buffer)) + { + event_data->return_value = FALSE; + return TRUE; + } exp_vpath = edit_get_save_file_as (edit); edit_push_undo_action (edit, KEY_PRESS + edit->start_display); @@ -1695,6 +1651,7 @@ edit_save_as_cmd (WEdit * edit) edit_load_syntax (edit, NULL, edit->syntax_type); vfs_path_free (exp_vpath); edit->force |= REDRAW_COMPLETELY; + event_data->return_value = TRUE; return TRUE; default: edit_error_dialog (_("Save as"), get_sys_error (_("Cannot save file"))); @@ -1711,20 +1668,26 @@ edit_save_as_cmd (WEdit * edit) ret: vfs_path_free (exp_vpath); edit->force |= REDRAW_COMPLETELY; - return FALSE; + event_data->return_value = FALSE; + return TRUE; } /* --------------------------------------------------------------------------------------------- */ -/** returns TRUE on success */ +/* event callback */ gboolean -edit_save_confirm_cmd (WEdit * edit) +mc_editor_cmd_save_confirm (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + if (edit->filename_vpath == NULL) - return edit_save_as_cmd (edit); + return mc_editor_call_event_save_as (edit); if (!edit_check_newline (&edit->buffer)) - return FALSE; + return TRUE; if (edit_confirm_save) { @@ -1736,9 +1699,10 @@ edit_save_confirm_cmd (WEdit * edit) ok = (edit_query_dialog2 (_("Save file"), f, _("&Save"), _("&Cancel")) == 0); g_free (f); if (!ok) - return FALSE; + return TRUE; } - return edit_save_cmd (edit); + (void) edit_save_cmd (edit); + return TRUE; } /* --------------------------------------------------------------------------------------------- */ @@ -1984,179 +1948,15 @@ eval_marks (WEdit * edit, off_t * start_mark, off_t * end_mark) } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -void -edit_block_copy_cmd (WEdit * edit) +gboolean +mc_editor_cmd_replace (event_info_t * event_info, gpointer data, GError ** error) { - off_t start_mark, end_mark, current = edit->buffer.curs1; - off_t mark1, mark2; - long c1, c2; - off_t size; - unsigned char *copy_buf; + WEdit *edit = (WEdit *) data; + /** call with edit = 0 before shutdown to close memory leaks */ + gboolean again = (gboolean) (intptr_t) event_info->init_data; - edit_update_curs_col (edit); - if (!eval_marks (edit, &start_mark, &end_mark)) - return; - - copy_buf = edit_get_block (edit, start_mark, end_mark, &size); - - /* all that gets pushed are deletes hence little space is used on the stack */ - - edit_push_markers (edit); - - if (edit->column_highlight) - { - long col_delta; - - col_delta = abs (edit->column2 - edit->column1); - edit_insert_column_of_text (edit, copy_buf, size, col_delta, &mark1, &mark2, &c1, &c2); - } - else - { - int size_orig = size; - - while (size-- != 0) - edit_insert_ahead (edit, copy_buf[size]); - - /* Place cursor at the end of text selection */ - if (option_cursor_after_inserted_block) - edit_cursor_move (edit, size_orig); - } - - g_free (copy_buf); - edit_scroll_screen_over_cursor (edit); - - if (edit->column_highlight) - edit_set_markers (edit, edit->buffer.curs1, mark2, c1, c2); - else if (start_mark < current && end_mark > current) - edit_set_markers (edit, start_mark, end_mark + end_mark - start_mark, 0, 0); - - edit->force |= REDRAW_PAGE; -} - - -/* --------------------------------------------------------------------------------------------- */ - -void -edit_block_move_cmd (WEdit * edit) -{ - off_t current; - unsigned char *copy_buf = NULL; - off_t start_mark, end_mark; - - if (!eval_marks (edit, &start_mark, &end_mark)) - return; - - if (!edit->column_highlight && edit->buffer.curs1 > start_mark && edit->buffer.curs1 < end_mark) - return; - - if (edit->mark2 < 0) - edit_mark_cmd (edit, FALSE); - edit_push_markers (edit); - - if (edit->column_highlight) - { - off_t mark1, mark2; - off_t size; - long c1, c2, b_width; - long x, x2; - - c1 = min (edit->column1, edit->column2); - c2 = max (edit->column1, edit->column2); - b_width = c2 - c1; - - edit_update_curs_col (edit); - - x = edit->curs_col; - x2 = x + edit->over_col; - - /* do nothing when cursor inside first line of selected area */ - if ((edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1) == - edit_buffer_get_eol (&edit->buffer, start_mark)) && x2 > c1 && x2 <= c2) - return; - - if (edit->buffer.curs1 > start_mark - && edit->buffer.curs1 < edit_buffer_get_eol (&edit->buffer, end_mark)) - { - if (x > c2) - x -= b_width; - else if (x > c1 && x <= c2) - x = c1; - } - /* save current selection into buffer */ - copy_buf = edit_get_block (edit, start_mark, end_mark, &size); - - /* remove current selection */ - edit_block_delete_cmd (edit); - - edit->over_col = max (0, edit->over_col - b_width); - /* calculate the cursor pos after delete block */ - current = edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), x, 0); - edit_cursor_move (edit, current - edit->buffer.curs1); - edit_scroll_screen_over_cursor (edit); - - /* add TWS if need before block insertion */ - if (option_cursor_beyond_eol && edit->over_col > 0) - edit_insert_over (edit); - - edit_insert_column_of_text (edit, copy_buf, size, b_width, &mark1, &mark2, &c1, &c2); - edit_set_markers (edit, mark1, mark2, c1, c2); - } - else - { - off_t count, count_orig; - - current = edit->buffer.curs1; - copy_buf = g_malloc0 (end_mark - start_mark); - edit_cursor_move (edit, start_mark - edit->buffer.curs1); - edit_scroll_screen_over_cursor (edit); - - for (count = start_mark; count < end_mark; count++) - copy_buf[end_mark - count - 1] = edit_delete (edit, TRUE); - - edit_scroll_screen_over_cursor (edit); - edit_cursor_move (edit, - current - edit->buffer.curs1 - - (((current - edit->buffer.curs1) > 0) ? end_mark - start_mark : 0)); - edit_scroll_screen_over_cursor (edit); - count_orig = count; - while (count-- > start_mark) - edit_insert_ahead (edit, copy_buf[end_mark - count - 1]); - - edit_set_markers (edit, edit->buffer.curs1, edit->buffer.curs1 + end_mark - start_mark, 0, - 0); - - /* Place cursor at the end of text selection */ - if (option_cursor_after_inserted_block) - edit_cursor_move (edit, count_orig - start_mark); - } - - edit_scroll_screen_over_cursor (edit); - g_free (copy_buf); - edit->force |= REDRAW_PAGE; -} - -/* --------------------------------------------------------------------------------------------- */ -/** returns 1 if canceelled by user */ - -int -edit_block_delete_cmd (WEdit * edit) -{ - off_t start_mark, end_mark; - - if (eval_marks (edit, &start_mark, &end_mark)) - return edit_block_delete (edit); - - edit_delete_line (edit); - return 0; -} - -/* --------------------------------------------------------------------------------------------- */ -/** call with edit = 0 before shutdown to close memory leaks */ - -void -edit_replace_cmd (WEdit * edit, int again) -{ /* 1 = search string, 2 = replace with */ static char *saved1 = NULL; /* saved default[123] */ static char *saved2 = NULL; @@ -2169,11 +1969,13 @@ edit_replace_cmd (WEdit * edit, int again) gboolean once_found = FALSE; edit_search_status_msg_t esm; + (void) error; + if (edit == NULL) { MC_PTR_FREE (saved1); MC_PTR_FREE (saved2); - return; + return TRUE; } edit->force |= REDRAW_COMPLETELY; @@ -2395,6 +2197,9 @@ edit_replace_cmd (WEdit * edit, int again) g_free (input2); if (input2_str != NULL) g_string_free (input2_str, TRUE); + + edit->prev_col = edit_get_col (edit); + return TRUE; } /* --------------------------------------------------------------------------------------------- */ @@ -2421,13 +2226,18 @@ edit_search_update_callback (const void *user_data, gsize char_offset) } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -void -edit_search_cmd (WEdit * edit, gboolean again) +gboolean +mc_editor_cmd_search (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + gboolean again = (gboolean) (intptr_t) event_info->init_data; + + (void) error; if (edit == NULL) - return; + return FALSE; if (!again) edit_search (edit); @@ -2478,6 +2288,10 @@ edit_search_cmd (WEdit * edit, gboolean again) edit_search (edit); } } + + edit->prev_col = edit_get_col (edit); + + return TRUE; } @@ -2607,21 +2421,32 @@ edit_save_block (WEdit * edit, const char *filename, off_t start, off_t finish) } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -void -edit_paste_from_history (WEdit * edit) +gboolean +mc_editor_cmd_paste_from_history (event_info_t * event_info, gpointer data, GError ** error) { - (void) edit; + (void) event_info; + (void) data; + (void) error; edit_error_dialog (_("Error"), _("This function is not implemented")); + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ gboolean -edit_copy_to_X_buf_cmd (WEdit * edit) +mc_editor_cmd_ext_clip_copy (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + off_t start_mark, end_mark; + (void) event_info; + (void) error; + if (!eval_marks (edit, &start_mark, &end_mark)) return TRUE; @@ -2640,78 +2465,105 @@ edit_copy_to_X_buf_cmd (WEdit * edit) } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ gboolean -edit_cut_to_X_buf_cmd (WEdit * edit) +mc_editor_cmd_ext_clip_cut (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + off_t start_mark, end_mark; + (void) event_info; + (void) error; + if (!eval_marks (edit, &start_mark, &end_mark)) return TRUE; if (!edit_save_block_to_clip_file (edit, start_mark, end_mark)) { edit_error_dialog (_("Cut to clipboard"), _("Unable to save to file")); - return FALSE; + return TRUE; } /* try use external clipboard utility */ mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL, NULL); - edit_block_delete_cmd (edit); + mc_editor_call_event_block_delete (edit); edit_mark_cmd (edit, TRUE); return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ gboolean -edit_paste_from_X_buf_cmd (WEdit * edit) +mc_editor_cmd_ext_clip_paste (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + vfs_path_t *tmp; - gboolean ret; + + (void) event_info; + (void) error; + + if (!option_persistent_selections && edit->mark1 != edit->mark2) + mc_editor_call_event_block_delete (edit); + if (option_cursor_beyond_eol && edit->over_col > 0) + edit_insert_over (edit); /* try use external clipboard utility */ mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_from_ext_clip", NULL, NULL); tmp = mc_config_get_full_vpath (EDIT_CLIP_FILE); - ret = (edit_insert_file (edit, tmp) >= 0); + edit_insert_file (edit, tmp); vfs_path_free (tmp); - return ret; + if (!option_persistent_selections && edit->mark2 >= 0) + { + if (edit->column_highlight) + edit_push_undo_action (edit, COLUMN_ON); + edit->column_highlight = 0; + edit_mark_cmd (edit, TRUE); + } + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ /** * Ask user for the line and go to that line. * Negative numbers mean line from the end (i.e. -1 is the last line). */ -void -edit_goto_cmd (WEdit * edit) +gboolean +mc_editor_cmd_goto_line (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + char *f; static long line = 0; /* line as typed, saved as default */ long l; - char *error; + char *error_str; char s[32]; + (void) event_info; + (void) error; + g_snprintf (s, sizeof (s), "%ld", line); f = input_dialog (_("Goto line"), _("Enter line:"), MC_HISTORY_EDIT_GOTO_LINE, line ? s : "", INPUT_COMPLETE_NONE); - if (!f) - return; - - if (!*f) + if (f == NULL || *f == '\0') { g_free (f); - return; + return TRUE; } - l = strtol (f, &error, 0); - if (*error) + l = strtol (f, &error_str, 0); + if (*error_str != '\0') { g_free (f); - return; + return TRUE; } line = l; @@ -2721,18 +2573,24 @@ edit_goto_cmd (WEdit * edit) edit_move_to_line (edit, l - 1); edit->force |= REDRAW_COMPLETELY; g_free (f); + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ -/** Return TRUE on success */ +/* event callback */ gboolean -edit_save_block_cmd (WEdit * edit) +mc_editor_cmd_save_block (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + off_t start_mark, end_mark; char *exp, *tmp; - gboolean ret = FALSE; + + (void) event_info; + (void) error; if (!eval_marks (edit, &start_mark, &end_mark)) return TRUE; @@ -2746,9 +2604,7 @@ edit_save_block_cmd (WEdit * edit) if (exp != NULL && *exp != '\0') { - if (edit_save_block (edit, exp, start_mark, end_mark)) - ret = TRUE; - else + if (!edit_save_block (edit, exp, start_mark, end_mark)) edit_error_dialog (_("Save block"), get_sys_error (_("Cannot save file"))); edit->force |= REDRAW_COMPLETELY; @@ -2756,19 +2612,22 @@ edit_save_block_cmd (WEdit * edit) g_free (exp); - return ret; + return TRUE; } - /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -/** returns TRUE on success */ gboolean -edit_insert_file_cmd (WEdit * edit) +mc_editor_cmd_insert_file (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + char *tmp; char *exp; - gboolean ret = FALSE; + + (void) event_info; + (void) error; tmp = mc_config_get_full_path (EDIT_CLIP_FILE); exp = input_expand_dialog (_("Insert file"), _("Enter file name:"), @@ -2782,34 +2641,39 @@ edit_insert_file_cmd (WEdit * edit) vfs_path_t *exp_vpath; exp_vpath = vfs_path_from_str (exp); - ret = (edit_insert_file (edit, exp_vpath) >= 0); - vfs_path_free (exp_vpath); - - if (!ret) + if (edit_insert_file (edit, exp_vpath) < 0) edit_error_dialog (_("Insert file"), get_sys_error (_("Cannot insert file"))); + vfs_path_free (exp_vpath); } g_free (exp); edit->force |= REDRAW_COMPLETELY; - return ret; + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ /** sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */ -int -edit_sort_cmd (WEdit * edit) +gboolean +mc_editor_cmd_sort (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + static char *old = 0; char *exp, *tmp, *tmp_edit_block_name, *tmp_edit_temp_name; off_t start_mark, end_mark; int e; + (void) event_info; + (void) error; + if (!eval_marks (edit, &start_mark, &end_mark)) { edit_error_dialog (_("Sort block"), _("You must first highlight a block of text")); - return 0; + return TRUE; } tmp = mc_config_get_full_path (EDIT_BLOCK_FILE); @@ -2820,64 +2684,71 @@ edit_sort_cmd (WEdit * edit) _("Enter sort options (see manpage) separated by whitespace:"), MC_HISTORY_EDIT_SORT, (old != NULL) ? old : "", INPUT_COMPLETE_NONE); - if (!exp) - return 1; g_free (old); - old = exp; - tmp_edit_block_name = mc_config_get_full_path (EDIT_BLOCK_FILE); - tmp_edit_temp_name = mc_config_get_full_path (EDIT_TEMP_FILE); - tmp = - g_strconcat (" sort ", exp, " ", tmp_edit_block_name, - " > ", tmp_edit_temp_name, (char *) NULL); - g_free (tmp_edit_temp_name); - g_free (tmp_edit_block_name); - e = system (tmp); - g_free (tmp); - if (e) + if (exp != NULL) { - if (e == -1 || e == 127) + old = exp; + tmp_edit_block_name = mc_config_get_full_path (EDIT_BLOCK_FILE); + tmp_edit_temp_name = mc_config_get_full_path (EDIT_TEMP_FILE); + tmp = + g_strconcat (" sort ", exp, " ", tmp_edit_block_name, + " > ", tmp_edit_temp_name, (char *) NULL); + g_free (tmp_edit_temp_name); + g_free (tmp_edit_block_name); + + e = system (tmp); + g_free (tmp); + if (e) { - edit_error_dialog (_("Sort"), get_sys_error (_("Cannot execute sort command"))); + if (e == -1 || e == 127) + { + edit_error_dialog (_("Sort"), get_sys_error (_("Cannot execute sort command"))); + } + else + { + char q[BUF_TINY]; + sprintf (q, "%d ", e); + tmp = g_strdup_printf (_("Sort returned non-zero: %s"), q); + edit_error_dialog (_("Sort"), tmp); + g_free (tmp); + } + return TRUE; } - else + + edit->force |= REDRAW_COMPLETELY; + + if (!mc_editor_call_event_block_delete (edit)) { - char q[8]; - sprintf (q, "%d ", e); - tmp = g_strdup_printf (_("Sort returned non-zero: %s"), q); - edit_error_dialog (_("Sort"), tmp); - g_free (tmp); + vfs_path_t *tmp_vpath; + + tmp_vpath = mc_config_get_full_vpath (EDIT_TEMP_FILE); + edit_insert_file (edit, tmp_vpath); + vfs_path_free (tmp_vpath); } - return -1; } - edit->force |= REDRAW_COMPLETELY; - - if (edit_block_delete_cmd (edit)) - return 1; - - { - vfs_path_t *tmp_vpath; - - tmp_vpath = mc_config_get_full_vpath (EDIT_TEMP_FILE); - edit_insert_file (edit, tmp_vpath); - vfs_path_free (tmp_vpath); - } - return 0; + return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ /** * Ask user for a command, execute it and paste its output back to the * editor. */ -int -edit_ext_cmd (WEdit * edit) +gboolean +mc_editor_cmd_run_external_command (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + char *exp, *tmp, *tmp_edit_temp_file; int e; + (void) event_info; + (void) error; + exp = input_dialog (_("Paste output of external command"), _("Enter shell command(s):"), MC_HISTORY_EDIT_PASTE_EXTCMD, NULL, @@ -2885,32 +2756,33 @@ edit_ext_cmd (WEdit * edit) | INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_CD | INPUT_COMPLETE_COMMANDS | INPUT_COMPLETE_SHELL_ESC); - if (!exp) - return 1; - - tmp_edit_temp_file = mc_config_get_full_path (EDIT_TEMP_FILE); - tmp = g_strconcat (exp, " > ", tmp_edit_temp_file, (char *) NULL); - g_free (tmp_edit_temp_file); - e = system (tmp); - g_free (tmp); - g_free (exp); - - if (e) + if (exp != NULL) { - edit_error_dialog (_("External command"), get_sys_error (_("Cannot execute command"))); - return -1; + + tmp_edit_temp_file = mc_config_get_full_path (EDIT_TEMP_FILE); + tmp = g_strconcat (exp, " > ", tmp_edit_temp_file, (char *) NULL); + g_free (tmp_edit_temp_file); + e = system (tmp); + g_free (tmp); + g_free (exp); + + if (e != 0) + { + edit_error_dialog (_("External command"), get_sys_error (_("Cannot execute command"))); + return TRUE; + } + + edit->force |= REDRAW_COMPLETELY; + + { + vfs_path_t *tmp_vpath; + + tmp_vpath = mc_config_get_full_vpath (EDIT_TEMP_FILE); + edit_insert_file (edit, tmp_vpath); + vfs_path_free (tmp_vpath); + } } - - edit->force |= REDRAW_COMPLETELY; - - { - vfs_path_t *tmp_vpath; - - tmp_vpath = mc_config_get_full_vpath (EDIT_TEMP_FILE); - edit_insert_file (edit, tmp_vpath); - vfs_path_free (tmp_vpath); - } - return 0; + return TRUE; } /* --------------------------------------------------------------------------------------------- */ @@ -2926,17 +2798,20 @@ edit_block_process_cmd (WEdit * edit, int macro_number) fname = g_strdup_printf ("%s.%i.sh", MC_EXTMACRO_FILE, macro_number); macros_fname = g_build_filename (mc_config_get_data_path (), fname, (char *) NULL); - user_menu (edit, macros_fname, 0); + mc_editor_call_event_user_menu (edit, macros_fname, 0); g_free (fname); g_free (macros_fname); edit->force |= REDRAW_COMPLETELY; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -void -edit_mail_dialog (WEdit * edit) +gboolean +mc_editor_cmd_mail (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + char *tmail_to = NULL; char *tmail_subject = NULL; char *tmail_cc = NULL; @@ -2969,6 +2844,9 @@ edit_mail_dialog (WEdit * edit) quick_widgets, NULL, NULL }; + (void) event_info; + (void) error; + if (quick_dialog (&qdlg) != B_CANCEL) { g_free (mail_cc_last); @@ -2979,6 +2857,8 @@ edit_mail_dialog (WEdit * edit) mail_to_last = tmail_to; pipe_mail (&edit->buffer, mail_to_last, mail_subject_last, mail_cc_last); } + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ @@ -3052,36 +2932,59 @@ edit_complete_word_cmd (WEdit * edit) } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ #ifdef HAVE_CHARSET -void -edit_select_codepage_cmd (WEdit * edit) + +gboolean +mc_editor_cmd_select_codepage (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + if (do_select_codepage ()) edit_set_codeset (edit); edit->force = REDRAW_PAGE; widget_redraw (WIDGET (edit)); + + return TRUE; } #endif /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -void -edit_insert_literal_cmd (WEdit * edit) +gboolean +mc_editor_cmd_insert_literal (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + int char_for_insertion; + (void) event_info; + (void) error; + char_for_insertion = editcmd_dialog_raw_key_query (_("Insert literal"), _("Press any key:"), FALSE); edit_execute_key_command (edit, -1, ascii_alpha_to_cntrl (char_for_insertion)); + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ gboolean -edit_load_forward_cmd (WEdit * edit) +mc_editor_cmd_file_load_next (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + if (edit->modified && edit_query_dialog2 (_("Warning"), _("Current text was modified without a file save.\n" @@ -3092,25 +2995,28 @@ edit_load_forward_cmd (WEdit * edit) return TRUE; } - if (edit_stack_iterator + 1 >= MAX_HISTORY_MOVETO) - return FALSE; - - if (edit_history_moveto[edit_stack_iterator + 1].line < 1) - return FALSE; - - edit_stack_iterator++; - if (edit_history_moveto[edit_stack_iterator].filename_vpath != NULL) - return edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath, - edit_history_moveto[edit_stack_iterator].line); - - return FALSE; + if (edit_stack_iterator + 1 < MAX_HISTORY_MOVETO + && edit_history_moveto[edit_stack_iterator + 1].line >= 1) + { + edit_stack_iterator++; + if (edit_history_moveto[edit_stack_iterator].filename_vpath != NULL) + edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath, + edit_history_moveto[edit_stack_iterator].line); + } + return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ gboolean -edit_load_back_cmd (WEdit * edit) +mc_editor_cmd_file_load_prev (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + if (edit->modified && edit_query_dialog2 (_("Warning"), _("Current text was modified without a file save.\n" @@ -3122,22 +3028,24 @@ edit_load_back_cmd (WEdit * edit) } /* we are in the bottom of the stack, NO WAY! */ - if (edit_stack_iterator == 0) - return FALSE; - - edit_stack_iterator--; - if (edit_history_moveto[edit_stack_iterator].filename_vpath != NULL) - return edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath, - edit_history_moveto[edit_stack_iterator].line); - - return FALSE; + if (edit_stack_iterator != 0) + { + edit_stack_iterator--; + if (edit_history_moveto[edit_stack_iterator].filename_vpath != NULL) + edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath, + edit_history_moveto[edit_stack_iterator].line); + } + return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -void -edit_get_match_keyword_cmd (WEdit * edit) +gboolean +mc_editor_cmd_match_keyword (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + gsize word_len = 0, max_len = 0; int num_def = 0; gsize i; @@ -3149,6 +3057,9 @@ edit_get_match_keyword_cmd (WEdit * edit) etags_hash_t def_hash[MAX_DEFINITIONS]; + (void) event_info; + (void) error; + for (i = 0; i < MAX_DEFINITIONS; i++) { def_hash[i].filename = NULL; @@ -3156,7 +3067,7 @@ edit_get_match_keyword_cmd (WEdit * edit) /* search start of word to be completed */ if (!edit_find_word_start (&edit->buffer, &word_start, &word_len)) - return; + return TRUE; /* prepare match expression */ match_expr = g_string_sized_new (word_len); @@ -3196,141 +3107,284 @@ edit_get_match_keyword_cmd (WEdit * edit) (etags_hash_t *) & def_hash, num_def); } g_string_free (match_expr, TRUE); + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/** + * The proxy function for calling "block_delete" event. + */ -#ifdef HAVE_ASPELL -int -edit_suggest_current_word (WEdit * edit) +gboolean +mc_editor_call_event_block_delete (WEdit * edit) { - gsize cut_len = 0; - gsize word_len = 0; - off_t word_start = 0; - int retval = B_SKIP_WORD; - GString *match_word; + mc_editor_event_data_ret_boolean_t event_data = { + .editor = edit + }; - /* search start of word to spell check */ - match_word = edit_buffer_get_word_from_pos (&edit->buffer, edit->buffer.curs1, &word_start, - &cut_len); - word_len = match_word->len; + mc_event_raise (MCEVENT_GROUP_EDITOR, "block_delete", &event_data, NULL); + return event_data.return_value; +} -#ifdef HAVE_CHARSET - if (mc_global.source_codepage >= 0 && (mc_global.source_codepage != mc_global.display_codepage)) +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_block_copy (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + off_t start_mark, end_mark, current = edit->buffer.curs1; + off_t mark1, mark2; + long c1, c2; + off_t size; + unsigned char *copy_buf; + + + (void) event_info; + (void) error; + + if (option_cursor_beyond_eol && edit->over_col > 0) + edit_insert_over (edit); + + + edit_update_curs_col (edit); + if (!eval_marks (edit, &start_mark, &end_mark)) + return TRUE; + + copy_buf = edit_get_block (edit, start_mark, end_mark, &size); + + /* all that gets pushed are deletes hence little space is used on the stack */ + + edit_push_markers (edit); + + if (edit->column_highlight) { - GString *tmp_word; + long col_delta; - tmp_word = str_convert_to_display (match_word->str); - g_string_free (match_word, TRUE); - match_word = tmp_word; + col_delta = abs (edit->column2 - edit->column1); + edit_insert_column_of_text (edit, copy_buf, size, col_delta, &mark1, &mark2, &c1, &c2); } -#endif - if (!aspell_check (match_word->str, (int) word_len)) + else { - GArray *suggest; - unsigned int res; + int size_orig = size; - suggest = g_array_new (TRUE, FALSE, sizeof (char *)); + while (size-- != 0) + edit_insert_ahead (edit, copy_buf[size]); - res = aspell_suggest (suggest, match_word->str, (int) word_len); - if (res != 0) + /* Place cursor at the end of text selection */ + if (option_cursor_after_inserted_block) + edit_cursor_move (edit, size_orig); + } + + g_free (copy_buf); + edit_scroll_screen_over_cursor (edit); + + if (edit->column_highlight) + edit_set_markers (edit, edit->buffer.curs1, mark2, c1, c2); + else if (start_mark < current && end_mark > current) + edit_set_markers (edit, start_mark, end_mark + end_mark - start_mark, 0, 0); + + edit->force |= REDRAW_PAGE; + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ +/** + * return value stored to mc_editor_event_data_ret_boolean_t->return_value + */ +gboolean +mc_editor_cmd_block_delete (event_info_t * event_info, gpointer data, GError ** error) +{ + mc_editor_event_data_ret_boolean_t *event_data = (mc_editor_event_data_ret_boolean_t *) data; + WEdit *edit = (WEdit *) event_data->editor; + + off_t start_mark, end_mark; + + (void) event_info; + (void) error; + + if (eval_marks (edit, &start_mark, &end_mark)) + { + off_t curs_pos; + long curs_line, c1, c2; + + if (edit->column_highlight && edit->mark2 < 0) + edit_mark_cmd (edit, FALSE); + if ((end_mark - start_mark) > option_max_undo / 2) { - char *new_word = NULL; - - edit->found_start = word_start; - edit->found_len = word_len; - edit->force |= REDRAW_PAGE; - edit_scroll_screen_over_cursor (edit); - edit_render_keypress (edit); - - retval = spell_dialog_spell_suggest_show (edit, match_word->str, &new_word, suggest); - edit_cursor_move (edit, word_len - cut_len); - - if (retval == B_ENTER && new_word != NULL) + /* Warning message with a query to continue or cancel the operation */ + if (edit_query_dialog2 + (_("Warning"), + _ + ("Block is large, you may not be able to undo this action"), + _("C&ontinue"), _("&Cancel"))) { - guint i; - char *cp_word; - -#ifdef HAVE_CHARSET - if (mc_global.source_codepage >= 0 && - (mc_global.source_codepage != mc_global.display_codepage)) - { - GString *tmp_word; - - tmp_word = str_convert_to_input (new_word); - g_free (new_word); - new_word = g_string_free (tmp_word, FALSE); - } -#endif - cp_word = new_word; - for (i = 0; i < word_len; i++) - edit_backspace (edit, TRUE); - for (; *new_word; new_word++) - edit_insert (edit, *new_word); - g_free (cp_word); + event_data->return_value = TRUE; + return TRUE; } - else if (retval == B_ADD_WORD && match_word != NULL) - aspell_add_to_dict (match_word->str, (int) word_len); } + c1 = min (edit->column1, edit->column2); + c2 = max (edit->column1, edit->column2); + edit->column1 = c1; + edit->column2 = c2; - g_array_free (suggest, TRUE); - edit->found_start = 0; - edit->found_len = 0; - } - g_string_free (match_word, TRUE); - return retval; -} + edit_push_markers (edit); -/* --------------------------------------------------------------------------------------------- */ + curs_line = edit->buffer.curs_line; -void -edit_spellcheck_file (WEdit * edit) -{ - if (edit->buffer.curs_line > 0) - { - edit_cursor_move (edit, -edit->buffer.curs1); - edit_move_to_prev_col (edit, 0); - edit_update_curs_row (edit); - } + curs_pos = edit->curs_col + edit->over_col; - do - { - int c1, c2; + /* move cursor to start of selection */ + edit_cursor_move (edit, start_mark - edit->buffer.curs1); + edit_scroll_screen_over_cursor (edit); - c2 = edit_buffer_get_current_byte (&edit->buffer); - - do + if (start_mark < end_mark) { - if (edit->buffer.curs1 >= edit->buffer.size) - return; + if (edit->column_highlight) + { + off_t line_width; - c1 = c2; - edit_cursor_move (edit, 1); - c2 = edit_buffer_get_current_byte (&edit->buffer); + if (edit->mark2 < 0) + edit_mark_cmd (edit, FALSE); + edit_delete_column_of_text (edit); + /* move cursor to the saved position */ + edit_move_to_line (edit, curs_line); + /* calculate line width and cursor position before cut */ + line_width = + edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, + edit_buffer_get_current_eol (&edit->buffer)); + if (option_cursor_beyond_eol && curs_pos > line_width) + edit->over_col = curs_pos - line_width; + } + else + { + off_t count; + + for (count = start_mark; count < end_mark; count++) + edit_delete (edit, TRUE); + } } - while (is_break_char (c1) || is_break_char (c2)); + edit_set_markers (edit, 0, 0, 0, 0); + edit->force |= REDRAW_PAGE; } - while (edit_suggest_current_word (edit) != B_CANCEL); + else + mc_event_raise (MCEVENT_GROUP_EDITOR, "delete_line", edit, NULL); + event_data->return_value = FALSE; + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -void -edit_set_spell_lang (void) +gboolean +mc_editor_cmd_block_move (event_info_t * event_info, gpointer data, GError ** error) { - GArray *lang_list; + WEdit *edit = (WEdit *) data; - lang_list = g_array_new (TRUE, FALSE, sizeof (char *)); - if (aspell_get_lang_list (lang_list) != 0) + off_t current; + unsigned char *copy_buf = NULL; + off_t start_mark, end_mark; + + (void) event_info; + (void) error; + + if (!eval_marks (edit, &start_mark, &end_mark)) + return TRUE; + + if (!edit->column_highlight && edit->buffer.curs1 > start_mark && edit->buffer.curs1 < end_mark) + return TRUE; + + if (edit->mark2 < 0) + edit_mark_cmd (edit, FALSE); + edit_push_markers (edit); + + if (edit->column_highlight) { - char *lang; + off_t mark1, mark2; + off_t size; + long c1, c2, b_width; + long x, x2; - lang = spell_dialog_lang_list_show (lang_list); - if (lang != NULL) - (void) aspell_set_lang (lang); + c1 = min (edit->column1, edit->column2); + c2 = max (edit->column1, edit->column2); + b_width = c2 - c1; + + edit_update_curs_col (edit); + + x = edit->curs_col; + x2 = x + edit->over_col; + + /* do nothing when cursor inside first line of selected area */ + if ((edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1) == + edit_buffer_get_eol (&edit->buffer, start_mark)) && x2 > c1 && x2 <= c2) + return TRUE; + + if (edit->buffer.curs1 > start_mark + && edit->buffer.curs1 < edit_buffer_get_eol (&edit->buffer, end_mark)) + { + if (x > c2) + x -= b_width; + else if (x > c1 && x <= c2) + x = c1; + } + /* save current selection into buffer */ + copy_buf = edit_get_block (edit, start_mark, end_mark, &size); + + /* remove current selection */ + mc_editor_call_event_block_delete (edit); + + edit->over_col = max (0, edit->over_col - b_width); + /* calculate the cursor pos after delete block */ + current = edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), x, 0); + edit_cursor_move (edit, current - edit->buffer.curs1); + edit_scroll_screen_over_cursor (edit); + + /* add TWS if need before block insertion */ + if (option_cursor_beyond_eol && edit->over_col > 0) + edit_insert_over (edit); + + edit_insert_column_of_text (edit, copy_buf, size, b_width, &mark1, &mark2, &c1, &c2); + edit_set_markers (edit, mark1, mark2, c1, c2); } - aspell_array_clean (lang_list); + else + { + off_t count, count_orig; + + current = edit->buffer.curs1; + copy_buf = g_malloc0 (end_mark - start_mark); + edit_cursor_move (edit, start_mark - edit->buffer.curs1); + edit_scroll_screen_over_cursor (edit); + + for (count = start_mark; count < end_mark; count++) + copy_buf[end_mark - count - 1] = edit_delete (edit, TRUE); + + edit_scroll_screen_over_cursor (edit); + edit_cursor_move (edit, + current - edit->buffer.curs1 - + (((current - edit->buffer.curs1) > 0) ? end_mark - start_mark : 0)); + edit_scroll_screen_over_cursor (edit); + count_orig = count; + while (count-- > start_mark) + edit_insert_ahead (edit, copy_buf[end_mark - count - 1]); + + edit_set_markers (edit, edit->buffer.curs1, edit->buffer.curs1 + end_mark - start_mark, 0, + 0); + + /* Place cursor at the end of text selection */ + if (option_cursor_after_inserted_block) + edit_cursor_move (edit, count_orig - start_mark); + } + + edit_scroll_screen_over_cursor (edit); + g_free (copy_buf); + edit->force |= REDRAW_PAGE; + + return TRUE; } -#endif /* HAVE_ASPELL */ /* --------------------------------------------------------------------------------------------- */ diff --git a/src/editor/editwidget.c b/src/editor/editwidget.c index ec81f857b..360b29c41 100644 --- a/src/editor/editwidget.c +++ b/src/editor/editwidget.c @@ -66,6 +66,7 @@ #include "spell.h" #endif #include "macro.h" +#include "event.h" /*** global variables ****************************************************************************/ @@ -446,7 +447,7 @@ edit_event (Gpm_Event * event, void *data) if (local.x == w->cols - dx - 4) { - edit_toggle_fullscreen (edit); + mc_event_raise (MCEVENT_GROUP_EDITOR, "toggle_fullscreen", edit, NULL); return MOU_NORMAL; } @@ -594,7 +595,7 @@ edit_event (Gpm_Event * event, void *data) else if (y == w->y && (event->type & (GPM_DOUBLE | GPM_UP)) == (GPM_DOUBLE | GPM_UP)) { /* double click on top line (toggle fullscreen) */ - edit_toggle_fullscreen (edit); + mc_event_raise (MCEVENT_GROUP_EDITOR, "toggle_fullscreen", edit, NULL); edit->drag_state = MCEDIT_DRAG_NORMAL; edit->force |= REDRAW_COMPLETELY; edit_update_screen (edit); @@ -692,7 +693,7 @@ edit_dialog_event (Gpm_Event * event, void *data) /* Handle buttons */ if (x <= 2) - edit_toggle_fullscreen (e); + mc_event_raise (MCEVENT_GROUP_EDITOR, "toggle_fullscreen", e, NULL); else send_message (h, NULL, MSG_ACTION, CK_Close, NULL); @@ -1466,15 +1467,21 @@ edit_handle_move_resize (WEdit * edit, unsigned long command) } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ /** * Toggle window fuulscreen mode. * * @param edit editor object */ -void -edit_toggle_fullscreen (WEdit * edit) +gboolean +mc_editor_cmd_toggle_fullscreen (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + edit->fullscreen = !edit->fullscreen; edit->force = REDRAW_COMPLETELY; @@ -1490,6 +1497,8 @@ edit_toggle_fullscreen (WEdit * edit) edit->force |= REDRAW_PAGE; edit_update_screen (edit); } + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ diff --git a/src/editor/editwidget.h b/src/editor/editwidget.h index 43936e106..796075d49 100644 --- a/src/editor/editwidget.h +++ b/src/editor/editwidget.h @@ -111,6 +111,7 @@ struct WEdit unsigned int delete_file:1; /* New file, needs to be deleted unless modified */ unsigned int highlight:1; /* There is a selected block */ unsigned int column_highlight:1; + unsigned int is_cursor_moved:1; unsigned int fullscreen:1; /* Is window fullscreen or not */ long prev_col; /* recent column position of the cursor - used when moving up or down past lines that are shorter than the current line */ diff --git a/src/editor/event.c b/src/editor/event.c new file mode 100644 index 000000000..baa73734e --- /dev/null +++ b/src/editor/event.c @@ -0,0 +1,161 @@ +/* + Editor's events definitions. + + Copyright (C) 2012-2014 + Free Software Foundation, Inc. + + Written by: + Slava Zanko , 2014 + + 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 . + */ + +#include + +#include "lib/global.h" +#include "lib/event.h" + +#include "src/setup.h" /* option_tab_spacing */ + +#include "edit-impl.h" +#include "event.h" + +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +void +mc_editor_init_events (GError ** error) +{ + /* *INDENT-OFF* */ + event_init_group_t core_group_events[] = + { + {"backspace", mc_editor_cmd_backspace, NULL}, + {"delete", mc_editor_cmd_delete, NULL}, + {"delete_word_left", mc_editor_cmd_delete_word, (void *) TO_LEFT}, + {"delete_word_right", mc_editor_cmd_delete_word, (void *) TO_RIGHT}, + + {"delete_line", mc_editor_cmd_delete_line, (void *) NONE}, + {"delete_line_to_begin", mc_editor_cmd_delete_line, (void *) TO_LINE_BEGIN}, + {"delete_line_to_end", mc_editor_cmd_delete_line, (void *) TO_LINE_END}, + + {"enter", mc_editor_cmd_enter, NULL}, + {"insert_char_raw", mc_editor_cmd_insert_char_raw, NULL}, + {"insert_char", mc_editor_cmd_insert_char, NULL}, + {"undo", mc_editor_cmd_undo, NULL}, + {"redo", mc_editor_cmd_redo, NULL}, + {"toggle_fullscreen", mc_editor_cmd_toggle_fullscreen, NULL}, + {"tab", mc_editor_cmd_tab, NULL}, + {"switch_insert_overwrite", mc_editor_cmd_switch_insert_overwrite, NULL}, + + {"move_cursor", mc_editor_cmd_move_cursor, NULL}, + + {"mark", mc_editor_cmd_mark, NULL}, + {"mark_column", mc_editor_cmd_mark_column, NULL}, + {"mark_all", mc_editor_cmd_mark_all, NULL}, + {"unmark", mc_editor_cmd_unmark, NULL}, + {"mark_word", mc_editor_cmd_mark, NULL}, + {"mark_line", mc_editor_cmd_mark, NULL}, + + {"bookmark_toggle", mc_editor_cmd_bookmark_toggle, NULL}, + {"bookmark_flush", mc_editor_cmd_bookmark_flush, NULL}, + {"bookmark_next", mc_editor_cmd_bookmark_next, NULL}, + {"bookmark_prev", mc_editor_cmd_bookmark_prev, NULL}, + + {"block_copy", mc_editor_cmd_block_copy, NULL}, + {"block_delete", mc_editor_cmd_block_delete, NULL}, + {"block_move", mc_editor_cmd_block_move, NULL}, + {"block_move_to_left", mc_editor_cmd_block_move_to_left, NULL}, + {"block_move_to_right", mc_editor_cmd_block_move_to_right, NULL}, + + {"ext_clip_copy", mc_editor_cmd_ext_clip_copy, NULL}, + {"ext_clip_cut", mc_editor_cmd_ext_clip_cut, NULL}, + {"ext_clip_paste", mc_editor_cmd_ext_clip_paste, NULL}, + {"paste_from_history", mc_editor_cmd_paste_from_history, NULL}, + + {"format_paragraph", mc_editor_cmd_format_paragraph, (void *) FALSE}, + {"format_paragraph_force", mc_editor_cmd_format_paragraph, (void *) TRUE}, + {"format_paragraph_auto", mc_editor_cmd_format_paragraph_auto, NULL}, + + {"save_as", mc_editor_cmd_save_as, NULL}, + {"save_confirm", mc_editor_cmd_save_confirm, NULL}, + {"save_block", mc_editor_cmd_save_block, NULL}, + + {"insert_file", mc_editor_cmd_insert_file, NULL}, + {"file_load_prev", mc_editor_cmd_file_load_prev, NULL}, + {"file_load_next", mc_editor_cmd_file_load_next, NULL}, + {"syntax_show_dialog", mc_editor_cmd_syntax_show_dialog, NULL}, + + {"search", mc_editor_cmd_search, (void *) FALSE}, + {"search_continue", mc_editor_cmd_search, (void *) TRUE}, + {"replace", mc_editor_cmd_replace, (void *) FALSE}, + {"replace_continue", mc_editor_cmd_replace, (void *) TRUE}, + + {"complete", mc_editor_cmd_complete, (void *) FALSE}, + {"match_keyword", mc_editor_cmd_match_keyword, (void *) FALSE}, + {"print_current_date", mc_editor_cmd_print_current_date, (void *) FALSE}, + {"goto_line", mc_editor_cmd_goto_line, (void *) FALSE}, + {"goto_matching_bracket", mc_editor_cmd_goto_matching_bracket, (void *) FALSE}, + {"user_menu", mc_editor_cmd_user_menu, (void *) FALSE}, + {"sort", mc_editor_cmd_sort, (void *) FALSE}, + {"run_external_command", mc_editor_cmd_run_external_command, (void *) FALSE}, + {"mail", mc_editor_cmd_mail, (void *) FALSE}, + {"insert_literal", mc_editor_cmd_insert_literal, (void *) FALSE}, + + {"macro_record_start_stop", mc_editor_cmd_macro_record_start_stop, (void *) FALSE}, + {"macro_repeat_start_stop", mc_editor_cmd_macro_repeat_start_stop, (void *) FALSE}, + {"macro_store", mc_editor_cmd_macro_store, (void *) FALSE}, + {"macro_delete", mc_editor_cmd_macro_delete, (void *) FALSE}, + {"macro_repeat", mc_editor_cmd_macro_repeat, (void *) FALSE}, + +#ifdef HAVE_ASPELL + {"spell_set_language", mc_editor_cmd_spell_set_language, (void *) FALSE}, + {"spell_check", mc_editor_cmd_spell_check, (void *) FALSE}, + {"spell_suggest_word", mc_editor_cmd_spell_suggest_word, (void *) FALSE}, +#endif /* HAVE_ASPELL */ + +#ifdef HAVE_CHARSET + {"select_codepage", mc_editor_cmd_select_codepage, (void *) FALSE}, +#endif /* HAVE_CHARSET */ + + {NULL, NULL, NULL} + }; + /* *INDENT-ON* */ + + /* *INDENT-OFF* */ + event_init_t standard_events[] = + { + {MCEVENT_GROUP_EDITOR, core_group_events}, + {NULL, NULL} + }; + /* *INDENT-ON* */ + + mc_event_mass_add (standard_events, error); + +} + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/editor/event.h b/src/editor/event.h new file mode 100644 index 000000000..48b5eece2 --- /dev/null +++ b/src/editor/event.h @@ -0,0 +1,161 @@ +#ifndef MC__EDIT_EVENT_H +#define MC__EDIT_EVENT_H + +#include "lib/event.h" + +#include "editwidget.h" + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +typedef enum +{ + NONE, + TO_LEFT, + TO_RIGHT, + TO_WORD_BEGIN, + TO_WORD_END, + TO_UP, + TO_DOWN, + TO_PARAGRAPH_UP, + TO_PARAGRAPH_DOWN, + TO_SCROLL_UP, + TO_SCROLL_DOWN, + TO_PAGE_UP, + TO_PAGE_DOWN, + TO_PAGE_BEGIN, + TO_PAGE_END, + TO_LINE_BEGIN, + TO_LINE_END, + TO_FILE_BEGIN, + TO_FILE_END, +} mc_editor_event_direction_t; + +typedef struct +{ + struct WEdit *editor; + int char_for_insertion; + long line; +} mc_editor_event_data_insert_char_t; + +typedef struct +{ + struct WEdit *editor; + gboolean is_mark; + gboolean is_column; + mc_editor_event_direction_t direction; + long line; +} mc_editor_event_data_move_cursor_t; + +typedef struct +{ + struct WEdit *editor; + gboolean return_value; +} mc_editor_event_data_ret_boolean_t; + + +typedef struct +{ + WEdit *editor; + const char *menu_file; + int selected_entry; +} mc_editor_event_data_user_menu_t; + + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + +void mc_editor_init_events (GError ** error); + +gboolean mc_editor_cmd_backspace (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_delete (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_delete_word (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_delete_line (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_enter (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_insert_char_raw (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_insert_char (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_undo (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_redo (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_toggle_fullscreen (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_move_cursor (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_tab (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_switch_insert_overwrite (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_mark (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_mark_column (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_mark_all (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_unmark (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_mark_word (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_mark_line (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_bookmark_toggle (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_bookmark_flush (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_bookmark_next (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_bookmark_prev (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_block_copy (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_block_delete (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_block_move (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_block_move_to_left (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_block_move_to_right (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_ext_clip_copy (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_ext_clip_cut (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_ext_clip_paste (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_paste_from_history (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_format_paragraph (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_format_paragraph_auto (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_save_as (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_save_confirm (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_save_block (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_insert_file (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_file_load_prev (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_file_load_next (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_syntax_show_dialog (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_search (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_replace (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_complete (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_match_keyword (event_info_t * event_info, gpointer data, GError ** error); + +gboolean mc_editor_cmd_print_current_date (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_goto_line (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_macro_delete (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_goto_matching_bracket (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_user_menu (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_sort (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_run_external_command (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_mail (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_insert_literal (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_macro_record_start_stop (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_macro_repeat_start_stop (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_macro_store (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_macro_repeat (event_info_t * event_info, gpointer data, GError ** error); + +#ifdef HAVE_ASPELL +gboolean mc_editor_cmd_spell_set_language (event_info_t * event_info, gpointer data, + GError ** error); +gboolean mc_editor_cmd_spell_check (event_info_t * event_info, gpointer data, GError ** error); +gboolean mc_editor_cmd_spell_suggest_word (event_info_t * event_info, gpointer data, + GError ** error); +#endif /* HAVE_ASPELL */ + +#ifdef HAVE_CHARSET +gboolean mc_editor_cmd_select_codepage (event_info_t * event_info, gpointer data, GError ** error); +#endif /* HAVE_CHARSET */ + + +/*** inline functions ****************************************************************************/ + +#endif /* MC__EDIT_EVENT_H */ diff --git a/src/editor/format.c b/src/editor/format.c index 28d36db59..5d6d06ed4 100644 --- a/src/editor/format.c +++ b/src/editor/format.c @@ -53,6 +53,7 @@ #include "edit-impl.h" #include "editwidget.h" +#include "event.h" /*** global variables ****************************************************************************/ @@ -468,11 +469,9 @@ test_indent (const WEdit * edit, off_t p, off_t q) return indent; } -/* --------------------------------------------------------------------------------------------- */ -/*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ -void +static void format_paragraph (WEdit * edit, gboolean force) { off_t p, q; @@ -488,6 +487,7 @@ format_paragraph (WEdit * edit, gboolean force) if (edit_line_is_blank (edit, edit->buffer.curs_line)) return; + edit->force |= REDRAW_PAGE; p = begin_paragraph (edit, force, &lines); q = end_paragraph (edit, force); indent = test_indent (edit, p, q); @@ -543,11 +543,18 @@ format_paragraph (WEdit * edit, gboolean force) /* try move to the start of next paragraph */ if (edit->buffer.curs_line < edit->buffer.lines) { - edit_execute_cmd (edit, CK_Home, -1); + mc_editor_event_data_move_cursor_t cursor_event_data = { + .editor = edit, + .is_mark = FALSE, + .is_column = FALSE, + .direction = TO_LINE_BEGIN + }; + mc_event_raise (MCEVENT_GROUP_EDITOR, "move_cursor", &cursor_event_data, NULL); + cursor_event_data.direction = TO_DOWN; do { - edit_execute_cmd (edit, CK_Down, -1); + mc_event_raise (MCEVENT_GROUP_EDITOR, "move_cursor", &cursor_event_data, NULL); } while (edit->buffer.curs_line < edit->buffer.lines && edit_line_is_blank (edit, edit->buffer.curs_line)); @@ -555,3 +562,38 @@ format_paragraph (WEdit * edit, gboolean force) } /* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_format_paragraph (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + gboolean force = (gboolean) (intptr_t) event_info->init_data; + + (void) error; + + format_paragraph (edit, force); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_format_paragraph_auto (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) error; + (void) event_info; + + if (option_auto_para_formatting) + format_paragraph (edit, FALSE); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/editor/macro.c b/src/editor/macro.c index d09165c28..9c426fba3 100644 --- a/src/editor/macro.c +++ b/src/editor/macro.c @@ -39,6 +39,7 @@ #include "editwidget.h" #include "editcmd_dialogs.h" +#include "event.h" #include "macro.h" /*** global variables ****************************************************************************/ @@ -140,15 +141,24 @@ edit_delete_macro (WEdit * edit, int hotkey) /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ -void -edit_delete_macro_cmd (WEdit * edit) +/* event callback */ + +gboolean +mc_editor_cmd_macro_delete (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + int hotkey; + (void) event_info; + (void) error; + hotkey = editcmd_dialog_raw_key_query (_("Delete macro"), _("Press macro hotkey:"), TRUE); if (hotkey != 0 && !edit_delete_macro (edit, hotkey)) message (D_ERROR, _("Delete macro"), _("Macro not deleted")); + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ @@ -186,11 +196,13 @@ edit_execute_macro (WEdit * edit, int hotkey) } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -/** returns FALSE on error */ gboolean -edit_store_macro_cmd (WEdit * edit) +mc_editor_cmd_macro_store (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + int i; int hotkey; GString *marcros_string; @@ -202,17 +214,20 @@ edit_store_macro_cmd (WEdit * edit) gboolean have_macro = FALSE; char *skeyname = NULL; + (void) event_info; + (void) error; + hotkey = editcmd_dialog_raw_key_query (_("Save macro"), _("Press the macro's new hotkey:"), TRUE); if (hotkey == ESC_CHAR) - return FALSE; + return TRUE; tmp_act = keybind_lookup_keymap_command (editor_map, hotkey); /* return FALSE if try assign macro into restricted hotkeys */ if (tmp_act == CK_MacroStartRecord || tmp_act == CK_MacroStopRecord || tmp_act == CK_MacroStartStopRecord) - return FALSE; + return TRUE; edit_delete_macro (edit, hotkey); @@ -221,7 +236,7 @@ edit_store_macro_cmd (WEdit * edit) g_free (macros_fname); if (macros_config == NULL) - return FALSE; + return TRUE; edit_push_undo_action (edit, KEY_PRESS + edit->start_display); @@ -264,33 +279,40 @@ edit_store_macro_cmd (WEdit * edit) g_string_free (marcros_string, TRUE); mc_config_save_file (macros_config, NULL); mc_config_deinit (macros_config); + return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ gboolean -edit_repeat_macro_cmd (WEdit * edit) +mc_editor_cmd_macro_repeat (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + int i, j; char *f; long count_repeat; - char *error = NULL; + char *error_str = NULL; + + (void) event_info; + (void) error; f = input_dialog (_("Repeat last commands"), _("Repeat times:"), MC_HISTORY_EDIT_REPEAT, NULL, INPUT_COMPLETE_NONE); if (f == NULL || *f == '\0') { g_free (f); - return FALSE; + return TRUE; } - count_repeat = strtol (f, &error, 0); + count_repeat = strtol (f, &error_str, 0); - if (*error != '\0') + if (*error_str != '\0') { g_free (f); - return FALSE; + return TRUE; } g_free (f); @@ -302,6 +324,7 @@ edit_repeat_macro_cmd (WEdit * edit) for (i = 0; i < macro_index; i++) edit_execute_cmd (edit, record_macro_buf[i].action, record_macro_buf[i].ch); edit_update_screen (edit); + return TRUE; } @@ -388,35 +411,52 @@ edit_load_macro_cmd (WEdit * edit) g_strfreev (keys); mc_config_deinit (macros_config); edit_macro_sort_by_hotkey (); + return TRUE; } /* }}} Macro stuff end here */ /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -void -edit_begin_end_macro_cmd (WEdit * edit) +gboolean +mc_editor_cmd_macro_record_start_stop (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + /* edit is a pointer to the widget */ if (edit != NULL) { unsigned long command = macro_index < 0 ? CK_MacroStartRecord : CK_MacroStopRecord; edit_execute_key_command (edit, command, -1); } + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ +/* event callback */ -void -edit_begin_end_repeat_cmd (WEdit * edit) +gboolean +mc_editor_cmd_macro_repeat_start_stop (event_info_t * event_info, gpointer data, GError ** error) { + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + /* edit is a pointer to the widget */ if (edit != NULL) { unsigned long command = macro_index < 0 ? CK_RepeatStartRecord : CK_RepeatStopRecord; edit_execute_key_command (edit, command, -1); } + + return TRUE; } /* --------------------------------------------------------------------------------------------- */ diff --git a/src/editor/macro.h b/src/editor/macro.h index 156857e55..d32373fae 100644 --- a/src/editor/macro.h +++ b/src/editor/macro.h @@ -11,14 +11,9 @@ /*** declarations of public functions ************************************************************/ -int edit_store_macro_cmd (WEdit * edit); gboolean edit_load_macro_cmd (WEdit * edit); -void edit_delete_macro_cmd (WEdit * edit); -gboolean edit_repeat_macro_cmd (WEdit * edit); gboolean edit_execute_macro (WEdit * edit, int hotkey); -void edit_begin_end_macro_cmd (WEdit * edit); -void edit_begin_end_repeat_cmd (WEdit * edit); /*** inline functions ****************************************************************************/ #endif /* MC__EDIT_MACRO_H */ diff --git a/src/editor/spell_cmd.c b/src/editor/spell_cmd.c new file mode 100644 index 000000000..b73812a00 --- /dev/null +++ b/src/editor/spell_cmd.c @@ -0,0 +1,218 @@ +/* + Editor spell checker dialogs + + Copyright (C) 2012-2014 + Free Software Foundation, Inc. + + Written by: + Ilia Maslakov , 2012 + Andrew Borodin , 2013 + + 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 . + */ + +#include + +#include "lib/global.h" +#include "lib/strutil.h" /* str_term_width1 */ +#ifdef HAVE_CHARSET +#include "lib/charsets.h" +#endif + +#include "editwidget.h" + +#include "event.h" +#include "spell.h" +#include "spell_dialogs.h" + +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +static int +edit_suggest_current_word (WEdit * edit) +{ + gsize cut_len = 0; + gsize word_len = 0; + off_t word_start = 0; + int retval = B_SKIP_WORD; + GString *match_word; + + /* search start of word to spell check */ + match_word = edit_buffer_get_word_from_pos (&edit->buffer, edit->buffer.curs1, &word_start, + &cut_len); + word_len = match_word->len; + +#ifdef HAVE_CHARSET + if (mc_global.source_codepage >= 0 && (mc_global.source_codepage != mc_global.display_codepage)) + { + GString *tmp_word; + + tmp_word = str_convert_to_display (match_word->str); + g_string_free (match_word, TRUE); + match_word = tmp_word; + } +#endif + if (!aspell_check (match_word->str, (int) word_len)) + { + GArray *suggest; + unsigned int res; + + suggest = g_array_new (TRUE, FALSE, sizeof (char *)); + + res = aspell_suggest (suggest, match_word->str, (int) word_len); + if (res != 0) + { + char *new_word = NULL; + + edit->found_start = word_start; + edit->found_len = word_len; + edit->force |= REDRAW_PAGE; + edit_scroll_screen_over_cursor (edit); + edit_render_keypress (edit); + + retval = spell_dialog_spell_suggest_show (edit, match_word->str, &new_word, suggest); + edit_cursor_move (edit, word_len - cut_len); + + if (retval == B_ENTER && new_word != NULL) + { + guint i; + char *cp_word; + +#ifdef HAVE_CHARSET + if (mc_global.source_codepage >= 0 && + (mc_global.source_codepage != mc_global.display_codepage)) + { + GString *tmp_word; + + tmp_word = str_convert_to_input (new_word); + g_free (new_word); + new_word = g_string_free (tmp_word, FALSE); + } +#endif + cp_word = new_word; + for (i = 0; i < word_len; i++) + edit_backspace (edit, TRUE); + for (; *new_word; new_word++) + edit_insert (edit, *new_word); + g_free (cp_word); + } + else if (retval == B_ADD_WORD && match_word != NULL) + aspell_add_to_dict (match_word->str, (int) word_len); + } + + g_array_free (suggest, TRUE); + edit->found_start = 0; + edit->found_len = 0; + } + g_string_free (match_word, TRUE); + return retval; +} + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/* event callback */ + +gboolean +mc_editor_cmd_spell_suggest_word (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + edit_suggest_current_word (edit); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_spell_check (event_info_t * event_info, gpointer data, GError ** error) +{ + WEdit *edit = (WEdit *) data; + + (void) event_info; + (void) error; + + if (edit->buffer.curs_line > 0) + { + edit_cursor_move (edit, -edit->buffer.curs1); + edit_move_to_prev_col (edit, 0); + edit_update_curs_row (edit); + } + + do + { + int c1, c2; + + c2 = edit_buffer_get_current_byte (&edit->buffer); + + do + { + if (edit->buffer.curs1 >= edit->buffer.size) + return TRUE; + + c1 = c2; + edit_cursor_move (edit, 1); + c2 = edit_buffer_get_current_byte (&edit->buffer); + } + while (is_break_char (c1) || is_break_char (c2)); + } + while (edit_suggest_current_word (edit) != B_CANCEL); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ +/* event callback */ + +gboolean +mc_editor_cmd_spell_set_language (event_info_t * event_info, gpointer data, GError ** error) +{ + GArray *lang_list; + + (void) event_info; + (void) error; + (void) data; + + + lang_list = g_array_new (TRUE, FALSE, sizeof (char *)); + if (aspell_get_lang_list (lang_list) != 0) + { + char *lang; + + lang = spell_dialog_lang_list_show (lang_list); + if (lang != NULL) + (void) aspell_set_lang (lang); + } + aspell_array_clean (lang_list); + + return TRUE; +} + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/filemanager/midnight.c b/src/filemanager/midnight.c index 914d4ad27..352277a97 100644 --- a/src/filemanager/midnight.c +++ b/src/filemanager/midnight.c @@ -1744,7 +1744,7 @@ do_nc (GError ** error) gboolean ret; #ifdef USE_INTERNAL_EDIT - edit_stack_init (); + mc_editor_init (error); #endif #ifdef USE_DIFF_VIEW @@ -1790,7 +1790,7 @@ do_nc (GError ** error) current_panel = NULL; #ifdef USE_INTERNAL_EDIT - edit_stack_free (); + mc_editor_deinit (error); #endif if ((quit & SUBSHELL_EXIT) == 0) diff --git a/tests/src/editor/editcmd__edit_complete_word_cmd.c b/tests/src/editor/editcmd__edit_complete_word_cmd.c index 9f008b23c..fa154855e 100644 --- a/tests/src/editor/editcmd__edit_complete_word_cmd.c +++ b/tests/src/editor/editcmd__edit_complete_word_cmd.c @@ -69,17 +69,6 @@ edit_get_syntax_color (WEdit * _edit, off_t _byte_index) /* --------------------------------------------------------------------------------------------- */ -/* @Mock */ -gboolean -edit_load_macro_cmd (WEdit * _edit) -{ - (void) _edit; - - return FALSE; -} - -/* --------------------------------------------------------------------------------------------- */ - /* @CapturedValue */ static const WEdit *editcmd_dialog_completion_show__edit; /* @CapturedValue */