From 0d01c262c0ed23ef950530c743b023e89ef4a821 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Thu, 8 Nov 2012 02:21:36 +0100 Subject: support line termination ($$) as immediate editing command + some fixes * separate function for immediate editing command processing * undo.clear() to remove and free all undo tokens without executing them * goto_table_clear() to remove and free all goto table entries --- cmdline.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++------------------ goto.cpp | 6 ++++++ goto.h | 2 ++ parser.cpp | 2 +- undo.cpp | 11 +++++++++++ undo.h | 2 ++ 6 files changed, 66 insertions(+), 19 deletions(-) diff --git a/cmdline.cpp b/cmdline.cpp index e0159ec..b9c58a0 100644 --- a/cmdline.cpp +++ b/cmdline.cpp @@ -5,8 +5,10 @@ #include "sciteco.h" #include "parser.h" +#include "goto.h" #include "undo.h" +static inline const gchar *process_edit_cmd(gchar key); static gchar *macro_echo(const gchar *macro, const gchar *prefix = ""); gchar *cmdline = NULL; @@ -14,27 +16,14 @@ gchar *cmdline = NULL; void cmdline_keypress(gchar key) { - gchar insert[255] = ""; + const gchar *insert; gint old_cmdline_len = 0; gchar *echo; /* * Process immediate editing commands */ - switch (key) { - case '\b': - if (!cmdline || !*cmdline) - break; - old_cmdline_len = strlen(cmdline); - - undo.pop(old_cmdline_len); - cmdline[old_cmdline_len-1] = '\0'; - macro_pc--; - break; - default: - insert[0] = key; - insert[1] = '\0'; - } + insert = process_edit_cmd(key); /* * Parse/execute characters @@ -44,12 +33,12 @@ cmdline_keypress(gchar key) cmdline = (gchar *)g_realloc(cmdline, old_cmdline_len + strlen(insert) + 1); } else { - cmdline = (gchar *)g_malloc(2); + cmdline = (gchar *)g_malloc(strlen(insert) + 1); *cmdline = '\0'; } - for (gchar *p = insert; *p; p++) { - strcat(cmdline, (gchar[]){key, '\0'}); + for (const gchar *p = insert; *p; p++) { + strcat(cmdline, (gchar[]){*p, '\0'}); if (!macro_execute(cmdline)) { cmdline[old_cmdline_len] = '\0'; @@ -65,6 +54,43 @@ cmdline_keypress(gchar key) g_free(echo); } +static inline const gchar * +process_edit_cmd(gchar key) +{ + static gchar insert[255]; + gint cmdline_len = cmdline ? strlen(cmdline) : 0; + + insert[0] = '\0'; + + switch (key) { + case '\b': + if (cmdline_len) { + undo.pop(cmdline_len); + cmdline[cmdline_len - 1] = '\0'; + macro_pc--; + } + break; + + case '\x1B': + if (cmdline && cmdline[cmdline_len - 1] == '\x1B') { + /* TODO: exit if previously requested */ + + undo.clear(); + goto_table_clear(); + + *cmdline = '\0'; + macro_pc = 0; + break; + } + /* fall through */ + default: + insert[0] = key; + insert[1] = '\0'; + } + + return insert; +} + static gchar * macro_echo(const gchar *macro, const gchar *prefix) { diff --git a/goto.cpp b/goto.cpp index 3785076..f4d9497 100644 --- a/goto.cpp +++ b/goto.cpp @@ -160,6 +160,12 @@ public: static GotoTable table; +void +goto_table_clear(void) +{ + table.clear(); +} + StateLabel::StateLabel() : State() { transitions['\0'] = this; diff --git a/goto.h b/goto.h index 64ae31b..0a83406 100644 --- a/goto.h +++ b/goto.h @@ -14,4 +14,6 @@ private: State *custom(gchar chr); }; +void goto_table_clear(void); + #endif diff --git a/parser.cpp b/parser.cpp index 60c2c49..5eefaf5 100644 --- a/parser.cpp +++ b/parser.cpp @@ -460,7 +460,7 @@ StateControl::custom(gchar chr) #endif /* - * Alternatives: ^[, (cannot be typed), + * Alternatives: ^[, , */ case '[': BEGIN_EXEC(&states.start); diff --git a/undo.cpp b/undo.cpp index 106f812..7a58c92 100644 --- a/undo.cpp +++ b/undo.cpp @@ -47,6 +47,17 @@ UndoStack::pop(gint pos) } } +void +UndoStack::clear(void) +{ + UndoToken *cur; + + while ((cur = SLIST_FIRST(&head))) { + SLIST_REMOVE_HEAD(&head, tokens); + delete cur; + } +} + UndoStack::~UndoStack() { UndoToken *token, *next; diff --git a/undo.h b/undo.h index aeefb09..5b955ab 100644 --- a/undo.h +++ b/undo.h @@ -124,6 +124,8 @@ public: } void pop(gint pos); + + void clear(void); } undo; #endif \ No newline at end of file -- cgit v1.2.3