From 9ddebe6bcf87f8a946f636687975beec80ec8081 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 20 Dec 2001 13:29:20 +0000 Subject: [PATCH] Added command history groups, set them with /WINDOW HISTORY. Patch by peder@ifi.uio.no git-svn-id: http://svn.irssi.org/repos/irssi/trunk@2276 dbcabf3a-b0e7-0310-adc4-f8d773084564 --- docs/perl.txt | 5 +- docs/signals.txt | 1 + src/fe-common/core/command-history.c | 232 +++++++++++++++++++-------- src/fe-common/core/command-history.h | 23 ++- src/fe-common/core/fe-windows.c | 15 ++ src/fe-common/core/fe-windows.h | 6 +- src/fe-common/core/module-formats.c | 1 + src/fe-common/core/module-formats.h | 1 + src/fe-common/core/window-commands.c | 14 ++ src/fe-common/core/windows-layout.c | 5 + src/fe-text/gui-readline.c | 12 +- src/perl/ui/UI.xs | 1 + src/perl/ui/Window.xs | 5 + 13 files changed, 243 insertions(+), 78 deletions(-) diff --git a/docs/perl.txt b/docs/perl.txt index 204259c4..6acf6c2c 100644 --- a/docs/perl.txt +++ b/docs/perl.txt @@ -336,6 +336,8 @@ UI::Window->{} width - Width height - Height + history_name - Name of named historylist for this window + active - Active window item active_server - Active server @@ -427,8 +429,9 @@ Window::set_active() Window::change_server(server) Window::set_refnum(refnum) Window::set_name(name) +Window::set_history(name) Window::set_level(level) - Change server/refnum/name/level in window. + Change server/refnum/name/history/level in window. Windowitem::set_active() Change window item active in parent window. diff --git a/docs/signals.txt b/docs/signals.txt index 6cf6a075..7a8d466c 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -283,6 +283,7 @@ windows.c: "window server changed", WINDOW_REC, SERVER_REC "window refnum changed", WINDOW_REC, int old "window name changed", WINDOW_REC + "window history changed", WINDOW_REC, char *oldname "window level changed", WINDOW_REC FE IRC diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index cdf4b5a5..1642c798 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -27,119 +27,215 @@ #include "fe-windows.h" #include "window-items.h" +#include "command-history.h" + /* command history */ -static GList *history, *history_pos; -static int history_lines, history_over_counter; +static HISTORY_REC *global_history; static int window_history; +static GSList *histories; -void command_history_add(WINDOW_REC *window, const char *text) +void command_history_add(HISTORY_REC *history, const char *text) { - GList **phistory, *link; - int *phistory_lines; + GList *link; + g_return_if_fail(history != NULL); g_return_if_fail(text != NULL); - if (window_history) { - /* window specific command history */ - phistory = &window->history; - phistory_lines = &window->history_lines; - } else { - /* global command history */ - phistory = &history; - phistory_lines = &history_lines; - } - - if (settings_get_int("max_command_history") < 1 || *phistory_lines < settings_get_int("max_command_history")) - (*phistory_lines)++; + if (settings_get_int("max_command_history") < 1 || + history->lines < settings_get_int("max_command_history")) + history->lines++; else { - link = *phistory; + link = history->list; g_free(link->data); - *phistory = g_list_remove_link(*phistory, link); + history->list = g_list_remove_link(history->list, link); g_list_free_1(link); } - *phistory = g_list_append(*phistory, g_strdup(text)); + history->list = g_list_append(history->list, g_strdup(text)); +} + +HISTORY_REC *command_history_find(HISTORY_REC *history) +{ + GSList *tmp; + tmp = g_slist_find(histories, history); + + if (tmp == NULL) + return NULL; + else + return tmp->data; +} + +HISTORY_REC *command_history_find_name(const char *name) +{ + GSList *tmp; + + if (name == NULL) + return NULL; + + for (tmp = histories; tmp != NULL; tmp = tmp->next) { + HISTORY_REC *rec = tmp->data; + + if (rec->name != NULL && g_strcasecmp(rec->name, name) == 0) + return rec; + } + + return NULL; +} + +HISTORY_REC *command_history_current(WINDOW_REC *window) +{ + HISTORY_REC *rec; + + if (window == NULL) + return global_history; + + if (window_history) + return window->history; + + rec = command_history_find_name(window->history_name); + if (rec != NULL) + return rec; + + return global_history; } const char *command_history_prev(WINDOW_REC *window, const char *text) { - GList *pos, **phistory_pos; - int *phistory_over_counter; + HISTORY_REC *history; + GList *pos; - if (window_history) { - phistory_pos = &window->history_pos; - phistory_over_counter = &window->history_over_counter; - } else { - phistory_pos = &history_pos; - phistory_over_counter = &history_over_counter; - } + history = command_history_current(window); + pos = history->pos; - pos = *phistory_pos; - if (*phistory_pos != NULL) { - *phistory_pos = (*phistory_pos)->prev; - if (*phistory_pos == NULL) - (*phistory_over_counter)++; + if (pos != NULL) { + history->pos = history->pos->prev; + if (history->pos == NULL) + history->over_counter++; } else { - *phistory_pos = g_list_last(window_history ? - window->history : history); + history->pos = g_list_last(history->list); } if (*text != '\0' && (pos == NULL || strcmp(pos->data, text) != 0)) { /* save the old entry to history */ - command_history_add(window, text); + command_history_add(history, text); } - return *phistory_pos == NULL ? "" : (*phistory_pos)->data; + return history->pos == NULL ? "" : history->pos->data; } const char *command_history_next(WINDOW_REC *window, const char *text) { - GList *pos, **phistory_pos; - int *phistory_over_counter; + HISTORY_REC *history; + GList *pos; - if (window_history) { - phistory_pos = &window->history_pos; - phistory_over_counter = &window->history_over_counter; - } else { - phistory_pos = &history_pos; - phistory_over_counter = &history_over_counter; - } - - pos = *phistory_pos; + history = command_history_current(window); + pos = history->pos; if (pos != NULL) - *phistory_pos = (*phistory_pos)->next; - else if (*phistory_over_counter > 0) { - (*phistory_over_counter)--; - *phistory_pos = window_history ? window->history : history; + history->pos = history->pos->next; + else if (history->over_counter > 0) { + history->over_counter--; + history->pos = history->list; } if (*text != '\0' && (pos == NULL || strcmp(pos->data, text) != 0)) { /* save the old entry to history */ - command_history_add(window, text); + command_history_add(history, text); } - return *phistory_pos == NULL ? "" : (*phistory_pos)->data; + return history->pos == NULL ? "" : history->pos->data; +} + +void command_history_clear_pos_func(HISTORY_REC *history, gpointer user_data) +{ + history->over_counter = 0; + history->pos = NULL; } void command_history_clear_pos(WINDOW_REC *window) { - window->history_over_counter = 0; - window->history_pos = NULL; - history_over_counter = 0; - history_pos = NULL; + g_slist_foreach(histories, + (GFunc) command_history_clear_pos_func, NULL); +} + +HISTORY_REC *command_history_create(const char *name) +{ + HISTORY_REC *rec; + + rec = g_new0(HISTORY_REC, 1); + + if (name != NULL) + rec->name = g_strdup(name); + + histories = g_slist_append(histories, rec); + + return rec; +} + +void command_history_destroy(HISTORY_REC *history) +{ + g_return_if_fail(history != NULL); + + /* history->refcount should be 0 here, or somthing is wrong... */ + g_return_if_fail(history->refcount == 0); + + histories = g_slist_remove(histories, history); + + g_list_foreach(history->list, (GFunc) g_free, NULL); + g_list_free(history->list); + + g_free_not_null(history->name); + g_free(history); +} + +void command_history_link(const char *name) +{ + HISTORY_REC *rec; + rec = command_history_find_name(name); + + if (rec == NULL) + rec = command_history_create(name); + + rec->refcount++; +} + +void command_history_unlink(const char *name) +{ + HISTORY_REC *rec; + rec = command_history_find_name(name); + + if (rec == NULL) + return; + + if (--(rec->refcount) <= 0) + command_history_destroy(rec); +} + +static void sig_window_created(WINDOW_REC *window, int automatic) +{ + window->history = command_history_create(NULL); } static void sig_window_destroyed(WINDOW_REC *window) { - g_list_foreach(window->history, (GFunc) g_free, NULL); - g_list_free(window->history); + command_history_unlink(window->history_name); + command_history_destroy(window->history); + + g_free_not_null(window->history_name); + g_free_not_null(window->history); +} + +static void sig_window_history_changed(WINDOW_REC *window, const char *oldname) +{ + command_history_link(window->history_name); + command_history_unlink(oldname); } static char *special_history_func(const char *text, void *item, int *free_ret) { WINDOW_REC *window; + HISTORY_REC *history; GList *tmp; char *findtext, *ret; @@ -148,8 +244,8 @@ static char *special_history_func(const char *text, void *item, int *free_ret) findtext = g_strdup_printf("*%s*", text); ret = NULL; - tmp = window_history ? window->history : history; - for (; tmp != NULL; tmp = tmp->next) { + history = command_history_current(window); + for (tmp = history->list; tmp != NULL; tmp = tmp->next) { const char *line = tmp->data; if (match_wildcards(findtext, line)) { @@ -174,19 +270,21 @@ void command_history_init(void) special_history_func_set(special_history_func); - history_lines = 0; history_over_counter = 0; - history = NULL; history_pos = NULL; + global_history = command_history_create(NULL); read_settings(); + signal_add("window created", (SIGNAL_FUNC) sig_window_created); signal_add("window destroyed", (SIGNAL_FUNC) sig_window_destroyed); + signal_add("window history changed", (SIGNAL_FUNC) sig_window_history_changed); signal_add("setup changed", (SIGNAL_FUNC) read_settings); } void command_history_deinit(void) { + signal_remove("window created", (SIGNAL_FUNC) sig_window_created); signal_remove("window destroyed", (SIGNAL_FUNC) sig_window_destroyed); + signal_remove("window history changed", (SIGNAL_FUNC) sig_window_history_changed); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); - g_list_foreach(history, (GFunc) g_free, NULL); - g_list_free(history); + command_history_destroy(global_history); } diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index 9f37f069..2ca312e1 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -1,16 +1,35 @@ #ifndef __COMMAND_HISTORY_H #define __COMMAND_HISTORY_H -#include "fe-windows.h" +#include "common.h" + +typedef struct { + char *name; + + GList *list, *pos; + int lines, over_counter; + + int refcount; +} HISTORY_REC; + +HISTORY_REC *command_history_find(HISTORY_REC *history); +HISTORY_REC *command_history_find_name(const char *name); + +HISTORY_REC *command_history_current(WINDOW_REC *window); void command_history_init(void); void command_history_deinit(void); -void command_history_add(WINDOW_REC *window, const char *text, int prepend); +void command_history_add(HISTORY_REC *window, const char *text); const char *command_history_prev(WINDOW_REC *window, const char *text); const char *command_history_next(WINDOW_REC *window, const char *text); void command_history_clear_pos(WINDOW_REC *window); +HISTORY_REC *command_history_create(const char *name); +void command_history_destroy(HISTORY_REC *history); +void command_history_link(const char *name); +void command_history_unlink(const char *name); + #endif diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index 5eb19314..53ff7a02 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -195,6 +195,21 @@ void window_set_name(WINDOW_REC *window, const char *name) signal_emit("window name changed", 1, window); } +void window_set_history(WINDOW_REC *window, const char *name) +{ + char *oldname; + oldname = window->history_name; + + if (*name == '\0') + window->history_name = NULL; + else + window->history_name = g_strdup(name); + + signal_emit("window history changed", 1, window, oldname); + + g_free_not_null(oldname); +} + void window_set_level(WINDOW_REC *window, int level) { g_return_if_fail(window != NULL); diff --git a/src/fe-common/core/fe-windows.h b/src/fe-common/core/fe-windows.h index 909cd1bc..32004459 100644 --- a/src/fe-common/core/fe-windows.h +++ b/src/fe-common/core/fe-windows.h @@ -2,6 +2,7 @@ #define __WINDOWS_H #include "window-item-def.h" +#include "command-history.h" enum { DATA_LEVEL_NONE = 0, @@ -34,8 +35,8 @@ struct _WINDOW_REC { unsigned int destroying:1; /* window-specific command line history */ - GList *history, *history_pos; - int history_lines, history_over_counter; + HISTORY_REC *history; + char *history_name; int data_level; /* current data level */ char *hilight_color; /* current hilight color in %format */ @@ -62,6 +63,7 @@ void window_change_server(WINDOW_REC *window, void *server); void window_set_refnum(WINDOW_REC *window, int refnum); void window_set_name(WINDOW_REC *window, const char *name); +void window_set_history(WINDOW_REC *window, const char *name); void window_set_level(WINDOW_REC *window, int level); /* return active item's name, or if none is active, window's name */ diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index 79fd7bdc..2a5c8f93 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -49,6 +49,7 @@ FORMAT_REC fecommon_core_formats[] = { { "window_info_refnum", "Window : {hilight #$0}", 1, { 1 } }, { "window_info_refnum_sticky", "Window : {hilight #$0 (sticky)}", 1, { 1 } }, { "window_info_name", "Name : $0", 1, { 0 } }, + { "window_info_history", "History : $0", 1, { 0 } }, { "window_info_size", "Size : $0x$1", 2, { 1, 1 } }, { "window_info_level", "Level : $0", 1, { 0 } }, { "window_info_server", "Server : $0", 1, { 0 } }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index e5e7d99b..fcfd87d5 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -27,6 +27,7 @@ enum { TXT_WINDOW_INFO_REFNUM, TXT_WINDOW_INFO_REFNUM_STICKY, TXT_WINDOW_INFO_NAME, + TXT_WINDOW_INFO_HISTORY, TXT_WINDOW_INFO_SIZE, TXT_WINDOW_INFO_LEVEL, TXT_WINDOW_INFO_SERVER, diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index 34cd3099..e388f23b 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -94,6 +94,12 @@ static void cmd_window_info(WINDOW_REC *win) TXT_WINDOW_INFO_NAME, win->name); } + /* Window history name */ + if (win->history_name != NULL) { + printformat_window(win, MSGLEVEL_CLIENTCRAP, + TXT_WINDOW_INFO_HISTORY, win->history_name); + } + /* Window width / height */ printformat_window(win, MSGLEVEL_CLIENTCRAP, TXT_WINDOW_INFO_SIZE, win->width, win->height); @@ -468,6 +474,12 @@ static void cmd_window_name(const char *data) } } +/* SYNTAX: WINDOW HISTORY */ +void cmd_window_history(const char *data) +{ + window_set_history(active_win, data); +} + /* we're moving the first window to last - move the first contiguous block of refnums to left. Like if there's windows 1..5 and 7..10, move 1 to 11, 2..5 to 1..4 and leave 7..10 alone */ @@ -692,6 +704,7 @@ void window_commands_init(void) command_bind("window item move", NULL, (SIGNAL_FUNC) cmd_window_item_move); command_bind("window number", NULL, (SIGNAL_FUNC) cmd_window_number); command_bind("window name", NULL, (SIGNAL_FUNC) cmd_window_name); + command_bind("window history", NULL, (SIGNAL_FUNC) cmd_window_history); command_bind("window move", NULL, (SIGNAL_FUNC) cmd_window_move); command_bind("window move prev", NULL, (SIGNAL_FUNC) cmd_window_move_prev); command_bind("window move next", NULL, (SIGNAL_FUNC) cmd_window_move_next); @@ -729,6 +742,7 @@ void window_commands_deinit(void) command_unbind("window item move", (SIGNAL_FUNC) cmd_window_item_move); command_unbind("window number", (SIGNAL_FUNC) cmd_window_number); command_unbind("window name", (SIGNAL_FUNC) cmd_window_name); + command_unbind("window history", (SIGNAL_FUNC) cmd_window_history); command_unbind("window move", (SIGNAL_FUNC) cmd_window_move); command_unbind("window move prev", (SIGNAL_FUNC) cmd_window_move_prev); command_unbind("window move next", (SIGNAL_FUNC) cmd_window_move_next); diff --git a/src/fe-common/core/windows-layout.c b/src/fe-common/core/windows-layout.c index 060fb7a0..9615006e 100644 --- a/src/fe-common/core/windows-layout.c +++ b/src/fe-common/core/windows-layout.c @@ -116,6 +116,7 @@ static void sig_layout_restore(void) window_set_refnum(window, atoi(node->key)); window->sticky_refnum = config_node_get_bool(node, "sticky_refnum", FALSE); window_set_name(window, config_node_get_str(node, "name", NULL)); + window_set_history(window, config_node_get_str(node, "history_name", NULL)); window_set_level(window, level2bits(config_node_get_str(node, "level", ""))); window->servertag = g_strdup(config_node_get_str(node, "servertag", NULL)); @@ -170,6 +171,10 @@ static void window_save(WINDOW_REC *window, CONFIG_NODE *node) if (window->name != NULL) iconfig_node_set_str(node, "name", window->name); + + if (window->history_name != NULL) + iconfig_node_set_str(node, "history_name", window->history_name); + if (window->servertag != NULL) iconfig_node_set_str(node, "servertag", window->servertag); if (window->level != 0) { diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 04c0fa09..0bdbbf0e 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -166,7 +166,7 @@ void handle_key(int key) static void key_send_line(void) { - WINDOW_REC *history_window; + HISTORY_REC *history; char *str, *add_history; str = gui_entry_get_text(active_entry); @@ -175,7 +175,8 @@ static void key_send_line(void) /* we can't use gui_entry_get_text() later, since the entry might have been destroyed after we get back */ add_history = g_strdup(str); - history_window = active_win; + history = command_history_current(active_win); + translate_output(str); if (redir == NULL) { @@ -189,10 +190,9 @@ static void key_send_line(void) } if (add_history != NULL) { - if (!settings_get_bool("window_history") || - (history_window != NULL && - g_slist_find(windows, history_window) != NULL)) - command_history_add(history_window, add_history, FALSE); + history = command_history_find(history); + if (history != NULL) + command_history_add(history, add_history); g_free(add_history); } diff --git a/src/perl/ui/UI.xs b/src/perl/ui/UI.xs index 2b55e8cb..83c2a366 100644 --- a/src/perl/ui/UI.xs +++ b/src/perl/ui/UI.xs @@ -23,6 +23,7 @@ static void perl_window_fill_hash(HV *hv, WINDOW_REC *window) { hv_store(hv, "refnum", 6, newSViv(window->refnum), 0); hv_store(hv, "name", 4, new_pv(window->name), 0); + hv_store(hv, "history_name", 12, new_pv(window->history_name), 0); hv_store(hv, "width", 5, newSViv(window->width), 0); hv_store(hv, "height", 6, newSViv(window->height), 0); diff --git a/src/perl/ui/Window.xs b/src/perl/ui/Window.xs index b4ab69a8..d6183789 100644 --- a/src/perl/ui/Window.xs +++ b/src/perl/ui/Window.xs @@ -205,6 +205,11 @@ window_set_name(window, name) Irssi::UI::Window window char *name +void +window_set_history(window, name) + Irssi::UI::Window window + char *name + void window_set_level(window, level) Irssi::UI::Window window