diff options
Diffstat (limited to 'src/fe-common')
-rw-r--r-- | src/fe-common/core/chat-completion.c | 55 | ||||
-rw-r--r-- | src/fe-common/core/fe-common-core.c | 51 | ||||
-rw-r--r-- | src/fe-common/core/fe-windows.h | 8 | ||||
-rw-r--r-- | src/fe-common/core/formats.c | 27 | ||||
-rw-r--r-- | src/fe-common/core/themes.c | 2 | ||||
-rw-r--r-- | src/fe-common/core/window-commands.c | 7 | ||||
-rw-r--r-- | src/fe-common/core/window-items.c | 2 | ||||
-rw-r--r-- | src/fe-common/irc/fe-netjoin.c | 19 | ||||
-rw-r--r-- | src/fe-common/irc/fe-netsplit.c | 22 |
9 files changed, 135 insertions, 58 deletions
diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index 97cd0565..7ecdd4a2 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -639,6 +639,59 @@ static void complete_window_nicks(GList **list, WINDOW_REC *window, } } +/* Checks if a line is only nicks from autocompletion. + This lets us insert colons only at the beginning of a list + of nicks */ +static int only_nicks(const char *linestart) +{ + int i = 1; + char prev; + + // at the beginning of the line + if (*linestart == '\0') { + return TRUE; + } + + /* completion_char being a whole string introduces loads of edge cases + and can't be handled generally. Skip this case; we handled the + "beginning of line" case already */ + if (completion_char[1] != '\0') + return FALSE; + + /* This would make the completion char get inserted everywhere otherwise */ + if (*completion_char == ' ') + return FALSE; + + /* First ensure that the line is of the format "foo: bar: baz" + we check this by ensuring each space is preceded by a colon or + another space */ + while (linestart[i] != '\0') { + if (linestart[i] == ' ') { + prev = linestart[i - 1]; + if (prev != *completion_char && prev != ' ') + return FALSE; + } + i += 1; + } + + /* There's an edge case here, if we're completing something + like `foo: bar ba<tab>`, then the `linestart` line will end + at "bar", and we'll miss the space. Ensure that the end + of the line is a colon followed by an optional series of spaces */ + i -= 1; + while (i >= 0) { + if (linestart[i] == ' ') { + i--; + continue; + } else if (linestart[i] == *completion_char) { + return TRUE; + } else { + break; + } + } + return FALSE; +} + static void sig_complete_word(GList **list, WINDOW_REC *window, const char *word, const char *linestart, int *want_space) @@ -691,7 +744,7 @@ static void sig_complete_word(GList **list, WINDOW_REC *window, } else if (channel != NULL) { /* nick completion .. we could also be completing a nick after /MSG from nicks in channel */ - const char *suffix = *linestart != '\0' ? NULL : completion_char; + const char *suffix = only_nicks(linestart) ? completion_char : NULL; complete_window_nicks(list, window, word, suffix); } else if (window->level & MSGLEVEL_MSGS) { /* msgs window, complete /MSG nicks */ diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index a3b7364c..209c2d9e 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -470,26 +470,49 @@ void fe_common_core_finish_init(void) gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) { + WI_ITEM_REC *item; + int server_tag_len, channel_type, query_type; + char **tmp; + + channel_type = module_get_uniq_id_str("WINDOW ITEM TYPE", "CHANNEL"); + query_type = module_get_uniq_id_str("WINDOW ITEM TYPE", "QUERY"); + g_return_val_if_fail(array != NULL, FALSE); + g_return_val_if_fail(dest != NULL, FALSE); + g_return_val_if_fail(dest->window != NULL, FALSE); + g_return_val_if_fail(dest->target != NULL, FALSE); - if (strarray_find(array, "*") != -1) - return TRUE; + item = window_item_find_window(dest->window, dest->server, dest->target); + if (item == NULL) { + return FALSE; + } - if (strarray_find(array, dest->target) != -1) - return TRUE; + server_tag_len = dest->server_tag != NULL ? strlen(dest->server_tag) : 0; + for (tmp = array; *tmp != NULL; tmp++) { + char *str = *tmp; + if (*str == '\0') { + continue; + } - if (dest->server_tag != NULL) { - char *tagtarget = g_strdup_printf("%s/%s", dest->server_tag, "*"); - int ret = strarray_find(array, tagtarget); - g_free(tagtarget); - if (ret != -1) - return TRUE; + if (server_tag_len && + g_ascii_strncasecmp(str, dest->server_tag, server_tag_len) == 0 && + str[server_tag_len] == '/') { + str += server_tag_len + 1; + } - tagtarget = g_strdup_printf("%s/%s", dest->server_tag, dest->target); - ret = strarray_find(array, tagtarget); - g_free(tagtarget); - if (ret != -1) + if (g_strcmp0(str, "") == 0 || g_strcmp0(str, "::all") == 0) { return TRUE; + } else if (g_ascii_strcasecmp(str, dest->target) == 0) { + return TRUE; + } else if (item->type == query_type && + g_strcmp0(str, dest->target[0] == '=' ? "::dccqueries" : + "::queries") == 0) { + return TRUE; + } else if (item->type == channel_type && + g_strcmp0(str, "::channels") == 0) { + return TRUE; + } } + return FALSE; } diff --git a/src/fe-common/core/fe-windows.h b/src/fe-common/core/fe-windows.h index 32d6cfcd..aaa773c8 100644 --- a/src/fe-common/core/fe-windows.h +++ b/src/fe-common/core/fe-windows.h @@ -11,6 +11,14 @@ enum { DATA_LEVEL_HILIGHT }; +enum { + MAIN_WINDOW_TYPE_NONE = -1, + MAIN_WINDOW_TYPE_DEFAULT = 0, + MAIN_WINDOW_TYPE_HIDDEN = 1, + MAIN_WINDOW_TYPE_SPLIT = 2, + MAIN_WINDOW_TYPE_RSPLIT = 3 +}; + typedef struct { char *servertag; char *name; diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 37db6f7c..4c819c2d 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -480,27 +480,30 @@ int format_real_length(const char *str, int len) start = str; tmp = g_string_new(NULL); - while (*str != '\0' && len > 0) { + while (*str != '\0') { + oldstr = str; if (*str == '%' && str[1] != '\0') { str++; if (*str != '%') { adv = format_expand_styles(tmp, &str, NULL); - str += adv; - if (adv) - continue; - } - - /* %% or unknown %code, written as-is */ - if (*str != '%') { - if (--len == 0) - break; + if (adv) { + str += adv; + continue; + } + /* discount for unknown % */ + if (--len < 0) { + str = oldstr; + break; + } + oldstr = str; } } - oldstr = str; len -= string_advance(&str, utf8); - if (len < 0) + if (len < 0) { str = oldstr; + break; + } } g_string_free(tmp, TRUE); diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index cb1cce8f..6692985b 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -130,7 +130,7 @@ static char *theme_replace_expand(THEME_REC *theme, int index, abstract = rec->data; abstract = theme_format_expand_data(theme, (const char **) &abstract, default_fg, default_bg, - last_fg, last_bg, flags); + last_fg, last_bg, (flags | EXPAND_FLAG_IGNORE_REPLACES)); ret = parse_special_string(abstract, NULL, NULL, data, NULL, PARSE_FLAG_ONLY_ARGS); g_free(abstract); diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index 57c81ac2..a81c0180 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -169,7 +169,7 @@ static void cmd_window(const char *data, void *server, WI_ITEM_REC *item) command_runsub("window", data, server, item); } -/* SYNTAX: WINDOW NEW [HIDDEN|SPLIT] */ +/* SYNTAX: WINDOW NEW [HIDDEN|SPLIT|RSPLIT] */ static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item) { WINDOW_REC *window; @@ -177,8 +177,9 @@ static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item) g_return_if_fail(data != NULL); - type = (g_ascii_strncasecmp(data, "hid", 3) == 0 || g_ascii_strcasecmp(data, "tab") == 0) ? 1 : - (g_ascii_strcasecmp(data, "split") == 0 ? 2 : 0); + type = (g_ascii_strncasecmp(data, "hid", 3) == 0 || g_ascii_strcasecmp(data, "tab") == 0) ? MAIN_WINDOW_TYPE_HIDDEN : + g_ascii_strcasecmp(data, "split") == 0 ? MAIN_WINDOW_TYPE_SPLIT : + g_ascii_strncasecmp(data, "rs", 2) == 0 ? MAIN_WINDOW_TYPE_RSPLIT : MAIN_WINDOW_TYPE_DEFAULT; signal_emit("gui window create override", 1, GINT_TO_POINTER(type)); window = window_create(NULL, FALSE); diff --git a/src/fe-common/core/window-items.c b/src/fe-common/core/window-items.c index bd6ae5e9..8eab7124 100644 --- a/src/fe-common/core/window-items.c +++ b/src/fe-common/core/window-items.c @@ -314,7 +314,7 @@ void window_item_create(WI_ITEM_REC *item, int automatic) /* create new window to use */ if (settings_get_bool("autocreate_split_windows")) { signal_emit("gui window create override", 1, - GINT_TO_POINTER(0)); + GINT_TO_POINTER(MAIN_WINDOW_TYPE_SPLIT)); } window = window_create(item, automatic); } else { diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c index 8272093f..a7a2e4fe 100644 --- a/src/fe-common/irc/fe-netjoin.c +++ b/src/fe-common/irc/fe-netjoin.c @@ -245,23 +245,18 @@ static void print_netjoins(NETJOIN_SERVER_REC *server, const char *filter_channe message before it. */ static void sig_print_starting(TEXT_DEST_REC *dest) { - NETJOIN_SERVER_REC *rec; + GSList *tmp, *next; if (printing_joins) return; - if (!IS_IRC_SERVER(dest->server)) - return; - - if (!(dest->level & MSGLEVEL_PUBLIC)) - return; - - if (!server_ischannel(dest->server, dest->target)) - return; + for (tmp = joinservers; tmp != NULL; tmp = next) { + NETJOIN_SERVER_REC *server = tmp->data; - rec = netjoin_find_server(IRC_SERVER(dest->server)); - if (rec != NULL && rec->netjoins != NULL) - print_netjoins(rec, dest->target); + next = tmp->next; + if (server->netjoins != NULL) + print_netjoins(server, NULL); + } } static int sig_check_netjoins(void) diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c index 4c69dd10..edd3fc34 100644 --- a/src/fe-common/irc/fe-netsplit.c +++ b/src/fe-common/irc/fe-netsplit.c @@ -199,7 +199,7 @@ static void temp_split_chan_free(TEMP_SPLIT_CHAN_REC *rec) g_free(rec); } -static void print_splits(IRC_SERVER_REC *server, const char *channel) +static void print_splits(IRC_SERVER_REC *server, const char *filter_channel) { TEMP_SPLIT_REC temp; GSList *servers; @@ -218,7 +218,7 @@ static void print_splits(IRC_SERVER_REC *server, const char *channel) g_hash_table_foreach(server->splits, (GHFunc) get_server_splits, &temp); - print_server_splits(server, &temp, channel); + print_server_splits(server, &temp, filter_channel); g_slist_foreach(temp.channels, (GFunc) temp_split_chan_free, NULL); @@ -247,23 +247,17 @@ static int check_server_splits(IRC_SERVER_REC *server) message before it. */ static void sig_print_starting(TEXT_DEST_REC *dest) { - IRC_SERVER_REC *rec; + GSList *tmp; if (printing_splits) return; - if (!IS_IRC_SERVER(dest->server)) - return; - - if (!(dest->level & MSGLEVEL_PUBLIC)) - return; - - if (!server_ischannel(dest->server, dest->target)) - return; + for (tmp = servers; tmp != NULL; tmp = tmp->next) { + IRC_SERVER_REC *rec = tmp->data; - rec = IRC_SERVER(dest->server); - if (rec->split_servers != NULL) - print_splits(rec, dest->target); + if (IS_IRC_SERVER(rec) && rec->split_servers != NULL) + print_splits(rec, NULL); + } } static int sig_check_splits(void) |