diff --git a/src/global.c b/src/global.c index 46633e38..12b61055 100644 --- a/src/global.c +++ b/src/global.c @@ -959,6 +959,12 @@ void shortcut_init(void) add_to_funcs(do_suspend_void, MMAIN, N_("Suspend"), IFSCHELP(nano_suspend_msg), BLANKAFTER, VIEW); + add_to_funcs(do_macro, MMAIN, + N_("Macro"), IFSCHELP(nano_suspend_msg), BLANKAFTER, VIEW); + + add_to_funcs(do_play, MMAIN, + N_("Play Macro"), IFSCHELP(nano_suspend_msg), BLANKAFTER, VIEW); + #ifndef NANO_TINY add_to_funcs(do_indent, MMAIN, N_("Indent Text"), IFSCHELP(nano_indent_msg), TOGETHER, NOVIEW); @@ -1431,6 +1437,64 @@ const char *flagtostr(int flag) } #endif /* !NANO_TINY */ +#define MAX_MACRO_LENGTH 10 +static bool handling_macro = 0; +static bool rec_macro = 0; +static int macro_pos = 0; +static int macro[MAX_MACRO_LENGTH]; + +void handle_macro_in(int action) +{ + if (handling_macro) + return; + + handling_macro = 1; + + if (rec_macro && macro_pos < MAX_MACRO_LENGTH) + macro[macro_pos++] = action; +} + +void handle_macro_out() +{ + handling_macro = 0; +} + +void do_macro(void) +{ + if (rec_macro) + statusline(ALERT, _("Stopped recording macro")); + else { + macro_pos = 0; + statusline(ALERT, _("Recording macro")); + } + + rec_macro = 1 - rec_macro; +} + +void do_play(void) +{ + int i; + statusline(ALERT, _("Playing macro")); + for (i = 0; i < macro_pos; i++) + switch (macro[i]) { + case ACTION_DOWN: + do_down_void(); + break; + case ACTION_END: + do_end(); + break; + case ACTION_LEFT: + do_left(); + break; + case ACTION_BACKSPACE: + do_backspace(); + break; + default: + break; + } + edit_refresh(); +} + #ifdef ENABLE_NANORC /* Interpret a function string given in the rc file, and return a * shortcut struct with the corresponding function filled in. */ @@ -1449,6 +1513,10 @@ sc *strtosc(const char *input) #endif if (!strcasecmp(input, "cancel")) s->scfunc = do_cancel; + else if (!strcasecmp(input, "macro")) + s->scfunc = do_macro; + else if (!strcasecmp(input, "play")) + s->scfunc = do_play; else if (!strcasecmp(input, "exit")) s->scfunc = do_exit; else if (!strcasecmp(input, "discardbuffer")) diff --git a/src/move.c b/src/move.c index b36b4bca..f9e5d410 100644 --- a/src/move.c +++ b/src/move.c @@ -440,6 +440,7 @@ void do_end(void) size_t line_len = strlen(openfile->current->data); bool moved_off_chunk = TRUE; + handle_macro_in(ACTION_END); #ifndef NANO_TINY if (ISSET(SOFTWRAP)) { bool last_chunk = FALSE; @@ -479,6 +480,7 @@ void do_end(void) edit_redraw(was_current, FLOWING); else if (line_needs_update(was_column, openfile->placewewant)) update_line(openfile->current, openfile->current_x); + handle_macro_out(); } /* Move the cursor to the preceding line or chunk. If scroll_only is TRUE, @@ -543,7 +545,9 @@ void do_up_void(void) /* Move down one line or chunk. */ void do_down_void(void) { + handle_macro_in(ACTION_DOWN); do_down(FALSE); + handle_macro_out(); } #ifndef NANO_TINY @@ -564,6 +568,7 @@ void do_scroll_down(void) void do_left(void) { filestruct *was_current = openfile->current; + handle_macro_in(ACTION_LEFT); if (openfile->current_x > 0) openfile->current_x = move_mbleft(openfile->current->data, @@ -574,6 +579,7 @@ void do_left(void) } edit_redraw(was_current, FLOWING); + handle_macro_out(); } /* Move right one character. */ diff --git a/src/nano.h b/src/nano.h index 7960d3be..1e382f40 100644 --- a/src/nano.h +++ b/src/nano.h @@ -507,6 +507,8 @@ enum NO_COLOR_SYNTAX, PRESERVE, HISTORYLOG, + MACRO, + PLAY, RESTRICTED, SMART_HOME, WHITESPACE_DISPLAY, @@ -529,6 +531,15 @@ enum AT_BLANKS }; +/* Enumaration used as macros' actions */ +enum +{ + ACTION_DOWN, + ACTION_END, + ACTION_LEFT, + ACTION_BACKSPACE, +}; + /* Flags for the menus in which a given function should be present. */ #define MMAIN (1<<0) #define MWHEREIS (1<<1) diff --git a/src/proto.h b/src/proto.h index 71c12d40..c7b3e3b4 100644 --- a/src/proto.h +++ b/src/proto.h @@ -700,6 +700,10 @@ void do_credits(void); /* These are just name definitions. */ void do_cancel(void); +void do_macro(void); +void do_play(void); +void handle_macro_in(int action); +void handle_macro_out(); void case_sens_void(void); void regexp_void(void); void backwards_void(void); diff --git a/src/rcfile.c b/src/rcfile.c index 2988d4fc..c2a41b86 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -50,6 +50,8 @@ static const rcoption rcopts[] = { #ifndef DISABLE_HISTORIES {"historylog", HISTORYLOG}, #endif + {"macro", MACRO}, + {"play", PLAY}, {"morespace", MORE_SPACE}, #ifdef ENABLE_MOUSE {"mouse", USE_MOUSE}, diff --git a/src/text.c b/src/text.c index 1cc867d4..eb5af670 100644 --- a/src/text.c +++ b/src/text.c @@ -189,10 +189,12 @@ void do_delete(void) * character, and then delete the character under the cursor. */ void do_backspace(void) { + handle_macro_in(ACTION_BACKSPACE); if (openfile->current != openfile->fileage || openfile->current_x > 0) { do_left(); do_deletion(BACK); } + handle_macro_out(); } #ifndef NANO_TINY