From b5fc1780277ba5c36a29c7a2e0b1426b1d45185a Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Sun, 19 Dec 2010 17:36:06 +0000 Subject: [PATCH 1/4] Ticket #25 (mcedit: REDO) little optimization, renamed: * variables stack* to undo_stack* * pop_action to edit_pop_undo_action * edit_push_action to edit_push_undo_action Signed-off-by: Ilia Maslakov --- src/editor/edit-impl.h | 2 +- src/editor/edit-widget.h | 10 +-- src/editor/edit.c | 143 ++++++++++++++++----------------------- src/editor/editcmd.c | 16 ++--- 4 files changed, 71 insertions(+), 100 deletions(-) diff --git a/src/editor/edit-impl.h b/src/editor/edit-impl.h index 6f3459043..69213cc4a 100644 --- a/src/editor/edit-impl.h +++ b/src/editor/edit-impl.h @@ -259,7 +259,7 @@ void edit_insert (WEdit * edit, int c); void edit_cursor_move (WEdit * edit, long increment); void edit_move_block_to_right (WEdit * edit); void edit_move_block_to_left (WEdit * edit); -void edit_push_action (WEdit * edit, long c, ...); +void edit_push_undo_action (WEdit * edit, long c, ...); void edit_push_key_press (WEdit * edit); void edit_insert_ahead (WEdit * edit, int c); long edit_write_stream (WEdit * edit, FILE * f); diff --git a/src/editor/edit-widget.h b/src/editor/edit-widget.h index 6ebb2920f..82a8c6183 100644 --- a/src/editor/edit-widget.h +++ b/src/editor/edit-widget.h @@ -106,12 +106,12 @@ struct WEdit GArray *serialized_bookmarks; /* undo stack and pointers */ - unsigned long stack_pointer; + unsigned long undo_stack_pointer; long *undo_stack; - unsigned long stack_size; - unsigned long stack_size_mask; - unsigned long stack_bottom; - unsigned int stack_disable:1; /* If not 0, don't save events in the undo stack */ + unsigned long undo_stack_size; + unsigned long undo_stack_size_mask; + unsigned long undo_stack_bottom; + unsigned int undo_stack_disable:1; /* If not 0, don't save events in the undo stack */ struct stat stat1; /* Result of mc_fstat() on the file */ unsigned int skip_detach_prompt:1; /* Do not prompt whether to detach a file anymore */ diff --git a/src/editor/edit.c b/src/editor/edit.c index 97d8abe47..e7c466475 100644 --- a/src/editor/edit.c +++ b/src/editor/edit.c @@ -478,13 +478,13 @@ edit_load_file (WEdit * edit) edit->last_byte = 0; if (*edit->filename) { - edit->stack_disable = 1; + edit->undo_stack_disable = 1; if (!edit_insert_file (edit, edit->filename)) { edit_clean (edit); return 1; } - edit->stack_disable = 0; + edit->undo_stack_disable = 0; } } edit->lb = LB_ASIS; @@ -580,31 +580,31 @@ edit_set_keymap (void) */ static long -pop_action (WEdit * edit) +edit_pop_undo_action (WEdit * edit) { long c; - unsigned long sp = edit->stack_pointer; + unsigned long sp = edit->undo_stack_pointer; - if (sp == edit->stack_bottom) + if (sp == edit->undo_stack_bottom) return STACK_BOTTOM; - sp = (sp - 1) & edit->stack_size_mask; + sp = (sp - 1) & edit->undo_stack_size_mask; c = edit->undo_stack[sp]; if (c >= 0) { /* edit->undo_stack[sp] = '@'; */ - edit->stack_pointer = (edit->stack_pointer - 1) & edit->stack_size_mask; + edit->undo_stack_pointer = (edit->undo_stack_pointer - 1) & edit->undo_stack_size_mask; return c; } - if (sp == edit->stack_bottom) + if (sp == edit->undo_stack_bottom) return STACK_BOTTOM; - c = edit->undo_stack[(sp - 1) & edit->stack_size_mask]; + c = edit->undo_stack[(sp - 1) & edit->undo_stack_size_mask]; if (edit->undo_stack[sp] == -2) { /* edit->undo_stack[sp] = '@'; */ - edit->stack_pointer = sp; + edit->undo_stack_pointer = sp; } else edit->undo_stack[sp]++; @@ -682,7 +682,7 @@ edit_backspace (WEdit * edit, const int byte_delete) } edit->last_byte--; edit->curs1--; - edit_push_action (edit, p); + edit_push_undo_action (edit, p); } edit_modification (edit); if (p == '\n') @@ -1226,9 +1226,9 @@ edit_do_undo (WEdit * edit) long ac; long count = 0; - edit->stack_disable = 1; /* don't record undo's onto undo stack! */ + edit->undo_stack_disable = 1; /* don't record undo's onto undo stack! */ edit->over_col = 0; - while ((ac = pop_action (edit)) < KEY_PRESS) + while ((ac = edit_pop_undo_action (edit)) < KEY_PRESS) { switch ((int) ac) { @@ -1286,7 +1286,7 @@ edit_do_undo (WEdit * edit) edit_update_curs_row (edit); done_undo:; - edit->stack_disable = 0; + edit->undo_stack_disable = 0; } /* --------------------------------------------------------------------------------------------- */ @@ -2027,9 +2027,9 @@ edit_init (WEdit * edit, int lines, int columns, const char *filename, long line edit->bracket = -1; edit->force |= REDRAW_PAGE; edit_set_filename (edit, filename); - edit->stack_size = START_STACK_SIZE; - edit->stack_size_mask = START_STACK_SIZE - 1; - edit->undo_stack = g_malloc0 ((edit->stack_size + 10) * sizeof (long)); + edit->undo_stack_size = START_STACK_SIZE; + edit->undo_stack_size_mask = START_STACK_SIZE - 1; + edit->undo_stack = g_malloc0 ((edit->undo_stack_size + 10) * sizeof (long)); edit->utf8 = 0; edit->converter = str_cnv_from_term; @@ -2259,52 +2259,40 @@ edit_set_codeset (WEdit * edit) */ void -edit_push_action (WEdit * edit, long c, ...) +edit_push_undo_action (WEdit * edit, long c, ...) { - unsigned long sp = edit->stack_pointer; + unsigned long sp = edit->undo_stack_pointer; unsigned long spm1; long *t; /* first enlarge the stack if necessary */ - if (sp > edit->stack_size - 10) + if (sp > edit->undo_stack_size - 10) { /* say */ if (option_max_undo < 256) option_max_undo = 256; - if (edit->stack_size < (unsigned long) option_max_undo) + if (edit->undo_stack_size < (unsigned long) option_max_undo) { - t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (long)); + t = g_realloc (edit->undo_stack, (edit->undo_stack_size * 2 + 10) * sizeof (long)); if (t) { edit->undo_stack = t; - edit->stack_size <<= 1; - edit->stack_size_mask = edit->stack_size - 1; + edit->undo_stack_size <<= 1; + edit->undo_stack_size_mask = edit->undo_stack_size - 1; } } } - spm1 = (edit->stack_pointer - 1) & edit->stack_size_mask; - if (edit->stack_disable) + spm1 = (edit->undo_stack_pointer - 1) & edit->undo_stack_size_mask; + if (edit->undo_stack_disable) return; -#ifdef FAST_MOVE_CURSOR - if (c == CURS_LEFT_LOTS || c == CURS_RIGHT_LOTS) - { - va_list ap; - edit->undo_stack[sp] = (c == CURS_LEFT_LOTS) ? CURS_LEFT : CURS_RIGHT; - edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; - va_start (ap, c); - c = -(va_arg (ap, int)); - va_end (ap); - } - else -#endif /* ! FAST_MOVE_CURSOR */ - if (edit->stack_bottom != sp - && spm1 != edit->stack_bottom - && ((sp - 2) & edit->stack_size_mask) != edit->stack_bottom) + if (edit->undo_stack_bottom != sp + && spm1 != edit->undo_stack_bottom + && ((sp - 2) & edit->undo_stack_size_mask) != edit->undo_stack_bottom) { int d; if (edit->undo_stack[spm1] < 0) { - d = edit->undo_stack[(sp - 2) & edit->stack_size_mask]; + d = edit->undo_stack[(sp - 2) & edit->undo_stack_size_mask]; if (d == c) { if (edit->undo_stack[spm1] > -1000000000) @@ -2315,16 +2303,6 @@ edit_push_action (WEdit * edit, long c, ...) } } /* #define NO_STACK_CURSMOVE_ANIHILATION */ -#ifndef NO_STACK_CURSMOVE_ANIHILATION - else if ((c == CURS_LEFT && d == CURS_RIGHT) || (c == CURS_RIGHT && d == CURS_LEFT)) - { /* a left then a right anihilate each other */ - if (edit->undo_stack[spm1] == -2) - edit->stack_pointer = spm1; - else - edit->undo_stack[spm1]++; - return; - } -#endif } else { @@ -2336,37 +2314,30 @@ edit_push_action (WEdit * edit, long c, ...) edit->undo_stack[sp] = -2; goto check_bottom; } -#ifndef NO_STACK_CURSMOVE_ANIHILATION - else if ((c == CURS_LEFT && d == CURS_RIGHT) || (c == CURS_RIGHT && d == CURS_LEFT)) - { /* a left then a right anihilate each other */ - edit->stack_pointer = spm1; - return; - } -#endif } } edit->undo_stack[sp] = c; check_bottom: - edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; + edit->undo_stack_pointer = (edit->undo_stack_pointer + 1) & edit->undo_stack_size_mask; - /* if the sp wraps round and catches the stack_bottom then erase + /* if the sp wraps round and catches the undo_stack_bottom then erase * the first set of actions on the stack to make space - by moving - * stack_bottom forward one "key press" */ - c = (edit->stack_pointer + 2) & edit->stack_size_mask; - if ((unsigned long) c == edit->stack_bottom || - (((unsigned long) c + 1) & edit->stack_size_mask) == edit->stack_bottom) + * undo_stack_bottom forward one "key press" */ + c = (edit->undo_stack_pointer + 2) & edit->undo_stack_size_mask; + if ((unsigned long) c == edit->undo_stack_bottom || + (((unsigned long) c + 1) & edit->undo_stack_size_mask) == edit->undo_stack_bottom) do { - edit->stack_bottom = (edit->stack_bottom + 1) & edit->stack_size_mask; + edit->undo_stack_bottom = (edit->undo_stack_bottom + 1) & edit->undo_stack_size_mask; } - while (edit->undo_stack[edit->stack_bottom] < KEY_PRESS - && edit->stack_bottom != edit->stack_pointer); + while (edit->undo_stack[edit->undo_stack_bottom] < KEY_PRESS + && edit->undo_stack_bottom != edit->undo_stack_pointer); - /*If a single key produced enough pushes to wrap all the way round then we would notice that the [stack_bottom] does not contain KEY_PRESS. The stack is then initialised: */ - if (edit->stack_pointer != edit->stack_bottom - && edit->undo_stack[edit->stack_bottom] < KEY_PRESS) - edit->stack_bottom = edit->stack_pointer = 0; + /*If a single key produced enough pushes to wrap all the way round then we would notice that the [undo_stack_bottom] does not contain KEY_PRESS. The stack is then initialised: */ + if (edit->undo_stack_pointer != edit->undo_stack_bottom + && edit->undo_stack[edit->undo_stack_bottom] < KEY_PRESS) + edit->undo_stack_bottom = edit->undo_stack_pointer = 0; } /* --------------------------------------------------------------------------------------------- */ @@ -2407,7 +2378,7 @@ edit_insert (WEdit * edit, int c) } /* save the reverse command onto the undo stack */ - edit_push_action (edit, BACKSPACE); + edit_push_undo_action (edit, BACKSPACE); /* update markers */ edit->mark1 += (edit->mark1 > edit->curs1); @@ -2452,7 +2423,7 @@ edit_insert_ahead (WEdit * edit, int c) edit->total_lines++; edit->force |= REDRAW_AFTER_CURSOR; } - edit_push_action (edit, DELCHAR); + edit_push_undo_action (edit, DELCHAR); edit->mark1 += (edit->mark1 >= edit->curs1); edit->mark2 += (edit->mark2 >= edit->curs1); @@ -2511,7 +2482,7 @@ edit_delete (WEdit * edit, const int byte_delete) } edit->last_byte--; edit->curs2--; - edit_push_action (edit, p + 256); + edit_push_undo_action (edit, p + 256); } edit_modification (edit); @@ -2545,7 +2516,7 @@ edit_move_backward_lots (WEdit * edit, long increment) increment = edit->curs1; if (increment <= 0) return -1; - edit_push_action (edit, CURS_RIGHT_LOTS, increment); + edit_push_undo_action (edit, CURS_RIGHT_LOTS, increment); t = r = EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE); if (r > increment) @@ -2655,7 +2626,7 @@ edit_cursor_move (WEdit * edit, long increment) if (!edit->curs1) return; - edit_push_action (edit, CURS_RIGHT); + edit_push_undo_action (edit, CURS_RIGHT); c = edit_get_byte (edit, edit->curs1 - 1); if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE)) @@ -2686,7 +2657,7 @@ edit_cursor_move (WEdit * edit, long increment) if (!edit->curs2) return; - edit_push_action (edit, CURS_LEFT); + edit_push_undo_action (edit, CURS_LEFT); c = edit_get_byte (edit, edit->curs1); if (!(edit->curs1 & M_EDIT_BUF_SIZE)) @@ -3059,8 +3030,8 @@ edit_move_display (WEdit * e, long line) void edit_push_markers (WEdit * edit) { - edit_push_action (edit, MARK_1 + edit->mark1); - edit_push_action (edit, MARK_2 + edit->mark2); + edit_push_undo_action (edit, MARK_1 + edit->mark1); + edit_push_undo_action (edit, MARK_2 + edit->mark2); } /* --------------------------------------------------------------------------------------------- */ @@ -3186,9 +3157,9 @@ edit_insert_indent (WEdit * edit, int indent) void edit_push_key_press (WEdit * edit) { - edit_push_action (edit, KEY_PRESS + edit->start_display); + edit_push_undo_action (edit, KEY_PRESS + edit->start_display); if (edit->mark2 == -1) - edit_push_action (edit, MARK_1 + edit->mark1); + edit_push_undo_action (edit, MARK_1 + edit->mark1); } /* --------------------------------------------------------------------------------------------- */ @@ -3362,7 +3333,7 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) if (!option_persistent_selections) { if (edit->column_highlight) - edit_push_action (edit, COLUMN_ON); + edit_push_undo_action (edit, COLUMN_ON); edit->column_highlight = 0; edit_mark_cmd (edit, 1); } @@ -3640,14 +3611,14 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) if (edit->mark2 >= 0) { if (edit->column_highlight) - edit_push_action (edit, COLUMN_ON); + edit_push_undo_action (edit, COLUMN_ON); edit->column_highlight = 0; } edit_mark_cmd (edit, 0); break; case CK_Column_Mark: if (!edit->column_highlight) - edit_push_action (edit, COLUMN_OFF); + edit_push_undo_action (edit, COLUMN_OFF); edit->column_highlight = 1; edit_mark_cmd (edit, 0); break; @@ -3657,7 +3628,7 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) break; case CK_Unmark: if (edit->column_highlight) - edit_push_action (edit, COLUMN_ON); + edit_push_undo_action (edit, COLUMN_ON); edit->column_highlight = 0; edit_mark_cmd (edit, 1); break; diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c index 556085a40..d91619177 100644 --- a/src/editor/editcmd.c +++ b/src/editor/editcmd.c @@ -937,7 +937,7 @@ edit_do_search (WEdit * edit) if (edit->search == NULL) edit->search_start = edit->curs1; - edit_push_action (edit, KEY_PRESS + edit->start_display); + edit_push_undo_action (edit, KEY_PRESS + edit->start_display); if (search_create_bookmark) { @@ -1397,7 +1397,7 @@ edit_save_as_cmd (WEdit * edit) return 0; exp = edit_get_save_file_as (edit); - edit_push_action (edit, KEY_PRESS + edit->start_display); + edit_push_undo_action (edit, KEY_PRESS + edit->start_display); if (exp) { @@ -1508,7 +1508,7 @@ edit_save_macro_cmd (WEdit * edit, struct macro macro[], int n) FILE *f; int s, i; - edit_push_action (edit, KEY_PRESS + edit->start_display); + edit_push_undo_action (edit, KEY_PRESS + edit->start_display); s = editcmd_dialog_raw_key_query (_("Save macro"), _("Press the macro's new hotkey:"), 1); edit->force |= REDRAW_COMPLETELY; if (s) @@ -1928,7 +1928,7 @@ edit_block_copy_cmd (WEdit * edit) if (edit->column_highlight) { edit_set_markers (edit, 0, 0, 0, 0); - edit_push_action (edit, COLUMN_ON); + edit_push_undo_action (edit, COLUMN_ON); edit->column_highlight = 0; } else if (start_mark < current && end_mark > current) @@ -2007,7 +2007,7 @@ edit_block_move_cmd (WEdit * edit) edit->curs1), x, 0) - edit->curs1); } edit_set_markers (edit, 0, 0, 0, 0); - edit_push_action (edit, COLUMN_ON); + edit_push_undo_action (edit, COLUMN_ON); edit->column_highlight = 0; } else @@ -2089,7 +2089,7 @@ edit_replace_cmd (WEdit * edit, int again) disp1 = edit_replace_cmd__conv_to_display (saved1 ? saved1 : (char *) ""); disp2 = edit_replace_cmd__conv_to_display (saved2 ? saved2 : (char *) ""); - edit_push_action (edit, KEY_PRESS + edit->start_display); + edit_push_undo_action (edit, KEY_PRESS + edit->start_display); editcmd_dialog_replace_show (edit, disp1, disp2, &input1, &input2); @@ -2566,7 +2566,7 @@ edit_save_block_cmd (WEdit * edit) input_expand_dialog (_("Save block"), _("Enter file name:"), MC_HISTORY_EDIT_SAVE_BLOCK, tmp); g_free (tmp); - edit_push_action (edit, KEY_PRESS + edit->start_display); + edit_push_undo_action (edit, KEY_PRESS + edit->start_display); if (exp) { if (!*exp) @@ -2607,7 +2607,7 @@ edit_insert_file_cmd (WEdit * edit) exp = input_expand_dialog (_("Insert file"), _("Enter file name:"), MC_HISTORY_EDIT_INSERT_FILE, tmp); g_free (tmp); - edit_push_action (edit, KEY_PRESS + edit->start_display); + edit_push_undo_action (edit, KEY_PRESS + edit->start_display); if (exp) { if (!*exp) From 03363eac7198cc032401b56bc912575e8abafa26 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Mon, 20 Dec 2010 18:11:55 +0300 Subject: [PATCH 2/4] added action EditRedo. added functions: * edit_push_redo_action * edit_pop_redo_action * edit_do_redo removed not supported (not actual) code Signed-off-by: Ilia Maslakov --- lib/keybind.c | 1 + lib/keybind.h | 23 +-- src/editor/edit-impl.h | 1 + src/editor/edit-widget.h | 7 + src/editor/edit.c | 341 ++++++++++++++++++++++++--------------- 5 files changed, 235 insertions(+), 138 deletions(-) diff --git a/lib/keybind.c b/lib/keybind.c index 45574e4f3..b36993a24 100644 --- a/lib/keybind.c +++ b/lib/keybind.c @@ -61,6 +61,7 @@ static name_keymap_t command_names[] = { {"EditEnd", CK_End}, {"EditTab", CK_Tab}, {"EditUndo", CK_Undo}, + {"EditRedo", CK_Redo}, {"EditBeginningOfText", CK_Beginning_Of_Text}, {"EditEndOfText", CK_End_Of_Text}, {"EditScrollUp", CK_Scroll_Up}, diff --git a/lib/keybind.h b/lib/keybind.h index e6d71b303..44a92f039 100644 --- a/lib/keybind.h +++ b/lib/keybind.h @@ -30,17 +30,18 @@ #define CK_End 13 #define CK_Tab 14 #define CK_Undo 15 -#define CK_Beginning_Of_Text 16 -#define CK_End_Of_Text 17 -#define CK_Scroll_Up 18 -#define CK_Scroll_Down 19 -#define CK_Return 20 -#define CK_Begin_Page 21 -#define CK_End_Page 22 -#define CK_Delete_Word_Left 23 -#define CK_Delete_Word_Right 24 -#define CK_Paragraph_Up 25 -#define CK_Paragraph_Down 26 +#define CK_Redo 16 +#define CK_Beginning_Of_Text 17 +#define CK_End_Of_Text 18 +#define CK_Scroll_Up 19 +#define CK_Scroll_Down 20 +#define CK_Return 21 +#define CK_Begin_Page 22 +#define CK_End_Page 23 +#define CK_Delete_Word_Left 24 +#define CK_Delete_Word_Right 25 +#define CK_Paragraph_Up 26 +#define CK_Paragraph_Down 27 /* file commands */ #define CK_Save 101 diff --git a/src/editor/edit-impl.h b/src/editor/edit-impl.h index 69213cc4a..b0e593f1e 100644 --- a/src/editor/edit-impl.h +++ b/src/editor/edit-impl.h @@ -260,6 +260,7 @@ void edit_cursor_move (WEdit * edit, long increment); void edit_move_block_to_right (WEdit * edit); void edit_move_block_to_left (WEdit * edit); void edit_push_undo_action (WEdit * edit, long c, ...); +void edit_push_redo_action (WEdit * edit, long c, ...); void edit_push_key_press (WEdit * edit); void edit_insert_ahead (WEdit * edit, int c); long edit_write_stream (WEdit * edit, FILE * f); diff --git a/src/editor/edit-widget.h b/src/editor/edit-widget.h index 82a8c6183..c82e05ad6 100644 --- a/src/editor/edit-widget.h +++ b/src/editor/edit-widget.h @@ -113,6 +113,13 @@ struct WEdit unsigned long undo_stack_bottom; unsigned int undo_stack_disable:1; /* If not 0, don't save events in the undo stack */ + unsigned long redo_stack_pointer; + long *redo_stack; + unsigned long redo_stack_size; + unsigned long redo_stack_size_mask; + unsigned long redo_stack_bottom; + unsigned int redo_stack_reset:1; /* If 1, need clear redo stack */ + struct stat stat1; /* Result of mc_fstat() on the file */ unsigned int skip_detach_prompt:1; /* Do not prompt whether to detach a file anymore */ diff --git a/src/editor/edit.c b/src/editor/edit.c index e7c466475..54adee6bb 100644 --- a/src/editor/edit.c +++ b/src/editor/edit.c @@ -612,6 +612,35 @@ edit_pop_undo_action (WEdit * edit) return c; } +static long +edit_pop_redo_action (WEdit * edit) +{ + long c; + unsigned long sp = edit->redo_stack_pointer; + + if (sp == edit->redo_stack_bottom) + return STACK_BOTTOM; + + sp = (sp - 1) & edit->redo_stack_size_mask; + c = edit->redo_stack[sp]; + if (c >= 0) + { + edit->redo_stack_pointer = (edit->redo_stack_pointer - 1) & edit->redo_stack_size_mask; + return c; + } + + if (sp == edit->redo_stack_bottom) + return STACK_BOTTOM; + + c = edit->redo_stack[(sp - 1) & edit->redo_stack_size_mask]; + if (edit->redo_stack[sp] == -2) + edit->redo_stack_pointer = sp; + else + edit->redo_stack[sp]++; + + return c; +} + /* --------------------------------------------------------------------------------------------- */ /** is called whenever a modification is made by one of the four routines below */ @@ -704,25 +733,6 @@ edit_backspace (WEdit * edit, const int byte_delete) return p; } - -/* --------------------------------------------------------------------------------------------- */ - -#ifdef FAST_MOVE_CURSOR -static void -memqcpy (WEdit * edit, unsigned char *dest, unsigned char *src, int n) -{ - unsigned long next; - while ((next = (unsigned long) memccpy (dest, src, '\n', n))) - { - edit->curs_line--; - next -= (unsigned long) dest; - n -= next; - src += next; - dest += next; - } -} -#endif /* FAST_MOVE_CURSOR */ - /* --------------------------------------------------------------------------------------------- */ /* high level cursor movement commands */ /* --------------------------------------------------------------------------------------------- */ @@ -1289,6 +1299,77 @@ edit_do_undo (WEdit * edit) edit->undo_stack_disable = 0; } +static void +edit_do_redo (WEdit * edit) +{ + long ac; + long count = 0; + + if (edit->redo_stack_reset) + return; + + edit->over_col = 0; + while ((ac = edit_pop_redo_action (edit)) < KEY_PRESS) + { + switch ((int) ac) + { + case STACK_BOTTOM: + goto done_redo; + case CURS_RIGHT: + edit_cursor_move (edit, 1); + break; + case CURS_LEFT: + edit_cursor_move (edit, -1); + break; + case BACKSPACE: + edit_backspace (edit, 1); + break; + case DELCHAR: + edit_delete (edit, 1); + break; + case COLUMN_ON: + edit->column_highlight = 1; + break; + case COLUMN_OFF: + edit->column_highlight = 0; + break; + } + if (ac >= 256 && ac < 512) + edit_insert_ahead (edit, ac - 256); + if (ac >= 0 && ac < 256) + edit_insert (edit, ac); + + if (ac >= MARK_1 - 2 && ac < MARK_2 - 2) + { + edit->mark1 = ac - MARK_1; + edit->column1 = edit_move_forward3 (edit, edit_bol (edit, edit->mark1), 0, edit->mark1); + } + else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) + { + edit->mark2 = ac - MARK_2; + edit->column2 = edit_move_forward3 (edit, edit_bol (edit, edit->mark2), 0, edit->mark2); + } + /* more than one pop usually means something big */ + if (count++) + edit->force |= REDRAW_PAGE; + } + + if (edit->start_display > ac - KEY_PRESS) + { + edit->start_line -= edit_count_lines (edit, ac - KEY_PRESS, edit->start_display); + edit->force |= REDRAW_PAGE; + } + else if (edit->start_display < ac - KEY_PRESS) + { + edit->start_line += edit_count_lines (edit, edit->start_display, ac - KEY_PRESS); + edit->force |= REDRAW_PAGE; + } + edit->start_display = ac - KEY_PRESS; /* see push and pop above */ + edit_update_curs_row (edit); + + done_redo:; +} + /* --------------------------------------------------------------------------------------------- */ static void @@ -2031,6 +2112,10 @@ edit_init (WEdit * edit, int lines, int columns, const char *filename, long line edit->undo_stack_size_mask = START_STACK_SIZE - 1; edit->undo_stack = g_malloc0 ((edit->undo_stack_size + 10) * sizeof (long)); + edit->redo_stack_size = START_STACK_SIZE; + edit->redo_stack_size_mask = START_STACK_SIZE - 1; + edit->redo_stack = g_malloc0 ((edit->redo_stack_size + 10) * sizeof (long)); + edit->utf8 = 0; edit->converter = str_cnv_from_term; edit_set_codeset (edit); @@ -2104,6 +2189,7 @@ edit_clean (WEdit * edit) } g_free (edit->undo_stack); + g_free (edit->redo_stack); g_free (edit->filename); g_free (edit->dir); @@ -2283,7 +2369,15 @@ edit_push_undo_action (WEdit * edit, long c, ...) } spm1 = (edit->undo_stack_pointer - 1) & edit->undo_stack_size_mask; if (edit->undo_stack_disable) + { + edit_push_redo_action (edit, KEY_PRESS); + edit_push_redo_action (edit, c); return; + } + else if (edit->redo_stack_reset) + { + edit->redo_stack_bottom = edit->redo_stack_pointer = 0; + } if (edit->undo_stack_bottom != sp && spm1 != edit->undo_stack_bottom @@ -2298,11 +2392,12 @@ edit_push_undo_action (WEdit * edit, long c, ...) if (edit->undo_stack[spm1] > -1000000000) { if (c < KEY_PRESS) /* --> no need to push multiple do-nothings */ + { edit->undo_stack[spm1]--; + } return; } } - /* #define NO_STACK_CURSMOVE_ANIHILATION */ } else { @@ -2337,7 +2432,93 @@ edit_push_undo_action (WEdit * edit, long c, ...) /*If a single key produced enough pushes to wrap all the way round then we would notice that the [undo_stack_bottom] does not contain KEY_PRESS. The stack is then initialised: */ if (edit->undo_stack_pointer != edit->undo_stack_bottom && edit->undo_stack[edit->undo_stack_bottom] < KEY_PRESS) + { edit->undo_stack_bottom = edit->undo_stack_pointer = 0; + } +} + +void +edit_push_redo_action (WEdit * edit, long c, ...) +{ + unsigned long sp = edit->redo_stack_pointer; + unsigned long spm1; + long *t; + /* first enlarge the stack if necessary */ + if (sp > edit->redo_stack_size - 10) + { /* say */ + if (option_max_undo < 256) + option_max_undo = 256; + if (edit->redo_stack_size < (unsigned long) option_max_undo) + { + t = g_realloc (edit->redo_stack, (edit->redo_stack_size * 2 + 10) * sizeof (long)); + if (t) + { + edit->redo_stack = t; + edit->redo_stack_size <<= 1; + edit->redo_stack_size_mask = edit->redo_stack_size - 1; + } + } + } + spm1 = (edit->redo_stack_pointer - 1) & edit->redo_stack_size_mask; + + if (edit->redo_stack_bottom != sp + && spm1 != edit->redo_stack_bottom + && ((sp - 2) & edit->redo_stack_size_mask) != edit->redo_stack_bottom) + { + int d; + if (edit->redo_stack[spm1] < 0) + { + d = edit->redo_stack[(sp - 2) & edit->redo_stack_size_mask]; + if (d == c) + { + if (edit->redo_stack[spm1] > -1000000000) + { + if (c < KEY_PRESS) /* --> no need to push multiple do-nothings */ + edit->redo_stack[spm1]--; + return; + } + } + } + else + { + d = edit->redo_stack[spm1]; + if (d == c) + { + if (c >= KEY_PRESS) + return; /* --> no need to push multiple do-nothings */ + edit->redo_stack[sp] = -2; + goto redo_check_bottom; + } + } + } + edit->redo_stack[sp] = c; + + redo_check_bottom: + edit->redo_stack_pointer = (edit->redo_stack_pointer + 1) & edit->redo_stack_size_mask; + + /* if the sp wraps round and catches the redo_stack_bottom then erase + * the first set of actions on the stack to make space - by moving + * redo_stack_bottom forward one "key press" */ + c = (edit->redo_stack_pointer + 2) & edit->redo_stack_size_mask; + if ((unsigned long) c == edit->redo_stack_bottom || + (((unsigned long) c + 1) & edit->redo_stack_size_mask) == edit->redo_stack_bottom) + do + { + edit->redo_stack_bottom = (edit->redo_stack_bottom + 1) & edit->redo_stack_size_mask; + } + while (edit->redo_stack[edit->redo_stack_bottom] < KEY_PRESS + && edit->redo_stack_bottom != edit->redo_stack_pointer); + + /* + * If a single key produced enough pushes to wrap all the way round then + * we would notice that the [redo_stack_bottom] does not contain KEY_PRESS. + * The stack is then initialised: + */ + + if (edit->redo_stack_pointer != edit->redo_stack_bottom + && edit->redo_stack[edit->redo_stack_bottom] < KEY_PRESS) + edit->redo_stack_bottom = edit->redo_stack_pointer = 0; + } /* --------------------------------------------------------------------------------------------- */ @@ -2503,105 +2684,6 @@ edit_delete (WEdit * edit, const int byte_delete) return p; } -/* --------------------------------------------------------------------------------------------- */ - -#ifdef FAST_MOVE_CURSOR -int -edit_move_backward_lots (WEdit * edit, long increment) -{ - int r, s, t; - unsigned char *p = NULL; - - if (increment > edit->curs1) - increment = edit->curs1; - if (increment <= 0) - return -1; - edit_push_undo_action (edit, CURS_RIGHT_LOTS, increment); - - t = r = EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE); - if (r > increment) - r = increment; - s = edit->curs1 & M_EDIT_BUF_SIZE; - - if (s > r) - { - memqcpy (edit, - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] + t - r, - edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] + s - r, r); - } - else - { - if (s != 0) - { - memqcpy (edit, - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] + t - - s, edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE], s); - p = edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE]; - edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = 0; - } - memqcpy (edit, - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] + t - r, - edit->buffers1[(edit->curs1 >> S_EDIT_BUF_SIZE) - 1] + - EDIT_BUF_SIZE - (r - s), r - s); - } - increment -= r; - edit->curs1 -= r; - edit->curs2 += r; - if (!(edit->curs2 & M_EDIT_BUF_SIZE)) - { - if (p) - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; - else - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = g_malloc0 (EDIT_BUF_SIZE); - } - else - { - g_free (p); - } - - s = edit->curs1 & M_EDIT_BUF_SIZE; - while (increment) - { - p = 0; - r = EDIT_BUF_SIZE; - if (r > increment) - r = increment; - t = s; - if (r < t) - t = r; - memqcpy (edit, - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] + - EDIT_BUF_SIZE - t, edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] + s - t, t); - if (r >= s) - { - if (t) - { - p = edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE]; - edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = 0; - } - memqcpy (edit, - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] + - EDIT_BUF_SIZE - r, - edit->buffers1[(edit->curs1 >> S_EDIT_BUF_SIZE) - 1] + - EDIT_BUF_SIZE - (r - s), r - s); - } - increment -= r; - edit->curs1 -= r; - edit->curs2 += r; - if (!(edit->curs2 & M_EDIT_BUF_SIZE)) - { - if (p) - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; - else - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = g_malloc0 (EDIT_BUF_SIZE); - } - else - g_free (p); - } - return edit_get_byte (edit, edit->curs1); -} -#endif /* ! FAST_MOVE_CURSOR */ - /* --------------------------------------------------------------------------------------------- */ /** moves the cursor right or left: increment positive or negative respectively */ @@ -2610,14 +2692,6 @@ edit_cursor_move (WEdit * edit, long increment) { /* this is the same as a combination of two of the above routines, with only one push onto the undo stack */ int c; -#ifdef FAST_MOVE_CURSOR - if (increment < -256) - { - edit->force |= REDRAW_PAGE; - edit_move_backward_lots (edit, -increment); - return; - } -#endif /* ! FAST_MOVE_CURSOR */ if (increment < 0) { @@ -3251,12 +3325,25 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) /* first check for undo */ if (command == CK_Undo) { + edit->redo_stack_reset = 0; edit_do_undo (edit); edit->found_len = 0; edit->prev_col = edit_get_col (edit); edit->search_start = edit->curs1; return; } + /* check for redo */ + if (command == CK_Redo) + { + edit->redo_stack_reset = 0; + edit_do_redo (edit); + edit->found_len = 0; + edit->prev_col = edit_get_col (edit); + edit->search_start = edit->curs1; + return; + } + + edit->redo_stack_reset = 1; /* An ordinary key press */ if (char_for_insertion >= 0) From 6832b8e7e9889cba5b5f004fb9273fe74831628f Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Sun, 26 Dec 2010 14:06:11 +0000 Subject: [PATCH 3/4] binded EditRedo on alt-r added entry Redo into editor menu Signed-off-by: Ilia Maslakov --- misc/mc.keymap.default | 1 + src/editor/editmenu.c | 1 + 2 files changed, 2 insertions(+) diff --git a/misc/mc.keymap.default b/misc/mc.keymap.default index 1b7928176..90f60b98a 100644 --- a/misc/mc.keymap.default +++ b/misc/mc.keymap.default @@ -23,6 +23,7 @@ EditHome = home EditEnd = end EditTab = tab EditUndo = ctrl-u +EditRedo = alt-r EditBeginningOfText = ctrl-home; alt-lt EditEndOfText = ctrl-end; alt-gt EditScrollUp = ctrl-up diff --git a/src/editor/editmenu.c b/src/editor/editmenu.c index aeb964eef..444bb7da2 100644 --- a/src/editor/editmenu.c +++ b/src/editor/editmenu.c @@ -93,6 +93,7 @@ create_edit_menu (void) GList *entries = NULL; entries = g_list_append (entries, menu_entry_create (_("&Undo"), CK_Undo)); + entries = g_list_append (entries, menu_entry_create (_("&Redo"), CK_Redo)); entries = g_list_append (entries, menu_separator_create ()); entries = g_list_append (entries, menu_entry_create (_("&Toggle ins/overw"), CK_Toggle_Insert)); entries = g_list_append (entries, menu_separator_create ()); From d84fb5d0cec80b868d814af955f0d01988c50748 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Sun, 26 Dec 2010 17:55:24 +0000 Subject: [PATCH 4/4] updated default_editor_keymap, added default for CK_Redo Signed-off-by: Ilia Maslakov --- src/keybind-defaults.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/keybind-defaults.c b/src/keybind-defaults.c index c17ec0778..381e44e5b 100644 --- a/src/keybind-defaults.c +++ b/src/keybind-defaults.c @@ -287,6 +287,7 @@ const global_keymap_t default_editor_keymap[] = { {XCTRL ('o'), CK_Shell, "C-o"}, {XCTRL ('s'), CK_Toggle_Syntax, "C-s"}, {XCTRL ('u'), CK_Undo, "C-u"}, + {ALT ('r'), CK_Redo, "M-r"}, {ALT ('e'), CK_SelectCodepage, "M-e"}, {XCTRL ('q'), CK_Insert_Literal, "C-q"}, {XCTRL ('r'), CK_Begin_End_Macro, "C-r"},