diff --git a/.travis.yml b/.travis.yml index 5c7435fb..3e1b576a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,11 @@ +dist: trusty +sudo: required language: c install: - lsb_release -a - uname -a - sudo apt-get update - - sudo apt-get -y install libssl-dev libexpat1-dev libncursesw5-dev libglib2.0-dev libnotify-dev libcurl3-dev libxss-dev libotr2-dev libgpgme11-dev autoconf-archive expect-dev tcl-dev libtool python-dev + - sudo apt-get -y install libssl-dev libexpat1-dev libncursesw5-dev libglib2.0-dev libnotify-dev libcurl3-dev libxss-dev libotr5-dev libgpgme11-dev autoconf-archive expect-dev tcl-dev libtool python-dev libgtk2.0-dev - git clone git://github.com/boothj5/libmesode.git - cd libmesode - mkdir m4 diff --git a/configure.ac b/configure.ac index 46e7c775..651805cd 100644 --- a/configure.ac +++ b/configure.ac @@ -159,8 +159,8 @@ AS_IF([test "x$ncurses_cv_wget_wch" != xyes], [AC_MSG_ERROR([ncurses does not support wide characters])]) ### Check for other profanity dependencies -PKG_CHECK_MODULES([glib], [glib-2.0 >= 2.26], [], - [AC_MSG_ERROR([glib 2.26 or higher is required for profanity])]) +PKG_CHECK_MODULES([glib], [glib-2.0 >= 2.40], [], + [AC_MSG_ERROR([glib 2.40 or higher is required for profanity])]) PKG_CHECK_MODULES([curl], [libcurl], [], [AC_CHECK_LIB([curl], [main], [], [AC_MSG_ERROR([libcurl is required for profanity])])]) diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index 544719d4..e5ec6f11 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -57,51 +57,51 @@ #include "pgp/gpg.h" #endif -static char* _sub_autocomplete(ProfWin *window, const char *const input); -static char* _notify_autocomplete(ProfWin *window, const char *const input); -static char* _theme_autocomplete(ProfWin *window, const char *const input); -static char* _autoaway_autocomplete(ProfWin *window, const char *const input); -static char* _autoconnect_autocomplete(ProfWin *window, const char *const input); -static char* _account_autocomplete(ProfWin *window, const char *const input); -static char* _who_autocomplete(ProfWin *window, const char *const input); -static char* _roster_autocomplete(ProfWin *window, const char *const input); -static char* _group_autocomplete(ProfWin *window, const char *const input); -static char* _bookmark_autocomplete(ProfWin *window, const char *const input); -static char* _otr_autocomplete(ProfWin *window, const char *const input); -static char* _pgp_autocomplete(ProfWin *window, const char *const input); -static char* _connect_autocomplete(ProfWin *window, const char *const input); -static char* _alias_autocomplete(ProfWin *window, const char *const input); -static char* _join_autocomplete(ProfWin *window, const char *const input); -static char* _log_autocomplete(ProfWin *window, const char *const input); -static char* _form_autocomplete(ProfWin *window, const char *const input); -static char* _form_field_autocomplete(ProfWin *window, const char *const input); -static char* _occupants_autocomplete(ProfWin *window, const char *const input); -static char* _kick_autocomplete(ProfWin *window, const char *const input); -static char* _ban_autocomplete(ProfWin *window, const char *const input); -static char* _affiliation_autocomplete(ProfWin *window, const char *const input); -static char* _role_autocomplete(ProfWin *window, const char *const input); -static char* _resource_autocomplete(ProfWin *window, const char *const input); -static char* _wintitle_autocomplete(ProfWin *window, const char *const input); -static char* _inpblock_autocomplete(ProfWin *window, const char *const input); -static char* _time_autocomplete(ProfWin *window, const char *const input); -static char* _receipts_autocomplete(ProfWin *window, const char *const input); -static char* _help_autocomplete(ProfWin *window, const char *const input); -static char* _wins_autocomplete(ProfWin *window, const char *const input); -static char* _tls_autocomplete(ProfWin *window, const char *const input); -static char* _script_autocomplete(ProfWin *window, const char *const input); -static char* _subject_autocomplete(ProfWin *window, const char *const input); -static char* _console_autocomplete(ProfWin *window, const char *const input); -static char* _win_autocomplete(ProfWin *window, const char *const input); -static char* _close_autocomplete(ProfWin *window, const char *const input); -static char* _plugins_autocomplete(ProfWin *window, const char *const input); -static char* _sendfile_autocomplete(ProfWin *window, const char *const input); -static char* _blocked_autocomplete(ProfWin *window, const char *const input); -static char* _tray_autocomplete(ProfWin *window, const char *const input); -static char* _presence_autocomplete(ProfWin *window, const char *const input); +static char* _sub_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _notify_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _theme_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _autoaway_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _autoconnect_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _account_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _who_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _roster_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _group_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _bookmark_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _otr_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _pgp_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _connect_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _alias_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _join_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _log_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _form_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _form_field_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _occupants_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _kick_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _ban_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _affiliation_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _role_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _resource_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _wintitle_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _inpblock_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _time_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _receipts_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _help_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _wins_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _tls_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _script_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _subject_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _console_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _win_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _close_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _plugins_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _sendfile_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _blocked_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _tray_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _presence_autocomplete(ProfWin *window, const char *const input, gboolean previous); -static char* _script_autocomplete_func(const char *const prefix); +static char* _script_autocomplete_func(const char *const prefix, gboolean previous); -static char* _cmd_ac_complete_params(ProfWin *window, const char *const input); +static char* _cmd_ac_complete_params(ProfWin *window, const char *const input, gboolean previous); static Autocomplete commands_ac; static Autocomplete who_room_ac; @@ -204,6 +204,8 @@ cmd_ac_init(void) help_ac = autocomplete_new(); autocomplete_add(help_ac, "commands"); autocomplete_add(help_ac, "navigation"); + autocomplete_add(help_ac, "search_all"); + autocomplete_add(help_ac, "search_any"); help_commands_ac = autocomplete_new(); autocomplete_add(help_commands_ac, "chat"); @@ -842,16 +844,16 @@ cmd_ac_add_form_fields(DataForm *form) return; } - GSList *fields = autocomplete_create_list(form->tag_ac); - GSList *curr_field = fields; + GList *fields = autocomplete_create_list(form->tag_ac); + GList *curr_field = fields; while (curr_field) { GString *field_str = g_string_new("/"); g_string_append(field_str, curr_field->data); cmd_ac_add(field_str->str); g_string_free(field_str, TRUE); - curr_field = g_slist_next(curr_field); + curr_field = g_list_next(curr_field); } - g_slist_free_full(fields, free); + g_list_free_full(fields, free); } void @@ -861,32 +863,32 @@ cmd_ac_remove_form_fields(DataForm *form) return; } - GSList *fields = autocomplete_create_list(form->tag_ac); - GSList *curr_field = fields; + GList *fields = autocomplete_create_list(form->tag_ac); + GList *curr_field = fields; while (curr_field) { GString *field_str = g_string_new("/"); g_string_append(field_str, curr_field->data); cmd_ac_remove(field_str->str); g_string_free(field_str, TRUE); - curr_field = g_slist_next(curr_field); + curr_field = g_list_next(curr_field); } - g_slist_free_full(fields, free); + g_list_free_full(fields, free); } char* -cmd_ac_complete(ProfWin *window, const char *const input) +cmd_ac_complete(ProfWin *window, const char *const input, gboolean previous) { // autocomplete command if ((strncmp(input, "/", 1) == 0) && (!str_contains(input, strlen(input), ' '))) { char *found = NULL; - found = autocomplete_complete(commands_ac, input, TRUE); + found = autocomplete_complete(commands_ac, input, TRUE, previous); if (found) { return found; } // autocomplete parameters } else { - char *found = _cmd_ac_complete_params(window, input); + char *found = _cmd_ac_complete_params(window, input, previous); if (found) { return found; } @@ -1149,7 +1151,7 @@ cmd_ac_uninit(void) } char* -cmd_ac_complete_filepath(const char *const input, char *const startstr) +cmd_ac_complete_filepath(const char *const input, char *const startstr, gboolean previous) { static char* last_directory = NULL; @@ -1247,7 +1249,7 @@ cmd_ac_complete_filepath(const char *const input, char *const startstr) } free(foofile); - result = autocomplete_param_with_ac(input, startstr, filepath_ac, TRUE); + result = autocomplete_param_with_ac(input, startstr, filepath_ac, TRUE, previous); if (result) { return result; } @@ -1256,7 +1258,7 @@ cmd_ac_complete_filepath(const char *const input, char *const startstr) } static char* -_cmd_ac_complete_params(ProfWin *window, const char *const input) +_cmd_ac_complete_params(ProfWin *window, const char *const input, gboolean previous) { int i; char *result = NULL; @@ -1269,7 +1271,7 @@ _cmd_ac_complete_params(ProfWin *window, const char *const input) "/lastactivity" }; for (i = 0; i < ARRAY_SIZE(boolean_choices); i++) { - result = autocomplete_param_with_func(input, boolean_choices[i], prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, boolean_choices[i], prefs_autocomplete_boolean_choice, previous); if (result) { return result; } @@ -1286,7 +1288,7 @@ _cmd_ac_complete_params(ProfWin *window, const char *const input) // Remove quote character before and after names when doing autocomplete char *unquoted = strip_arg_quotes(input); for (i = 0; i < ARRAY_SIZE(nick_choices); i++) { - result = autocomplete_param_with_ac(unquoted, nick_choices[i], nick_ac, TRUE); + result = autocomplete_param_with_ac(unquoted, nick_choices[i], nick_ac, TRUE, previous); if (result) { free(unquoted); return result; @@ -1301,7 +1303,7 @@ _cmd_ac_complete_params(ProfWin *window, const char *const input) // Remove quote character before and after names when doing autocomplete char *unquoted = strip_arg_quotes(input); for (i = 0; i < ARRAY_SIZE(contact_choices); i++) { - result = autocomplete_param_with_func(unquoted, contact_choices[i], roster_contact_autocomplete); + result = autocomplete_param_with_func(unquoted, contact_choices[i], roster_contact_autocomplete, previous); if (result) { free(unquoted); return result; @@ -1311,7 +1313,7 @@ _cmd_ac_complete_params(ProfWin *window, const char *const input) gchar *resource_choices[] = { "/caps", "/software", "/ping" }; for (i = 0; i < ARRAY_SIZE(resource_choices); i++) { - result = autocomplete_param_with_func(input, resource_choices[i], roster_fulljid_autocomplete); + result = autocomplete_param_with_func(input, resource_choices[i], roster_fulljid_autocomplete, previous); if (result) { return result; } @@ -1319,7 +1321,7 @@ _cmd_ac_complete_params(ProfWin *window, const char *const input) } if (conn_status == JABBER_CONNECTED) { - result = autocomplete_param_with_func(input, "/invite", roster_contact_autocomplete); + result = autocomplete_param_with_func(input, "/invite", roster_contact_autocomplete, previous); if (result) { return result; } @@ -1327,7 +1329,7 @@ _cmd_ac_complete_params(ProfWin *window, const char *const input) gchar *invite_choices[] = { "/decline", "/join" }; for (i = 0; i < ARRAY_SIZE(invite_choices); i++) { - result = autocomplete_param_with_func(input, invite_choices[i], muc_invites_find); + result = autocomplete_param_with_func(input, invite_choices[i], muc_invites_find, previous); if (result) { return result; } @@ -1337,7 +1339,7 @@ _cmd_ac_complete_params(ProfWin *window, const char *const input) Autocomplete completers[] = { prefs_ac, disco_ac, room_ac, autoping_ac, winpos_ac, winpos_ac, winpos_ac, winpos_ac }; for (i = 0; i < ARRAY_SIZE(cmds); i++) { - result = autocomplete_param_with_ac(input, cmds[i], completers[i], TRUE); + result = autocomplete_param_with_ac(input, cmds[i], completers[i], TRUE, previous); if (result) { return result; } @@ -1398,9 +1400,9 @@ _cmd_ac_complete_params(ProfWin *window, const char *const input) } parsed[i] = '\0'; - char * (*ac_func)(ProfWin*, const char * const) = g_hash_table_lookup(ac_funcs, parsed); + char * (*ac_func)(ProfWin*, const char * const, gboolean) = g_hash_table_lookup(ac_funcs, parsed); if (ac_func) { - result = ac_func(window, input); + result = ac_func(window, input, previous); if (result) { g_hash_table_destroy(ac_funcs); return result; @@ -1408,13 +1410,13 @@ _cmd_ac_complete_params(ProfWin *window, const char *const input) } g_hash_table_destroy(ac_funcs); - result = plugins_autocomplete(input); + result = plugins_autocomplete(input, previous); if (result) { return result; } if (g_str_has_prefix(input, "/field")) { - result = _form_field_autocomplete(window, input); + result = _form_field_autocomplete(window, input, previous); if (result) { return result; } @@ -1424,18 +1426,18 @@ _cmd_ac_complete_params(ProfWin *window, const char *const input) } static char* -_sub_autocomplete(ProfWin *window, const char *const input) +_sub_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_func(input, "/sub allow", presence_sub_request_find); + result = autocomplete_param_with_func(input, "/sub allow", presence_sub_request_find, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/sub deny", presence_sub_request_find); + result = autocomplete_param_with_func(input, "/sub deny", presence_sub_request_find, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/sub", sub_ac, TRUE); + result = autocomplete_param_with_ac(input, "/sub", sub_ac, TRUE, previous); if (result) { return result; } @@ -1444,15 +1446,15 @@ _sub_autocomplete(ProfWin *window, const char *const input) } static char* -_tray_autocomplete(ProfWin *window, const char *const input) +_tray_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_func(input, "/tray read", prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, "/tray read", prefs_autocomplete_boolean_choice, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/tray", tray_ac, FALSE); + result = autocomplete_param_with_ac(input, "/tray", tray_ac, FALSE, previous); if (result) { return result; } @@ -1461,12 +1463,12 @@ _tray_autocomplete(ProfWin *window, const char *const input) } static char* -_who_autocomplete(ProfWin *window, const char *const input) +_who_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; if (window->type == WIN_MUC) { - result = autocomplete_param_with_ac(input, "/who", who_room_ac, TRUE); + result = autocomplete_param_with_ac(input, "/who", who_room_ac, TRUE, previous); if (result) { return result; } @@ -1479,14 +1481,14 @@ _who_autocomplete(ProfWin *window, const char *const input) "/who unavailable" }; for (i = 0; i < ARRAY_SIZE(group_commands); i++) { - result = autocomplete_param_with_func(input, group_commands[i], roster_group_autocomplete); + result = autocomplete_param_with_func(input, group_commands[i], roster_group_autocomplete, previous); if (result) { return result; } } } - result = autocomplete_param_with_ac(input, "/who", who_roster_ac, TRUE); + result = autocomplete_param_with_ac(input, "/who", who_roster_ac, TRUE, previous); if (result) { return result; } @@ -1496,135 +1498,135 @@ _who_autocomplete(ProfWin *window, const char *const input) } static char* -_roster_autocomplete(ProfWin *window, const char *const input) +_roster_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_ac(input, "/roster room private char", roster_char_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster room private char", roster_char_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster room private", roster_header_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster room private", roster_header_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster header char", roster_char_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster header char", roster_char_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster contact char", roster_char_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster contact char", roster_char_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster room char", roster_char_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster room char", roster_char_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster private char", roster_char_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster private char", roster_char_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster resource char", roster_char_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster resource char", roster_char_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/roster resource join", prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, "/roster resource join", prefs_autocomplete_boolean_choice, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster room position", roster_room_position_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster room position", roster_room_position_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster room by", roster_room_by_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster room by", roster_room_by_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster room order", roster_room_order_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster room order", roster_room_order_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster room unread", roster_unread_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster room unread", roster_unread_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/roster count zero", prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, "/roster count zero", prefs_autocomplete_boolean_choice, previous); if (result) { return result; } jabber_conn_status_t conn_status = connection_get_status(); if (conn_status == JABBER_CONNECTED) { - result = autocomplete_param_with_func(input, "/roster nick", roster_barejid_autocomplete); + result = autocomplete_param_with_func(input, "/roster nick", roster_barejid_autocomplete, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/roster clearnick", roster_barejid_autocomplete); + result = autocomplete_param_with_func(input, "/roster clearnick", roster_barejid_autocomplete, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/roster remove", roster_barejid_autocomplete); + result = autocomplete_param_with_func(input, "/roster remove", roster_barejid_autocomplete, previous); if (result) { return result; } } - result = autocomplete_param_with_ac(input, "/roster remove_all", roster_remove_all_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster remove_all", roster_remove_all_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster show", roster_show_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster show", roster_show_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster hide", roster_show_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster hide", roster_show_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster by", roster_by_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster by", roster_by_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster count", roster_count_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster count", roster_count_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster order", roster_order_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster order", roster_order_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster unread", roster_unread_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster unread", roster_unread_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster room", roster_room_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster room", roster_room_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/roster wrap", prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, "/roster wrap", prefs_autocomplete_boolean_choice, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster header", roster_header_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster header", roster_header_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster contact", roster_contact_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster contact", roster_contact_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster resource", roster_resource_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster resource", roster_resource_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster presence", roster_presence_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster presence", roster_presence_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster private", roster_private_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster private", roster_private_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/roster", roster_ac, TRUE); + result = autocomplete_param_with_ac(input, "/roster", roster_ac, TRUE, previous); if (result) { return result; } @@ -1633,36 +1635,36 @@ _roster_autocomplete(ProfWin *window, const char *const input) } static char* -_group_autocomplete(ProfWin *window, const char *const input) +_group_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; jabber_conn_status_t conn_status = connection_get_status(); if (conn_status == JABBER_CONNECTED) { - result = autocomplete_param_with_func(input, "/group show", roster_group_autocomplete); + result = autocomplete_param_with_func(input, "/group show", roster_group_autocomplete, previous); if (result) { return result; } - result = autocomplete_param_no_with_func(input, "/group add", 4, roster_contact_autocomplete); + result = autocomplete_param_no_with_func(input, "/group add", 4, roster_contact_autocomplete, previous); if (result) { return result; } - result = autocomplete_param_no_with_func(input, "/group remove", 4, roster_contact_autocomplete); + result = autocomplete_param_no_with_func(input, "/group remove", 4, roster_contact_autocomplete, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/group add", roster_group_autocomplete); + result = autocomplete_param_with_func(input, "/group add", roster_group_autocomplete, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/group remove", roster_group_autocomplete); + result = autocomplete_param_with_func(input, "/group remove", roster_group_autocomplete, previous); if (result) { return result; } } - result = autocomplete_param_with_ac(input, "/group", group_ac, TRUE); + result = autocomplete_param_with_ac(input, "/group", group_ac, TRUE, previous); if (result) { return result; } @@ -1671,16 +1673,16 @@ _group_autocomplete(ProfWin *window, const char *const input) } static char* -_blocked_autocomplete(ProfWin *window, const char *const input) +_blocked_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_func(input, "/blocked remove", blocked_ac_find); + result = autocomplete_param_with_func(input, "/blocked remove", blocked_ac_find, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/blocked", blocked_ac, FALSE); + result = autocomplete_param_with_ac(input, "/blocked", blocked_ac, FALSE, previous); if (result) { return result; } @@ -1689,7 +1691,7 @@ _blocked_autocomplete(ProfWin *window, const char *const input) } static char* -_bookmark_autocomplete(ProfWin *window, const char *const input) +_bookmark_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; @@ -1702,7 +1704,7 @@ _bookmark_autocomplete(ProfWin *window, const char *const input) if ((num_args == 2 && space_at_end) || (num_args == 3 && !space_at_end)) { GString *beginning = g_string_new("/bookmark"); g_string_append_printf(beginning, " %s %s", args[0], args[1]); - found = autocomplete_param_with_ac(input, beginning->str, bookmark_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, bookmark_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -1713,7 +1715,7 @@ _bookmark_autocomplete(ProfWin *window, const char *const input) || (num_args == 4 && (g_strcmp0(args[2], "autojoin") == 0) && !space_at_end)) { GString *beginning = g_string_new("/bookmark"); g_string_append_printf(beginning, " %s %s %s", args[0], args[1], args[2]); - found = autocomplete_param_with_func(input, beginning->str, prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_func(input, beginning->str, prefs_autocomplete_boolean_choice, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -1723,7 +1725,7 @@ _bookmark_autocomplete(ProfWin *window, const char *const input) if ((num_args == 4 && space_at_end) || (num_args == 5 && !space_at_end)) { GString *beginning = g_string_new("/bookmark"); g_string_append_printf(beginning, " %s %s %s %s", args[0], args[1], args[2], args[3]); - found = autocomplete_param_with_ac(input, beginning->str, bookmark_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, bookmark_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -1734,7 +1736,7 @@ _bookmark_autocomplete(ProfWin *window, const char *const input) || (num_args == 6 && (g_strcmp0(args[4], "autojoin") == 0) && !space_at_end)) { GString *beginning = g_string_new("/bookmark"); g_string_append_printf(beginning, " %s %s %s %s %s", args[0], args[1], args[2], args[3], args[4]); - found = autocomplete_param_with_func(input, beginning->str, prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_func(input, beginning->str, prefs_autocomplete_boolean_choice, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -1744,7 +1746,7 @@ _bookmark_autocomplete(ProfWin *window, const char *const input) if ((num_args == 6 && space_at_end) || (num_args == 7 && !space_at_end)) { GString *beginning = g_string_new("/bookmark"); g_string_append_printf(beginning, " %s %s %s %s %s %s", args[0], args[1], args[2], args[3], args[4], args[5]); - found = autocomplete_param_with_ac(input, beginning->str, bookmark_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, bookmark_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -1755,7 +1757,7 @@ _bookmark_autocomplete(ProfWin *window, const char *const input) || (num_args == 8 && (g_strcmp0(args[6], "autojoin") == 0) && !space_at_end)) { GString *beginning = g_string_new("/bookmark"); g_string_append_printf(beginning, " %s %s %s %s %s %s %s", args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - found = autocomplete_param_with_func(input, beginning->str, prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_func(input, beginning->str, prefs_autocomplete_boolean_choice, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -1766,34 +1768,34 @@ _bookmark_autocomplete(ProfWin *window, const char *const input) g_strfreev(args); - found = autocomplete_param_with_func(input, "/bookmark remove", bookmark_find); + found = autocomplete_param_with_func(input, "/bookmark remove", bookmark_find, previous); if (found) { return found; } - found = autocomplete_param_with_func(input, "/bookmark join", bookmark_find); + found = autocomplete_param_with_func(input, "/bookmark join", bookmark_find, previous); if (found) { return found; } - found = autocomplete_param_with_func(input, "/bookmark update", bookmark_find); + found = autocomplete_param_with_func(input, "/bookmark update", bookmark_find, previous); if (found) { return found; } - found = autocomplete_param_with_func(input, "/bookmark invites", prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_func(input, "/bookmark invites", prefs_autocomplete_boolean_choice, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/bookmark", bookmark_ac, TRUE); + found = autocomplete_param_with_ac(input, "/bookmark", bookmark_ac, TRUE, previous); return found; } static char* -_notify_autocomplete(ProfWin *window, const char *const input) +_notify_autocomplete(ProfWin *window, const char *const input, gboolean previous) { int i = 0; char *result = NULL; - result = autocomplete_param_with_func(input, "/notify room trigger remove", prefs_autocomplete_room_trigger); + result = autocomplete_param_with_func(input, "/notify room trigger remove", prefs_autocomplete_room_trigger, previous); if (result) { return result; } @@ -1801,46 +1803,46 @@ _notify_autocomplete(ProfWin *window, const char *const input) gchar *boolean_choices1[] = { "/notify room current", "/notify chat current", "/notify typing current", "/notify room text", "/notify chat text" }; for (i = 0; i < ARRAY_SIZE(boolean_choices1); i++) { - result = autocomplete_param_with_func(input, boolean_choices1[i], prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, boolean_choices1[i], prefs_autocomplete_boolean_choice, previous); if (result) { return result; } } - result = autocomplete_param_with_ac(input, "/notify room mention", notify_mention_ac, TRUE); + result = autocomplete_param_with_ac(input, "/notify room mention", notify_mention_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/notify room trigger", notify_trigger_ac, TRUE); + result = autocomplete_param_with_ac(input, "/notify room trigger", notify_trigger_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/notify room", notify_room_ac, TRUE); + result = autocomplete_param_with_ac(input, "/notify room", notify_room_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/notify chat", notify_chat_ac, TRUE); + result = autocomplete_param_with_ac(input, "/notify chat", notify_chat_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/notify typing", notify_typing_ac, TRUE); + result = autocomplete_param_with_ac(input, "/notify typing", notify_typing_ac, TRUE, previous); if (result) { return result; } gchar *boolean_choices2[] = { "/notify invite", "/notify sub", "/notify mention", "/notify trigger"}; for (i = 0; i < ARRAY_SIZE(boolean_choices2); i++) { - result = autocomplete_param_with_func(input, boolean_choices2[i], prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, boolean_choices2[i], prefs_autocomplete_boolean_choice, previous); if (result) { return result; } } - result = autocomplete_param_with_ac(input, "/notify", notify_ac, TRUE); + result = autocomplete_param_with_ac(input, "/notify", notify_ac, TRUE, previous); if (result) { return result; } @@ -1849,30 +1851,30 @@ _notify_autocomplete(ProfWin *window, const char *const input) } static char* -_autoaway_autocomplete(ProfWin *window, const char *const input) +_autoaway_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_ac(input, "/autoaway mode", autoaway_mode_ac, TRUE); + result = autocomplete_param_with_ac(input, "/autoaway mode", autoaway_mode_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/autoaway time", autoaway_presence_ac, TRUE); + result = autocomplete_param_with_ac(input, "/autoaway time", autoaway_presence_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/autoaway message", autoaway_presence_ac, TRUE); + result = autocomplete_param_with_ac(input, "/autoaway message", autoaway_presence_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/autoaway check", prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, "/autoaway check", prefs_autocomplete_boolean_choice, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/autoaway", autoaway_ac, TRUE); + result = autocomplete_param_with_ac(input, "/autoaway", autoaway_ac, TRUE, previous); if (result) { return result; } @@ -1881,19 +1883,19 @@ _autoaway_autocomplete(ProfWin *window, const char *const input) } static char* -_log_autocomplete(ProfWin *window, const char *const input) +_log_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_func(input, "/log rotate", prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, "/log rotate", prefs_autocomplete_boolean_choice, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/log shared", prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, "/log shared", prefs_autocomplete_boolean_choice, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/log", log_ac, TRUE); + result = autocomplete_param_with_ac(input, "/log", log_ac, TRUE, previous); if (result) { return result; } @@ -1902,16 +1904,16 @@ _log_autocomplete(ProfWin *window, const char *const input) } static char* -_autoconnect_autocomplete(ProfWin *window, const char *const input) +_autoconnect_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_func(input, "/autoconnect set", accounts_find_enabled); + result = autocomplete_param_with_func(input, "/autoconnect set", accounts_find_enabled, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/autoconnect", autoconnect_ac, TRUE); + result = autocomplete_param_with_ac(input, "/autoconnect", autoconnect_ac, TRUE, previous); if (result) { return result; } @@ -1920,20 +1922,20 @@ _autoconnect_autocomplete(ProfWin *window, const char *const input) } static char* -_otr_autocomplete(ProfWin *window, const char *const input) +_otr_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; jabber_conn_status_t conn_status = connection_get_status(); if (conn_status == JABBER_CONNECTED) { - found = autocomplete_param_with_func(input, "/otr start", roster_contact_autocomplete); + found = autocomplete_param_with_func(input, "/otr start", roster_contact_autocomplete, previous); if (found) { return found; } } - found = autocomplete_param_with_ac(input, "/otr log", otr_log_ac, TRUE); + found = autocomplete_param_with_ac(input, "/otr log", otr_log_ac, TRUE, previous); if (found) { return found; } @@ -1950,7 +1952,7 @@ _otr_autocomplete(ProfWin *window, const char *const input) g_string_append(beginning, args[1]); } - found = autocomplete_param_with_func(input, beginning->str, roster_contact_autocomplete); + found = autocomplete_param_with_func(input, beginning->str, roster_contact_autocomplete, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -1960,12 +1962,12 @@ _otr_autocomplete(ProfWin *window, const char *const input) g_strfreev(args); } - found = autocomplete_param_with_ac(input, "/otr policy", otr_policy_ac, TRUE); + found = autocomplete_param_with_ac(input, "/otr policy", otr_policy_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/otr", otr_ac, TRUE); + found = autocomplete_param_with_ac(input, "/otr", otr_ac, TRUE, previous); if (found) { return found; } @@ -1974,20 +1976,20 @@ _otr_autocomplete(ProfWin *window, const char *const input) } static char* -_pgp_autocomplete(ProfWin *window, const char *const input) +_pgp_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; jabber_conn_status_t conn_status = connection_get_status(); if (conn_status == JABBER_CONNECTED) { - found = autocomplete_param_with_func(input, "/pgp start", roster_contact_autocomplete); + found = autocomplete_param_with_func(input, "/pgp start", roster_contact_autocomplete, previous); if (found) { return found; } } - found = autocomplete_param_with_ac(input, "/pgp log", pgp_log_ac, TRUE); + found = autocomplete_param_with_ac(input, "/pgp log", pgp_log_ac, TRUE, previous); if (found) { return found; } @@ -2002,7 +2004,7 @@ _pgp_autocomplete(ProfWin *window, const char *const input) g_string_append(beginning, " "); g_string_append(beginning, args[1]); } - found = autocomplete_param_with_func(input, beginning->str, p_gpg_autocomplete_key); + found = autocomplete_param_with_func(input, beginning->str, p_gpg_autocomplete_key, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2013,13 +2015,13 @@ _pgp_autocomplete(ProfWin *window, const char *const input) #endif if (conn_status == JABBER_CONNECTED) { - found = autocomplete_param_with_func(input, "/pgp setkey", roster_barejid_autocomplete); + found = autocomplete_param_with_func(input, "/pgp setkey", roster_barejid_autocomplete, previous); if (found) { return found; } } - found = autocomplete_param_with_ac(input, "/pgp", pgp_ac, TRUE); + found = autocomplete_param_with_ac(input, "/pgp", pgp_ac, TRUE, previous); if (found) { return found; } @@ -2028,20 +2030,20 @@ _pgp_autocomplete(ProfWin *window, const char *const input) } static char* -_plugins_autocomplete(ProfWin *window, const char *const input) +_plugins_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; if (strncmp(input, "/plugins sourcepath set ", 24) == 0) { - return cmd_ac_complete_filepath(input, "/plugins sourcepath set"); + return cmd_ac_complete_filepath(input, "/plugins sourcepath set", previous); } if (strncmp(input, "/plugins install ", 17) == 0) { - return cmd_ac_complete_filepath(input, "/plugins install"); + return cmd_ac_complete_filepath(input, "/plugins install", previous); } if (strncmp(input, "/plugins sourcepath ", 20) == 0) { - result = autocomplete_param_with_ac(input, "/plugins sourcepath", plugins_sourcepath_ac, TRUE); + result = autocomplete_param_with_ac(input, "/plugins sourcepath", plugins_sourcepath_ac, TRUE, previous); if (result) { return result; } @@ -2058,7 +2060,7 @@ _plugins_autocomplete(ProfWin *window, const char *const input) } g_slist_free_full(plugins, g_free); } - result = autocomplete_param_with_ac(input, "/plugins load", plugins_load_ac, TRUE); + result = autocomplete_param_with_ac(input, "/plugins load", plugins_load_ac, TRUE, previous); if (result) { return result; } @@ -2075,7 +2077,7 @@ _plugins_autocomplete(ProfWin *window, const char *const input) } g_list_free(plugins); } - result = autocomplete_param_with_ac(input, "/plugins reload", plugins_reload_ac, TRUE); + result = autocomplete_param_with_ac(input, "/plugins reload", plugins_reload_ac, TRUE, previous); if (result) { return result; } @@ -2092,13 +2094,13 @@ _plugins_autocomplete(ProfWin *window, const char *const input) } g_list_free(plugins); } - result = autocomplete_param_with_ac(input, "/plugins unload", plugins_unload_ac, TRUE); + result = autocomplete_param_with_ac(input, "/plugins unload", plugins_unload_ac, TRUE, previous); if (result) { return result; } } - result = autocomplete_param_with_ac(input, "/plugins", plugins_ac, TRUE); + result = autocomplete_param_with_ac(input, "/plugins", plugins_ac, TRUE, previous); if (result) { return result; } @@ -2107,7 +2109,7 @@ _plugins_autocomplete(ProfWin *window, const char *const input) } static char* -_theme_autocomplete(ProfWin *window, const char *const input) +_theme_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; if (strncmp(input, "/theme load ", 12) == 0) { @@ -2122,12 +2124,12 @@ _theme_autocomplete(ProfWin *window, const char *const input) g_slist_free_full(themes, g_free); autocomplete_add(theme_load_ac, "default"); } - result = autocomplete_param_with_ac(input, "/theme load", theme_load_ac, TRUE); + result = autocomplete_param_with_ac(input, "/theme load", theme_load_ac, TRUE, previous); if (result) { return result; } } - result = autocomplete_param_with_ac(input, "/theme", theme_ac, TRUE); + result = autocomplete_param_with_ac(input, "/theme", theme_ac, TRUE, previous); if (result) { return result; } @@ -2136,7 +2138,7 @@ _theme_autocomplete(ProfWin *window, const char *const input) } static char* -_script_autocomplete_func(const char *const prefix) +_script_autocomplete_func(const char *const prefix, gboolean previous) { if (script_show_ac == NULL) { script_show_ac = autocomplete_new(); @@ -2149,29 +2151,29 @@ _script_autocomplete_func(const char *const prefix) g_slist_free_full(scripts, g_free); } - return autocomplete_complete(script_show_ac, prefix, FALSE); + return autocomplete_complete(script_show_ac, prefix, FALSE, previous); } static char* -_script_autocomplete(ProfWin *window, const char *const input) +_script_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; if (strncmp(input, "/script show ", 13) == 0) { - result = autocomplete_param_with_func(input, "/script show", _script_autocomplete_func); + result = autocomplete_param_with_func(input, "/script show", _script_autocomplete_func, previous); if (result) { return result; } } if (strncmp(input, "/script run ", 12) == 0) { - result = autocomplete_param_with_func(input, "/script run", _script_autocomplete_func); + result = autocomplete_param_with_func(input, "/script run", _script_autocomplete_func, previous); if (result) { return result; } } - result = autocomplete_param_with_ac(input, "/script", script_ac, TRUE); + result = autocomplete_param_with_ac(input, "/script", script_ac, TRUE, previous); if (result) { return result; } @@ -2180,7 +2182,7 @@ _script_autocomplete(ProfWin *window, const char *const input) } static char* -_resource_autocomplete(ProfWin *window, const char *const input) +_resource_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; @@ -2191,24 +2193,24 @@ _resource_autocomplete(ProfWin *window, const char *const input) PContact contact = roster_get_contact(chatwin->barejid); if (contact) { Autocomplete ac = p_contact_resource_ac(contact); - found = autocomplete_param_with_ac(input, "/resource set", ac, FALSE); + found = autocomplete_param_with_ac(input, "/resource set", ac, FALSE, previous); if (found) { return found; } } } - found = autocomplete_param_with_func(input, "/resource title", prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_func(input, "/resource title", prefs_autocomplete_boolean_choice, previous); if (found) { return found; } - found = autocomplete_param_with_func(input, "/resource message", prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_func(input, "/resource message", prefs_autocomplete_boolean_choice, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/resource", resource_ac, FALSE); + found = autocomplete_param_with_ac(input, "/resource", resource_ac, FALSE, previous); if (found) { return found; } @@ -2217,21 +2219,21 @@ _resource_autocomplete(ProfWin *window, const char *const input) } static char* -_wintitle_autocomplete(ProfWin *window, const char *const input) +_wintitle_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; - found = autocomplete_param_with_func(input, "/wintitle show", prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_func(input, "/wintitle show", prefs_autocomplete_boolean_choice, previous); if (found) { return found; } - found = autocomplete_param_with_func(input, "/wintitle goodbye", prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_func(input, "/wintitle goodbye", prefs_autocomplete_boolean_choice, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/wintitle", wintitle_ac, FALSE); + found = autocomplete_param_with_ac(input, "/wintitle", wintitle_ac, FALSE, previous); if (found) { return found; } @@ -2240,16 +2242,16 @@ _wintitle_autocomplete(ProfWin *window, const char *const input) } static char* -_inpblock_autocomplete(ProfWin *window, const char *const input) +_inpblock_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; - found = autocomplete_param_with_func(input, "/inpblock dynamic", prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_func(input, "/inpblock dynamic", prefs_autocomplete_boolean_choice, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/inpblock", inpblock_ac, FALSE); + found = autocomplete_param_with_ac(input, "/inpblock", inpblock_ac, FALSE, previous); if (found) { return found; } @@ -2258,7 +2260,7 @@ _inpblock_autocomplete(ProfWin *window, const char *const input) } static char* -_form_autocomplete(ProfWin *window, const char *const input) +_form_autocomplete(ProfWin *window, const char *const input, gboolean previous) { if (window->type != WIN_MUC_CONFIG) { return NULL; @@ -2269,13 +2271,13 @@ _form_autocomplete(ProfWin *window, const char *const input) ProfMucConfWin *confwin = (ProfMucConfWin*)window; DataForm *form = confwin->form; if (form) { - found = autocomplete_param_with_ac(input, "/form help", form->tag_ac, TRUE); + found = autocomplete_param_with_ac(input, "/form help", form->tag_ac, TRUE, previous); if (found) { return found; } } - found = autocomplete_param_with_ac(input, "/form", form_ac, TRUE); + found = autocomplete_param_with_ac(input, "/form", form_ac, TRUE, previous); if (found) { return found; } @@ -2284,7 +2286,7 @@ _form_autocomplete(ProfWin *window, const char *const input) } static char* -_form_field_autocomplete(ProfWin *window, const char *const input) +_form_field_autocomplete(ProfWin *window, const char *const input, gboolean previous) { if (window->type != WIN_MUC_CONFIG) { return NULL; @@ -2311,13 +2313,13 @@ _form_field_autocomplete(ProfWin *window, const char *const input) if (((g_strcmp0(split[1], "add") == 0) || (g_strcmp0(split[1], "remove") == 0)) && field_type == FIELD_LIST_MULTI) { - found = autocomplete_param_with_ac(input, beginning->str, value_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, value_ac, TRUE, previous); } else if ((g_strcmp0(split[1], "remove") == 0) && field_type == FIELD_TEXT_MULTI) { - found = autocomplete_param_with_ac(input, beginning->str, value_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, value_ac, TRUE, previous); } else if ((g_strcmp0(split[1], "remove") == 0) && field_type == FIELD_JID_MULTI) { - found = autocomplete_param_with_ac(input, beginning->str, value_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, value_ac, TRUE, previous); } g_string_free(beginning, TRUE); @@ -2332,15 +2334,15 @@ _form_field_autocomplete(ProfWin *window, const char *const input) switch (field_type) { case FIELD_BOOLEAN: - found = autocomplete_param_with_func(input, split[0], prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_func(input, split[0], prefs_autocomplete_boolean_choice, previous); break; case FIELD_LIST_SINGLE: - found = autocomplete_param_with_ac(input, split[0], value_ac, TRUE); + found = autocomplete_param_with_ac(input, split[0], value_ac, TRUE, previous); break; case FIELD_LIST_MULTI: case FIELD_JID_MULTI: case FIELD_TEXT_MULTI: - found = autocomplete_param_with_ac(input, split[0], form_field_multi_ac, TRUE); + found = autocomplete_param_with_ac(input, split[0], form_field_multi_ac, TRUE, previous); break; default: break; @@ -2354,36 +2356,36 @@ _form_field_autocomplete(ProfWin *window, const char *const input) } static char* -_occupants_autocomplete(ProfWin *window, const char *const input) +_occupants_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; - found = autocomplete_param_with_ac(input, "/occupants default show", occupants_show_ac, TRUE); + found = autocomplete_param_with_ac(input, "/occupants default show", occupants_show_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/occupants default hide", occupants_show_ac, TRUE); + found = autocomplete_param_with_ac(input, "/occupants default hide", occupants_show_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/occupants default", occupants_default_ac, TRUE); + found = autocomplete_param_with_ac(input, "/occupants default", occupants_default_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/occupants show", occupants_show_ac, TRUE); + found = autocomplete_param_with_ac(input, "/occupants show", occupants_show_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/occupants hide", occupants_show_ac, TRUE); + found = autocomplete_param_with_ac(input, "/occupants hide", occupants_show_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/occupants", occupants_ac, TRUE); + found = autocomplete_param_with_ac(input, "/occupants", occupants_ac, TRUE, previous); if (found) { return found; } @@ -2392,51 +2394,51 @@ _occupants_autocomplete(ProfWin *window, const char *const input) } static char* -_time_autocomplete(ProfWin *window, const char *const input) +_time_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; - found = autocomplete_param_with_ac(input, "/time statusbar", time_format_ac, TRUE); + found = autocomplete_param_with_ac(input, "/time statusbar", time_format_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/time lastactivity", time_format_ac, TRUE); + found = autocomplete_param_with_ac(input, "/time lastactivity", time_format_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/time console", time_format_ac, TRUE); + found = autocomplete_param_with_ac(input, "/time console", time_format_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/time chat", time_format_ac, TRUE); + found = autocomplete_param_with_ac(input, "/time chat", time_format_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/time muc", time_format_ac, TRUE); + found = autocomplete_param_with_ac(input, "/time muc", time_format_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/time mucconfig", time_format_ac, TRUE); + found = autocomplete_param_with_ac(input, "/time mucconfig", time_format_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/time private", time_format_ac, TRUE); + found = autocomplete_param_with_ac(input, "/time private", time_format_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/time xml", time_format_ac, TRUE); + found = autocomplete_param_with_ac(input, "/time xml", time_format_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/time", time_ac, TRUE); + found = autocomplete_param_with_ac(input, "/time", time_ac, TRUE, previous); if (found) { return found; } @@ -2445,7 +2447,7 @@ _time_autocomplete(ProfWin *window, const char *const input) } static char* -_kick_autocomplete(ProfWin *window, const char *const input) +_kick_autocomplete(ProfWin *window, const char *const input, gboolean previous) { if (window->type != WIN_MUC) { return NULL; @@ -2458,13 +2460,13 @@ _kick_autocomplete(ProfWin *window, const char *const input) return NULL; } - char *result = autocomplete_param_with_ac(input, "/kick", nick_ac, TRUE); + char *result = autocomplete_param_with_ac(input, "/kick", nick_ac, TRUE, previous); return result; } static char* -_ban_autocomplete(ProfWin *window, const char *const input) +_ban_autocomplete(ProfWin *window, const char *const input, gboolean previous) { if (window->type != WIN_MUC) { return NULL; @@ -2477,13 +2479,13 @@ _ban_autocomplete(ProfWin *window, const char *const input) return NULL; } - char *result = autocomplete_param_with_ac(input, "/ban", jid_ac, TRUE); + char *result = autocomplete_param_with_ac(input, "/ban", jid_ac, TRUE, previous); return result; } static char* -_affiliation_autocomplete(ProfWin *window, const char *const input) +_affiliation_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; @@ -2503,7 +2505,7 @@ _affiliation_autocomplete(ProfWin *window, const char *const input) g_string_append(beginning, args[1]); } - result = autocomplete_param_with_ac(input, beginning->str, jid_ac, TRUE); + result = autocomplete_param_with_ac(input, beginning->str, jid_ac, TRUE, previous); g_string_free(beginning, TRUE); if (result) { g_strfreev(args); @@ -2514,17 +2516,17 @@ _affiliation_autocomplete(ProfWin *window, const char *const input) g_strfreev(args); } - result = autocomplete_param_with_ac(input, "/affiliation set", affiliation_ac, TRUE); + result = autocomplete_param_with_ac(input, "/affiliation set", affiliation_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/affiliation list", affiliation_ac, TRUE); + result = autocomplete_param_with_ac(input, "/affiliation list", affiliation_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/affiliation", privilege_cmd_ac, TRUE); + result = autocomplete_param_with_ac(input, "/affiliation", privilege_cmd_ac, TRUE, previous); if (result) { return result; } @@ -2533,7 +2535,7 @@ _affiliation_autocomplete(ProfWin *window, const char *const input) } static char* -_role_autocomplete(ProfWin *window, const char *const input) +_role_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; @@ -2553,7 +2555,7 @@ _role_autocomplete(ProfWin *window, const char *const input) g_string_append(beginning, args[1]); } - result = autocomplete_param_with_ac(input, beginning->str, nick_ac, TRUE); + result = autocomplete_param_with_ac(input, beginning->str, nick_ac, TRUE, previous); g_string_free(beginning, TRUE); if (result) { g_strfreev(args); @@ -2564,17 +2566,17 @@ _role_autocomplete(ProfWin *window, const char *const input) g_strfreev(args); } - result = autocomplete_param_with_ac(input, "/role set", role_ac, TRUE); + result = autocomplete_param_with_ac(input, "/role set", role_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/role list", role_ac, TRUE); + result = autocomplete_param_with_ac(input, "/role list", role_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/role", privilege_cmd_ac, TRUE); + result = autocomplete_param_with_ac(input, "/role", privilege_cmd_ac, TRUE, previous); if (result) { return result; } @@ -2583,16 +2585,16 @@ _role_autocomplete(ProfWin *window, const char *const input) } static char* -_wins_autocomplete(ProfWin *window, const char *const input) +_wins_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_func(input, "/wins autotidy", prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, "/wins autotidy", prefs_autocomplete_boolean_choice, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/wins", wins_ac, TRUE); + result = autocomplete_param_with_ac(input, "/wins", wins_ac, TRUE, previous); if (result) { return result; } @@ -2601,31 +2603,31 @@ _wins_autocomplete(ProfWin *window, const char *const input) } static char* -_tls_autocomplete(ProfWin *window, const char *const input) +_tls_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_func(input, "/tls revoke", tlscerts_complete); + result = autocomplete_param_with_func(input, "/tls revoke", tlscerts_complete, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/tls cert", tlscerts_complete); + result = autocomplete_param_with_func(input, "/tls cert", tlscerts_complete, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/tls certpath", tls_certpath_ac, TRUE); + result = autocomplete_param_with_ac(input, "/tls certpath", tls_certpath_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/tls show", prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, "/tls show", prefs_autocomplete_boolean_choice, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/tls", tls_ac, TRUE); + result = autocomplete_param_with_ac(input, "/tls", tls_ac, TRUE, previous); if (result) { return result; } @@ -2634,21 +2636,21 @@ _tls_autocomplete(ProfWin *window, const char *const input) } static char* -_receipts_autocomplete(ProfWin *window, const char *const input) +_receipts_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_func(input, "/receipts send", prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, "/receipts send", prefs_autocomplete_boolean_choice, previous); if (result) { return result; } - result = autocomplete_param_with_func(input, "/receipts request", prefs_autocomplete_boolean_choice); + result = autocomplete_param_with_func(input, "/receipts request", prefs_autocomplete_boolean_choice, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/receipts", receipts_ac, TRUE); + result = autocomplete_param_with_ac(input, "/receipts", receipts_ac, TRUE, previous); if (result) { return result; } @@ -2657,16 +2659,16 @@ _receipts_autocomplete(ProfWin *window, const char *const input) } static char* -_alias_autocomplete(ProfWin *window, const char *const input) +_alias_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_ac(input, "/alias remove", aliases_ac, TRUE); + result = autocomplete_param_with_ac(input, "/alias remove", aliases_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/alias", alias_ac, TRUE); + result = autocomplete_param_with_ac(input, "/alias", alias_ac, TRUE, previous); if (result) { return result; } @@ -2675,7 +2677,7 @@ _alias_autocomplete(ProfWin *window, const char *const input) } static char* -_connect_autocomplete(ProfWin *window, const char *const input) +_connect_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; gboolean result = FALSE; @@ -2688,7 +2690,7 @@ _connect_autocomplete(ProfWin *window, const char *const input) if ((num_args == 1 && space_at_end) || (num_args == 2 && !space_at_end)) { GString *beginning = g_string_new("/connect"); g_string_append_printf(beginning, " %s", args[0]); - found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2699,7 +2701,7 @@ _connect_autocomplete(ProfWin *window, const char *const input) || (num_args == 3 && (g_strcmp0(args[1], "tls") == 0) && !space_at_end)) { GString *beginning = g_string_new("/connect"); g_string_append_printf(beginning, " %s %s", args[0], args[1]); - found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2709,7 +2711,7 @@ _connect_autocomplete(ProfWin *window, const char *const input) if ((num_args == 3 && space_at_end) || (num_args == 4 && !space_at_end)) { GString *beginning = g_string_new("/connect"); g_string_append_printf(beginning, " %s %s %s", args[0], args[1], args[2]); - found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2720,7 +2722,7 @@ _connect_autocomplete(ProfWin *window, const char *const input) || (num_args == 5 && (g_strcmp0(args[3], "tls") == 0) && !space_at_end)) { GString *beginning = g_string_new("/connect"); g_string_append_printf(beginning, " %s %s %s %s", args[0], args[1], args[2], args[3]); - found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2730,7 +2732,7 @@ _connect_autocomplete(ProfWin *window, const char *const input) if ((num_args == 5 && space_at_end) || (num_args == 6 && !space_at_end)) { GString *beginning = g_string_new("/connect"); g_string_append_printf(beginning, " %s %s %s %s %s", args[0], args[1], args[2], args[3], args[4]); - found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2741,7 +2743,7 @@ _connect_autocomplete(ProfWin *window, const char *const input) || (num_args == 7 && (g_strcmp0(args[5], "tls") == 0) && !space_at_end)) { GString *beginning = g_string_new("/connect"); g_string_append_printf(beginning, " %s %s %s %s %s %s", args[0], args[1], args[2], args[3], args[4], args[5]); - found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2752,7 +2754,7 @@ _connect_autocomplete(ProfWin *window, const char *const input) g_strfreev(args); - found = autocomplete_param_with_func(input, "/connect", accounts_find_enabled); + found = autocomplete_param_with_func(input, "/connect", accounts_find_enabled, previous); if (found) { return found; } @@ -2761,16 +2763,16 @@ _connect_autocomplete(ProfWin *window, const char *const input) } static char* -_help_autocomplete(ProfWin *window, const char *const input) +_help_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_ac(input, "/help commands", help_commands_ac, TRUE); + result = autocomplete_param_with_ac(input, "/help commands", help_commands_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/help", help_ac, TRUE); + result = autocomplete_param_with_ac(input, "/help", help_ac, TRUE, previous); if (result) { return result; } @@ -2779,7 +2781,7 @@ _help_autocomplete(ProfWin *window, const char *const input) } static char* -_join_autocomplete(ProfWin *window, const char *const input) +_join_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; gboolean result = FALSE; @@ -2792,7 +2794,7 @@ _join_autocomplete(ProfWin *window, const char *const input) if ((num_args == 1 && space_at_end) || (num_args == 2 && !space_at_end)) { GString *beginning = g_string_new("/join"); g_string_append_printf(beginning, " %s", args[0]); - found = autocomplete_param_with_ac(input, beginning->str, join_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, join_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2802,7 +2804,7 @@ _join_autocomplete(ProfWin *window, const char *const input) if ((num_args == 3 && space_at_end) || (num_args == 4 && !space_at_end)) { GString *beginning = g_string_new("/join"); g_string_append_printf(beginning, " %s %s %s", args[0], args[1], args[2]); - found = autocomplete_param_with_ac(input, beginning->str, join_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, join_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2813,7 +2815,7 @@ _join_autocomplete(ProfWin *window, const char *const input) g_strfreev(args); - found = autocomplete_param_with_func(input, "/join", bookmark_find); + found = autocomplete_param_with_func(input, "/join", bookmark_find, previous); if (found) { return found; } @@ -2822,24 +2824,24 @@ _join_autocomplete(ProfWin *window, const char *const input) } static char* -_console_autocomplete(ProfWin *window, const char *const input) +_console_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; - result = autocomplete_param_with_ac(input, "/console chat", console_msg_ac, TRUE); + result = autocomplete_param_with_ac(input, "/console chat", console_msg_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/console muc", console_msg_ac, TRUE); + result = autocomplete_param_with_ac(input, "/console muc", console_msg_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/console private", console_msg_ac, TRUE); + result = autocomplete_param_with_ac(input, "/console private", console_msg_ac, TRUE, previous); if (result) { return result; } - result = autocomplete_param_with_ac(input, "/console", console_ac, TRUE); + result = autocomplete_param_with_ac(input, "/console", console_ac, TRUE, previous); if (result) { return result; } @@ -2848,25 +2850,25 @@ _console_autocomplete(ProfWin *window, const char *const input) } static char* -_win_autocomplete(ProfWin *window, const char *const input) +_win_autocomplete(ProfWin *window, const char *const input, gboolean previous) { - return autocomplete_param_with_func(input, "/win", win_autocomplete); + return autocomplete_param_with_func(input, "/win", win_autocomplete, previous); } static char* -_close_autocomplete(ProfWin *window, const char *const input) +_close_autocomplete(ProfWin *window, const char *const input, gboolean previous) { - return autocomplete_param_with_func(input, "/close", win_close_autocomplete); + return autocomplete_param_with_func(input, "/close", win_close_autocomplete, previous); } static char* -_sendfile_autocomplete(ProfWin *window, const char *const input) +_sendfile_autocomplete(ProfWin *window, const char *const input, gboolean previous) { - return cmd_ac_complete_filepath(input, "/sendfile"); + return cmd_ac_complete_filepath(input, "/sendfile", previous); } static char* -_subject_autocomplete(ProfWin *window, const char *const input) +_subject_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; @@ -2895,7 +2897,7 @@ _subject_autocomplete(ProfWin *window, const char *const input) return result; } - result = autocomplete_param_with_ac(input, "/subject", subject_ac, TRUE); + result = autocomplete_param_with_ac(input, "/subject", subject_ac, TRUE, previous); if (result) { return result; } @@ -2904,7 +2906,7 @@ _subject_autocomplete(ProfWin *window, const char *const input) } static char* -_account_autocomplete(ProfWin *window, const char *const input) +_account_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; gboolean result = FALSE; @@ -2916,7 +2918,7 @@ _account_autocomplete(ProfWin *window, const char *const input) if ((num_args == 2 && space_at_end) || (num_args == 3 && !space_at_end)) { GString *beginning = g_string_new("/account"); g_string_append_printf(beginning, " %s %s", args[0], args[1]); - found = autocomplete_param_with_ac(input, beginning->str, account_set_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, account_set_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2927,7 +2929,7 @@ _account_autocomplete(ProfWin *window, const char *const input) || (num_args == 4 && (g_strcmp0(args[2], "otr") == 0) && !space_at_end)) { GString *beginning = g_string_new("/account"); g_string_append_printf(beginning, " %s %s %s", args[0], args[1], args[2]); - found = autocomplete_param_with_ac(input, beginning->str, otr_policy_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, otr_policy_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2938,7 +2940,7 @@ _account_autocomplete(ProfWin *window, const char *const input) || (num_args == 4 && (g_strcmp0(args[2], "status") == 0) && !space_at_end)) { GString *beginning = g_string_new("/account"); g_string_append_printf(beginning, " %s %s %s", args[0], args[1], args[2]); - found = autocomplete_param_with_ac(input, beginning->str, account_status_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, account_status_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2949,7 +2951,7 @@ _account_autocomplete(ProfWin *window, const char *const input) || (num_args == 4 && (g_strcmp0(args[2], "tls") == 0) && !space_at_end)) { GString *beginning = g_string_new("/account"); g_string_append_printf(beginning, " %s %s %s", args[0], args[1], args[2]); - found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2960,7 +2962,7 @@ _account_autocomplete(ProfWin *window, const char *const input) || (num_args == 4 && (g_strcmp0(args[2], "startscript") == 0) && !space_at_end)) { GString *beginning = g_string_new("/account"); g_string_append_printf(beginning, " %s %s %s", args[0], args[1], args[2]); - found = autocomplete_param_with_func(input, beginning->str, _script_autocomplete_func); + found = autocomplete_param_with_func(input, beginning->str, _script_autocomplete_func, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2982,7 +2984,7 @@ _account_autocomplete(ProfWin *window, const char *const input) g_slist_free_full(themes, g_free); autocomplete_add(theme_load_ac, "default"); } - found = autocomplete_param_with_ac(input, beginning->str, theme_load_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, theme_load_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -2994,7 +2996,7 @@ _account_autocomplete(ProfWin *window, const char *const input) || (num_args == 4 && (g_strcmp0(args[2], "pgpkeyid") == 0) && !space_at_end)) { GString *beginning = g_string_new("/account"); g_string_append_printf(beginning, " %s %s %s", args[0], args[1], args[2]); - found = autocomplete_param_with_func(input, beginning->str, p_gpg_autocomplete_key); + found = autocomplete_param_with_func(input, beginning->str, p_gpg_autocomplete_key, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -3007,7 +3009,7 @@ _account_autocomplete(ProfWin *window, const char *const input) if ((strncmp(input, "/account clear", 14) == 0) && (result == TRUE)) { GString *beginning = g_string_new("/account clear "); g_string_append(beginning, args[1]); - found = autocomplete_param_with_ac(input, beginning->str, account_clear_ac, TRUE); + found = autocomplete_param_with_ac(input, beginning->str, account_clear_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { g_strfreev(args); @@ -3017,7 +3019,7 @@ _account_autocomplete(ProfWin *window, const char *const input) g_strfreev(args); - found = autocomplete_param_with_ac(input, "/account default", account_default_ac, TRUE); + found = autocomplete_param_with_ac(input, "/account default", account_default_ac, TRUE, previous); if(found){ return found; } @@ -3028,42 +3030,42 @@ _account_autocomplete(ProfWin *window, const char *const input) "/account default set" }; for (i = 0; i < ARRAY_SIZE(account_choice); i++) { - found = autocomplete_param_with_func(input, account_choice[i], accounts_find_all); + found = autocomplete_param_with_func(input, account_choice[i], accounts_find_all, previous); if (found) { return found; } } - found = autocomplete_param_with_ac(input, "/account", account_ac, TRUE); + found = autocomplete_param_with_ac(input, "/account", account_ac, TRUE, previous); return found; } static char* -_presence_autocomplete(ProfWin *window, const char *const input) +_presence_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *found = NULL; - found = autocomplete_param_with_func(input, "/presence titlebar", prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_func(input, "/presence titlebar", prefs_autocomplete_boolean_choice, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/presence console", presence_setting_ac, TRUE); + found = autocomplete_param_with_ac(input, "/presence console", presence_setting_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/presence chat", presence_setting_ac, TRUE); + found = autocomplete_param_with_ac(input, "/presence chat", presence_setting_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/presence room", presence_setting_ac, TRUE); + found = autocomplete_param_with_ac(input, "/presence room", presence_setting_ac, TRUE, previous); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/presence", presence_ac, TRUE); + found = autocomplete_param_with_ac(input, "/presence", presence_ac, TRUE, previous); if (found) { return found; } diff --git a/src/command/cmd_ac.h b/src/command/cmd_ac.h index b5e2f7d6..d56d0e30 100644 --- a/src/command/cmd_ac.h +++ b/src/command/cmd_ac.h @@ -40,7 +40,7 @@ void cmd_ac_init(void); void cmd_ac_uninit(void); -char* cmd_ac_complete(ProfWin *window, const char *const input); +char* cmd_ac_complete(ProfWin *window, const char *const input, gboolean previous); void cmd_ac_reset(ProfWin *window); gboolean cmd_ac_exists(char *cmd); @@ -57,6 +57,6 @@ void cmd_ac_remove_alias_value(char *value); void cmd_ac_add_form_fields(DataForm *form); void cmd_ac_remove_form_fields(DataForm *form); -char* cmd_ac_complete_filepath(const char *const input, char *const startstr); +char* cmd_ac_complete_filepath(const char *const input, char *const startstr, gboolean previous); #endif diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 8f8ced09..ae77bf53 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -113,12 +113,12 @@ static gboolean _cmd_has_tag(Command *pcmd, const char *const tag); static struct cmd_t command_defs[] = { { "/help", - parse_args, 0, 2, NULL, + parse_args_with_freetext, 0, 2, NULL, CMD_NOSUBFUNCS CMD_MAINFUNC(cmd_help) CMD_NOTAGS CMD_SYN( - "/help [|]") + "/help [||search_all|search_any] []") CMD_DESC( "Help on using Profanity. Passing no arguments list help areas. " "For command help, optional arguments are shown using square brackets, " @@ -126,9 +126,12 @@ static struct cmd_t command_defs[] = "Arguments that may be one of a number of values are separated by a pipe " "e.g. val1|val2|val3.") CMD_ARGS( - { "", "Summary help for commands in a certain area of functionality." }, - { "", "Full help for a specific command, for example '/help connect'." }) + { "", "Summary help for commands in a certain area of functionality." }, + { "", "Full help for a specific command, for example '/help connect'." }, + { "search_all ", "Search commands for returning matches that contain all of the search terms." }, + { "search_any ", "Search commands for returning matches that contain any of the search terms." }) CMD_EXAMPLES( + "/help search_all presence online", "/help commands", "/help presence", "/help who") @@ -576,7 +579,7 @@ static struct cmd_t command_defs[] = CMD_SYN( "/leave") CMD_DESC( - "Leave the current chat room.") + "Leave the current chat or room.") CMD_NOARGS CMD_NOEXAMPLES }, @@ -2264,9 +2267,112 @@ static struct cmd_t command_defs[] = CMD_EXAMPLES( "/export /path/to/output.csv", "/export ~/contacts.csv") - }, + } }; +static GHashTable *search_index; + +char* +_cmd_index(Command *cmd) { + GString *index_source = g_string_new(""); + index_source = g_string_append(index_source, cmd->cmd); + index_source = g_string_append(index_source, " "); + index_source = g_string_append(index_source, cmd->help.desc); + index_source = g_string_append(index_source, " "); + + int len = g_strv_length(cmd->help.tags); + int i = 0; + for (i = 0; i < len; i++) { + index_source = g_string_append(index_source, cmd->help.tags[i]); + index_source = g_string_append(index_source, " "); + } + len = g_strv_length(cmd->help.synopsis); + for (i = 0; i < len; i++) { + index_source = g_string_append(index_source, cmd->help.synopsis[i]); + index_source = g_string_append(index_source, " "); + } + for (i = 0; cmd->help.args[i][0] != NULL; i++) { + index_source = g_string_append(index_source, cmd->help.args[i][0]); + index_source = g_string_append(index_source, " "); + index_source = g_string_append(index_source, cmd->help.args[i][1]); + index_source = g_string_append(index_source, " "); + } + + gchar **tokens = g_str_tokenize_and_fold(index_source->str, NULL, NULL); + g_string_free(index_source, TRUE); + + GString *index = g_string_new(""); + i = 0; + for (i = 0; i < g_strv_length(tokens); i++) { + index = g_string_append(index, tokens[i]); + index = g_string_append(index, " "); + } + g_strfreev(tokens); + + char *res = index->str; + g_string_free(index, FALSE); + + return res; +} + +GList* +cmd_search_index_any(char *term) +{ + GList *results = NULL; + + gchar **processed_terms = g_str_tokenize_and_fold(term, NULL, NULL); + int terms_len = g_strv_length(processed_terms); + + int i = 0; + for (i = 0; i < terms_len; i++) { + GList *index_keys = g_hash_table_get_keys(search_index); + GList *curr = index_keys; + while (curr) { + char *index_entry = g_hash_table_lookup(search_index, curr->data); + if (g_str_match_string(processed_terms[i], index_entry, FALSE)) { + results = g_list_append(results, curr->data); + } + curr = g_list_next(curr); + } + g_list_free(index_keys); + } + + g_strfreev(processed_terms); + + return results; +} + +GList* +cmd_search_index_all(char *term) +{ + GList *results = NULL; + + gchar **terms = g_str_tokenize_and_fold(term, NULL, NULL); + int terms_len = g_strv_length(terms); + + GList *commands = g_hash_table_get_keys(search_index); + GList *curr = commands; + while (curr) { + char *command = curr->data; + int matches = 0; + int i = 0; + for (i = 0; i < terms_len; i++) { + char *command_index = g_hash_table_lookup(search_index, command); + if (g_str_match_string(terms[i], command_index, FALSE)) { + matches++; + } + } + if (matches == terms_len) { + results = g_list_append(results, command); + } + curr = g_list_next(curr); + } + + g_list_free(commands); + g_strfreev(terms); + + return results; +} /* * Initialise command autocompleter and history @@ -2278,6 +2384,8 @@ cmd_init(void) cmd_ac_init(); + search_index = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); + // load command defs into hash table commands = g_hash_table_new(g_str_hash, g_str_equal); unsigned int i; @@ -2287,6 +2395,9 @@ cmd_init(void) // add to hash g_hash_table_insert(commands, pcmd->cmd, pcmd); + // add to search index + g_hash_table_insert(search_index, strdup(pcmd->cmd), strdup(_cmd_index(pcmd))); + // add to commands and help autocompleters cmd_ac_add_cmd(pcmd); } @@ -2306,6 +2417,7 @@ void cmd_uninit(void) { cmd_ac_uninit(); + g_hash_table_destroy(search_index); } gboolean diff --git a/src/command/cmd_defs.h b/src/command/cmd_defs.h index 074970c9..e0cadaf2 100644 --- a/src/command/cmd_defs.h +++ b/src/command/cmd_defs.h @@ -49,4 +49,7 @@ gboolean cmd_valid_tag(const char *const str); void command_docgen(void); +GList* cmd_search_index_all(char *term); +GList* cmd_search_index_any(char *term); + #endif diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 3df17079..71c8816a 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -1484,6 +1484,41 @@ cmd_win(ProfWin *window, const char *const command, gchar **args) return TRUE; } +static void +_cmd_list_commands(GList *commands) { + int maxlen = 0; + GList *curr = commands; + while (curr) { + gchar *cmd = curr->data; + int len = strlen(cmd); + if (len > maxlen) maxlen = len; + curr = g_list_next(curr); + } + + GString *cmds = g_string_new(""); + curr = commands; + int count = 0; + while (curr) { + gchar *cmd = curr->data; + if (count == 5) { + cons_show(cmds->str); + g_string_free(cmds, TRUE); + cmds = g_string_new(""); + count = 0; + } + g_string_append_printf(cmds, "%-*s", maxlen + 1, cmd); + curr = g_list_next(curr); + count++; + } + cons_show(cmds->str); + g_string_free(cmds, TRUE); + g_list_free(curr); + + cons_show(""); + cons_show("Use /help [command] without the leading slash, for help on a specific command"); + cons_show(""); +} + static void _cmd_help_cmd_list(const char *const tag) { @@ -1520,38 +1555,8 @@ _cmd_help_cmd_list(const char *const tag) } } - int maxlen = 0; - GList *curr = ordered_commands; - while (curr) { - gchar *cmd = curr->data; - int len = strlen(cmd); - if (len > maxlen) maxlen = len; - curr = g_list_next(curr); - } - - GString *cmds = g_string_new(""); - curr = ordered_commands; - int count = 0; - while (curr) { - gchar *cmd = curr->data; - if (count == 5) { - cons_show(cmds->str); - g_string_free(cmds, TRUE); - cmds = g_string_new(""); - count = 0; - } - g_string_append_printf(cmds, "%-*s", maxlen + 1, cmd); - curr = g_list_next(curr); - count++; - } - cons_show(cmds->str); - g_string_free(cmds, TRUE); + _cmd_list_commands(ordered_commands); g_list_free(ordered_commands); - g_list_free(curr); - - cons_show(""); - cons_show("Use /help [command] without the leading slash, for help on a specific command"); - cons_show(""); } gboolean @@ -1560,6 +1565,46 @@ cmd_help(ProfWin *window, const char *const command, gchar **args) int num_args = g_strv_length(args); if (num_args == 0) { cons_help(); + } else if (strcmp(args[0], "search_all") == 0) { + if (args[1] == NULL) { + cons_bad_cmd_usage(command); + } else { + GList *cmds = cmd_search_index_all(args[1]); + if (cmds == NULL) { + cons_show("No commands found."); + } else { + GList *curr = cmds; + GList *results = NULL; + while (curr) { + results = g_list_insert_sorted(results, curr->data, (GCompareFunc)g_strcmp0); + curr = g_list_next(curr); + } + cons_show("Search results:"); + _cmd_list_commands(results); + g_list_free(results); + } + g_list_free(cmds); + } + } else if (strcmp(args[0], "search_any") == 0) { + if (args[1] == NULL) { + cons_bad_cmd_usage(command); + } else { + GList *cmds = cmd_search_index_any(args[1]); + if (cmds == NULL) { + cons_show("No commands found."); + } else { + GList *curr = cmds; + GList *results = NULL; + while (curr) { + results = g_list_insert_sorted(results, curr->data, (GCompareFunc)g_strcmp0); + curr = g_list_next(curr); + } + cons_show("Search results:"); + _cmd_list_commands(results); + g_list_free(results); + } + g_list_free(cmds); + } } else if (strcmp(args[0], "commands") == 0) { if (args[1]) { if (!cmd_valid_tag(args[1])) { @@ -2133,16 +2178,16 @@ cmd_group(ProfWin *window, const char *const command, gchar **args) // list all groups if (args[0] == NULL) { - GSList *groups = roster_get_groups(); - GSList *curr = groups; + GList *groups = roster_get_groups(); + GList *curr = groups; if (curr) { cons_show("Groups:"); while (curr) { cons_show(" %s", curr->data); - curr = g_slist_next(curr); + curr = g_list_next(curr); } - g_slist_free_full(groups, g_free); + g_list_free_full(groups, g_free); } else { cons_show("No groups."); } @@ -3562,9 +3607,9 @@ cmd_invite(ProfWin *window, const char *const command, gchar **args) gboolean cmd_invites(ProfWin *window, const char *const command, gchar **args) { - GSList *invites = muc_invites(); + GList *invites = muc_invites(); cons_show_room_invites(invites); - g_slist_free_full(invites, g_free); + g_list_free_full(invites, g_free); return TRUE; } @@ -4756,24 +4801,14 @@ cmd_clear(ProfWin *window, const char *const command, gchar **args) gboolean cmd_leave(ProfWin *window, const char *const command, gchar **args) { - jabber_conn_status_t conn_status = connection_get_status(); - int index = wins_get_current_num(); - - if (window->type != WIN_MUC) { - cons_show("You can only use the /leave command in a chat room."); + if (window->type != WIN_MUC && window->type != WIN_CHAT && window->type != WIN_PRIVATE) { + cons_show("The /leave command is only valid in chat, or chat room windows."); cons_alert(); return TRUE; } - // handle leaving rooms, or chat - if (conn_status == JABBER_CONNECTED) { - ui_close_connected_win(index); - } - - // close the window - ui_close_win(index); - - return TRUE; + // use /close behaviour + return cmd_close(window, "/leave", args); } gboolean diff --git a/src/common.c b/src/common.c index 898f62fa..fa3af68c 100644 --- a/src/common.c +++ b/src/common.c @@ -67,54 +67,6 @@ static unsigned long unique_id = 0; static size_t _data_callback(void *ptr, size_t size, size_t nmemb, void *data); -// taken from glib 2.30.3 -gchar* -p_utf8_substring(const gchar *str, glong start_pos, glong end_pos) -{ - gchar *start, *end, *out; - - start = g_utf8_offset_to_pointer (str, start_pos); - end = g_utf8_offset_to_pointer (start, end_pos - start_pos); - - out = g_malloc (end - start + 1); - memcpy (out, start, end - start); - out[end - start] = 0; - - return out; -} - -void -p_slist_free_full(GSList *items, GDestroyNotify free_func) -{ - g_slist_foreach (items, (GFunc) free_func, NULL); - g_slist_free (items); -} - -void -p_list_free_full(GList *items, GDestroyNotify free_func) -{ - g_list_foreach (items, (GFunc) free_func, NULL); - g_list_free (items); -} - -gboolean -p_hash_table_add(GHashTable *hash_table, gpointer key) -{ - // doesn't handle when key exists, but value == NULL - gpointer found = g_hash_table_lookup(hash_table, key); - g_hash_table_replace(hash_table, key, key); - - return (found == NULL); -} - -gboolean -p_hash_table_contains(GHashTable *hash_table, gconstpointer key) -{ - // doesn't handle when key exists, but value == NULL - gpointer found = g_hash_table_lookup(hash_table, key); - return (found != NULL); -} - gboolean create_dir(char *name) { @@ -515,11 +467,18 @@ prof_occurrences(const char *const needle, const char *const haystack, int offse gchar *needle_last_ch = g_utf8_offset_to_pointer(needle, g_utf8_strlen(needle, -1)- 1); int needle_last_ch_len = mblen(needle_last_ch, MB_CUR_MAX); - gchar *haystack_before_ch = g_utf8_prev_char(haystack_curr); - gchar *haystack_after_ch = g_utf8_next_char(haystack_curr + strlen(needle) - needle_last_ch_len); + gunichar before = 0; + gchar *haystack_before_ch = g_utf8_find_prev_char(haystack, haystack_curr); + if (haystack_before_ch) { + before = g_utf8_get_char(haystack_before_ch); + } + + gunichar after = 0; + gchar *haystack_after_ch = g_utf8_find_next_char(haystack_curr + strlen(needle) - needle_last_ch_len, NULL); + if (haystack_after_ch) { + after = g_utf8_get_char(haystack_after_ch); + } - gunichar before = g_utf8_get_char(haystack_before_ch); - gunichar after = g_utf8_get_char(haystack_after_ch); if (!g_unichar_isalnum(before) && !g_unichar_isalnum(after)) { *result = g_slist_append(*result, GINT_TO_POINTER(offset)); } diff --git a/src/common.h b/src/common.h index 8c42ae52..421c56cd 100644 --- a/src/common.h +++ b/src/common.h @@ -40,20 +40,6 @@ #include -#if !GLIB_CHECK_VERSION(2,28,0) -#define g_slist_free_full(items, free_func) p_slist_free_full(items, free_func) -#define g_list_free_full(items, free_func) p_list_free_full(items, free_func) -#endif - -#if !GLIB_CHECK_VERSION(2,30,0) -#define g_utf8_substring(str, start_pos, end_pos) p_utf8_substring(str, start_pos, end_pos) -#endif - -#if !GLIB_CHECK_VERSION(2,32,0) -#define g_hash_table_add(hash_table, key) p_hash_table_add(hash_table, key) -#define g_hash_table_contains(hash_table, key) p_hash_table_contains(hash_table, key) -#endif - #ifndef NOTIFY_CHECK_VERSION #define notify_notification_new(summary, body, icon) notify_notification_new(summary, body, icon, NULL) #endif @@ -94,12 +80,6 @@ typedef enum { RESOURCE_XA } resource_presence_t; -gchar* p_utf8_substring(const gchar *str, glong start_pos, glong end_pos); -void p_slist_free_full(GSList *items, GDestroyNotify free_func); -void p_list_free_full(GList *items, GDestroyNotify free_func); -gboolean p_hash_table_add(GHashTable *hash_table, gpointer key); -gboolean p_hash_table_contains(GHashTable *hash_table, gconstpointer key); - gboolean create_dir(char *name); gboolean mkdir_recursive(const char *dir); gboolean copy_file(const char *const src, const char *const target); diff --git a/src/config/accounts.c b/src/config/accounts.c index fd57a177..fb7b4a0e 100644 --- a/src/config/accounts.c +++ b/src/config/accounts.c @@ -96,15 +96,15 @@ accounts_close(void) } char* -accounts_find_enabled(const char *const prefix) +accounts_find_enabled(const char *const prefix, gboolean previous) { - return autocomplete_complete(enabled_ac, prefix, TRUE); + return autocomplete_complete(enabled_ac, prefix, TRUE, previous); } char* -accounts_find_all(const char *const prefix) +accounts_find_all(const char *const prefix, gboolean previous) { - return autocomplete_complete(all_ac, prefix, TRUE); + return autocomplete_complete(all_ac, prefix, TRUE, previous); } void diff --git a/src/config/accounts.h b/src/config/accounts.h index f5735f07..51969ab8 100644 --- a/src/config/accounts.h +++ b/src/config/accounts.h @@ -43,8 +43,8 @@ void accounts_load(void); void accounts_close(void); -char* accounts_find_all(const char *const prefix); -char* accounts_find_enabled(const char *const prefix); +char* accounts_find_all(const char *const prefix, gboolean previous); +char* accounts_find_enabled(const char *const prefix, gboolean previous); void accounts_reset_all_search(void); void accounts_reset_enabled_search(void); void accounts_add(const char *jid, const char *altdomain, const int port, const char *const tls_policy); diff --git a/src/config/preferences.c b/src/config/preferences.c index 6dc8ef32..b86f710a 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -183,9 +183,9 @@ prefs_close(void) } char* -prefs_autocomplete_boolean_choice(const char *const prefix) +prefs_autocomplete_boolean_choice(const char *const prefix, gboolean previous) { - return autocomplete_complete(boolean_choice_ac, prefix, TRUE); + return autocomplete_complete(boolean_choice_ac, prefix, TRUE, previous); } void @@ -195,9 +195,9 @@ prefs_reset_boolean_choice(void) } char* -prefs_autocomplete_room_trigger(const char *const prefix) +prefs_autocomplete_room_trigger(const char *const prefix, gboolean previous) { - return autocomplete_complete(room_trigger_ac, prefix, TRUE); + return autocomplete_complete(room_trigger_ac, prefix, TRUE, previous); } void diff --git a/src/config/preferences.h b/src/config/preferences.h index cc605c79..134fba49 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -162,10 +162,10 @@ void prefs_close(void); char* prefs_find_login(char *prefix); void prefs_reset_login_search(void); -char* prefs_autocomplete_boolean_choice(const char *const prefix); +char* prefs_autocomplete_boolean_choice(const char *const prefix, gboolean previous); void prefs_reset_boolean_choice(void); -char* prefs_autocomplete_room_trigger(const char *const prefix); +char* prefs_autocomplete_room_trigger(const char *const prefix, gboolean previous); void prefs_reset_room_trigger_ac(void); gint prefs_get_gone(void); diff --git a/src/config/theme.c b/src/config/theme.c index 2d418f73..5a44e370 100644 --- a/src/config/theme.c +++ b/src/config/theme.c @@ -104,6 +104,7 @@ theme_init(const char *const theme_name) g_hash_table_insert(defaults, strdup("statusbar.brackets"), strdup("cyan")); g_hash_table_insert(defaults, strdup("statusbar.active"), strdup("cyan")); g_hash_table_insert(defaults, strdup("statusbar.new"), strdup("white")); + g_hash_table_insert(defaults, strdup("statusbar.time"), strdup("white")); g_hash_table_insert(defaults, strdup("me"), strdup("yellow")); g_hash_table_insert(defaults, strdup("them"), strdup("green")); g_hash_table_insert(defaults, strdup("receipt.sent"), strdup("red")); @@ -755,6 +756,7 @@ theme_attrs(theme_item_t attrs) case THEME_STATUS_BRACKET: _theme_prep_fgnd("statusbar.brackets", lookup_str, &bold); break; case THEME_STATUS_ACTIVE: _theme_prep_fgnd("statusbar.active", lookup_str, &bold); break; case THEME_STATUS_NEW: _theme_prep_fgnd("statusbar.new", lookup_str, &bold); break; + case THEME_STATUS_TIME: _theme_prep_fgnd("statusbar.time", lookup_str, &bold); break; case THEME_ME: _theme_prep_fgnd("me", lookup_str, &bold); break; case THEME_THEM: _theme_prep_fgnd("them", lookup_str, &bold); break; case THEME_RECEIPT_SENT: _theme_prep_fgnd("receipt.sent", lookup_str, &bold); break; @@ -843,6 +845,7 @@ theme_attrs(theme_item_t attrs) case THEME_STATUS_BRACKET: case THEME_STATUS_ACTIVE: case THEME_STATUS_NEW: + case THEME_STATUS_TIME: _theme_prep_bgnd("statusbar", "blue", lookup_str); break; default: diff --git a/src/config/theme.h b/src/config/theme.h index 6e9d13eb..747eace1 100644 --- a/src/config/theme.h +++ b/src/config/theme.h @@ -69,6 +69,7 @@ typedef enum { THEME_STATUS_BRACKET, THEME_STATUS_ACTIVE, THEME_STATUS_NEW, + THEME_STATUS_TIME, THEME_ME, THEME_THEM, THEME_ROOMINFO, diff --git a/src/config/tlscerts.c b/src/config/tlscerts.c index a664eabb..39733405 100644 --- a/src/config/tlscerts.c +++ b/src/config/tlscerts.c @@ -368,9 +368,9 @@ tlscerts_get_trusted(const char * const fingerprint) } char* -tlscerts_complete(const char *const prefix) +tlscerts_complete(const char *const prefix, gboolean previous) { - return autocomplete_complete(certs_ac, prefix, TRUE); + return autocomplete_complete(certs_ac, prefix, TRUE, previous); } void diff --git a/src/config/tlscerts.h b/src/config/tlscerts.h index c32412de..e1a1758f 100644 --- a/src/config/tlscerts.h +++ b/src/config/tlscerts.h @@ -89,7 +89,7 @@ void tlscerts_free(TLSCertificate *cert); GList* tlscerts_list(void); -char* tlscerts_complete(const char *const prefix); +char* tlscerts_complete(const char *const prefix, gboolean previous); void tlscerts_reset_ac(void); diff --git a/src/pgp/gpg.c b/src/pgp/gpg.c index 2a875404..051f99f0 100644 --- a/src/pgp/gpg.c +++ b/src/pgp/gpg.c @@ -749,9 +749,9 @@ p_gpg_free_decrypted(char *decrypted) } char* -p_gpg_autocomplete_key(const char *const search_str) +p_gpg_autocomplete_key(const char *const search_str, gboolean previous) { - return autocomplete_complete(key_ac, search_str, TRUE); + return autocomplete_complete(key_ac, search_str, TRUE, previous); } void diff --git a/src/pgp/gpg.h b/src/pgp/gpg.h index 81128df2..8377b05d 100644 --- a/src/pgp/gpg.h +++ b/src/pgp/gpg.h @@ -67,7 +67,7 @@ void p_gpg_verify(const char *const barejid, const char *const sign); char* p_gpg_encrypt(const char *const barejid, const char *const message, const char *const fp); char* p_gpg_decrypt(const char *const cipher); void p_gpg_free_decrypted(char *decrypted); -char* p_gpg_autocomplete_key(const char *const search_str); +char* p_gpg_autocomplete_key(const char *const search_str, gboolean previous); void p_gpg_autocomplete_key_reset(void); char* p_gpg_format_fp_str(char *fp); diff --git a/src/plugins/autocompleters.c b/src/plugins/autocompleters.c index 1f0d3c4c..20abaddf 100644 --- a/src/plugins/autocompleters.c +++ b/src/plugins/autocompleters.c @@ -129,7 +129,7 @@ autocompleters_filepath_add(const char *const plugin_name, const char *prefix) } char* -autocompleters_complete(const char * const input) +autocompleters_complete(const char * const input, gboolean previous) { char *result = NULL; @@ -141,7 +141,7 @@ autocompleters_complete(const char * const input) GList *keys = g_hash_table_get_keys(key_to_ac); GList *curr = keys; while (curr) { - result = autocomplete_param_with_ac(input, curr->data, g_hash_table_lookup(key_to_ac, curr->data), TRUE); + result = autocomplete_param_with_ac(input, curr->data, g_hash_table_lookup(key_to_ac, curr->data), TRUE, previous); if (result) { g_list_free(ac_hashes); g_list_free(keys); @@ -164,7 +164,7 @@ autocompleters_complete(const char * const input) while (curr_prefix) { char *prefix = curr_prefix->data; if (g_str_has_prefix(input, prefix)) { - result = cmd_ac_complete_filepath(input, prefix); + result = cmd_ac_complete_filepath(input, prefix, previous); if (result) { g_list_free(filepath_hashes); g_list_free(prefixes); diff --git a/src/plugins/autocompleters.h b/src/plugins/autocompleters.h index 2d6b072d..37539e27 100644 --- a/src/plugins/autocompleters.h +++ b/src/plugins/autocompleters.h @@ -42,7 +42,7 @@ void autocompleters_add(const char *const plugin_name, const char *key, char **i void autocompleters_remove(const char *const plugin_name, const char *key, char **items); void autocompleters_clear(const char *const plugin_name, const char *key); void autocompleters_filepath_add(const char *const plugin_name, const char *prefix); -char* autocompleters_complete(const char * const input); +char* autocompleters_complete(const char * const input, gboolean previous); void autocompleters_reset(void); void autocompleters_destroy(void); diff --git a/src/plugins/plugins.c b/src/plugins/plugins.c index 92d605e8..06b1417f 100644 --- a/src/plugins/plugins.c +++ b/src/plugins/plugins.c @@ -369,9 +369,9 @@ plugins_loaded_list(void) } char * -plugins_autocomplete(const char * const input) +plugins_autocomplete(const char * const input, gboolean previous) { - return autocompleters_complete(input); + return autocompleters_complete(input, previous); } void diff --git a/src/plugins/plugins.h b/src/plugins/plugins.h index af659757..0aa490f0 100644 --- a/src/plugins/plugins.h +++ b/src/plugins/plugins.h @@ -108,7 +108,7 @@ typedef struct prof_plugin_t { void plugins_init(void); GSList *plugins_unloaded_list(void); GList *plugins_loaded_list(void); -char* plugins_autocomplete(const char *const input); +char* plugins_autocomplete(const char *const input, gboolean previous); void plugins_reset_autocomplete(void); void plugins_shutdown(void); diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c index b3c49610..c4a843ba 100644 --- a/src/tools/autocomplete.c +++ b/src/tools/autocomplete.c @@ -35,18 +35,21 @@ #include #include #include +#include #include "common.h" #include "tools/autocomplete.h" #include "tools/parser.h" +#include "ui/ui.h" struct autocomplete_t { - GSList *items; - GSList *last_found; + GList *items; + GList *last_found; gchar *search_str; }; -static gchar* _search_from(Autocomplete ac, GSList *curr, gboolean quote); +static gchar* _search_next(Autocomplete ac, GList *curr, gboolean quote); +static gchar* _search_prev(Autocomplete ac, GList *curr, gboolean quote); Autocomplete autocomplete_new(void) @@ -63,7 +66,7 @@ void autocomplete_clear(Autocomplete ac) { if (ac) { - g_slist_free_full(ac->items, free); + g_list_free_full(ac->items, free); ac->items = NULL; autocomplete_reset(ac); @@ -94,7 +97,7 @@ autocomplete_length(Autocomplete ac) } else if (!ac->items) { return 0; } else { - return g_slist_length(ac->items); + return g_list_length(ac->items); } } @@ -103,7 +106,7 @@ autocomplete_add(Autocomplete ac, const char *item) { if (ac) { char *item_cpy; - GSList *curr = g_slist_find_custom(ac->items, item, (GCompareFunc)strcmp); + GList *curr = g_list_find_custom(ac->items, item, (GCompareFunc)strcmp); // if item already exists if (curr) { @@ -111,7 +114,7 @@ autocomplete_add(Autocomplete ac, const char *item) } item_cpy = strdup(item); - ac->items = g_slist_insert_sorted(ac->items, item_cpy, (GCompareFunc)strcmp); + ac->items = g_list_insert_sorted(ac->items, item_cpy, (GCompareFunc)strcmp); } return; @@ -130,7 +133,7 @@ void autocomplete_remove(Autocomplete ac, const char *const item) { if (ac) { - GSList *curr = g_slist_find_custom(ac->items, item, (GCompareFunc)strcmp); + GList *curr = g_list_find_custom(ac->items, item, (GCompareFunc)strcmp); if (!curr) { return; @@ -142,7 +145,7 @@ autocomplete_remove(Autocomplete ac, const char *const item) } free(curr->data); - ac->items = g_slist_delete_link(ac->items, curr); + ac->items = g_list_delete_link(ac->items, curr); } return; @@ -157,15 +160,15 @@ autocomplete_remove_all(Autocomplete ac, char **items) } } -GSList* +GList* autocomplete_create_list(Autocomplete ac) { - GSList *copy = NULL; - GSList *curr = ac->items; + GList *copy = NULL; + GList *curr = ac->items; while(curr) { - copy = g_slist_append(copy, strdup(curr->data)); - curr = g_slist_next(curr); + copy = g_list_append(copy, strdup(curr->data)); + curr = g_list_next(curr); } return copy; @@ -174,20 +177,20 @@ autocomplete_create_list(Autocomplete ac) gboolean autocomplete_contains(Autocomplete ac, const char *value) { - GSList *curr = ac->items; + GList *curr = ac->items; while(curr) { if (strcmp(curr->data, value) == 0) { return TRUE; } - curr = g_slist_next(curr); + curr = g_list_next(curr); } return FALSE; } gchar* -autocomplete_complete(Autocomplete ac, const gchar *search_str, gboolean quote) +autocomplete_complete(Autocomplete ac, const gchar *search_str, gboolean quote, gboolean previous) { gchar *found = NULL; @@ -208,22 +211,38 @@ autocomplete_complete(Autocomplete ac, const gchar *search_str, gboolean quote) } ac->search_str = strdup(search_str); - found = _search_from(ac, ac->items, quote); + found = _search_next(ac, ac->items, quote); return found; // subsequent search attempt } else { - // search from here+1 to end - found = _search_from(ac, g_slist_next(ac->last_found), quote); - if (found) { - return found; + if (previous) { + // search from here-1 to beginning + found = _search_prev(ac, g_list_previous(ac->last_found), quote); + if (found) { + return found; + } + } else { + // search from here+1 to end + found = _search_next(ac, g_list_next(ac->last_found), quote); + if (found) { + return found; + } } - // search from beginning - found = _search_from(ac, ac->items, quote); - if (found) { - return found; + if (previous) { + // search from end + found = _search_prev(ac, g_list_last(ac->items), quote); + if (found) { + return found; + } + } else { + // search from beginning + found = _search_next(ac, ac->items, quote); + if (found) { + return found; + } } // we found nothing, reset search @@ -234,7 +253,7 @@ autocomplete_complete(Autocomplete ac, const gchar *search_str, gboolean quote) } char* -autocomplete_param_with_func(const char *const input, char *command, autocomplete_func func) +autocomplete_param_with_func(const char *const input, char *command, autocomplete_func func, gboolean previous) { GString *auto_msg = NULL; char *result = NULL; @@ -251,7 +270,7 @@ autocomplete_param_with_func(const char *const input, char *command, autocomplet } prefix[inp_len - len] = '\0'; - char *found = func(prefix); + char *found = func(prefix, previous); if (found) { auto_msg = g_string_new(command_cpy); g_string_append(auto_msg, found); @@ -265,7 +284,7 @@ autocomplete_param_with_func(const char *const input, char *command, autocomplet } char* -autocomplete_param_with_ac(const char *const input, char *command, Autocomplete ac, gboolean quote) +autocomplete_param_with_ac(const char *const input, char *command, Autocomplete ac, gboolean quote, gboolean previous) { GString *auto_msg = NULL; char *result = NULL; @@ -281,7 +300,7 @@ autocomplete_param_with_ac(const char *const input, char *command, Autocomplete } prefix[inp_len - len] = '\0'; - char *found = autocomplete_complete(ac, prefix, quote); + char *found = autocomplete_complete(ac, prefix, quote, previous); if (found) { auto_msg = g_string_new(command_cpy); g_string_append(auto_msg, found); @@ -296,7 +315,7 @@ autocomplete_param_with_ac(const char *const input, char *command, Autocomplete } char* -autocomplete_param_no_with_func(const char *const input, char *command, int arg_number, autocomplete_func func) +autocomplete_param_no_with_func(const char *const input, char *command, int arg_number, autocomplete_func func, gboolean previous) { if (strncmp(input, command, strlen(command)) == 0) { GString *result_str = NULL; @@ -311,7 +330,7 @@ autocomplete_param_no_with_func(const char *const input, char *command, int arg_ // autocomplete param if (comp_str) { - char *found = func(comp_str); + char *found = func(comp_str, previous); if (found) { result_str = g_string_new(""); g_string_append(result_str, start_str); @@ -328,12 +347,19 @@ autocomplete_param_no_with_func(const char *const input, char *command, int arg_ } static gchar* -_search_from(Autocomplete ac, GSList *curr, gboolean quote) +_search_next(Autocomplete ac, GList *curr, gboolean quote) { + gchar *search_str_ascii = g_str_to_ascii(ac->search_str, NULL); + gchar *search_str_lower = g_ascii_strdown(search_str_ascii, -1); + g_free(search_str_ascii); + while(curr) { + gchar *curr_ascii = g_str_to_ascii(curr->data, NULL); + gchar *curr_lower = g_ascii_strdown(curr_ascii, -1); + g_free(curr_ascii); // match found - if (strncmp(curr->data, ac->search_str, strlen(ac->search_str)) == 0) { + if (strncmp(curr_lower, search_str_lower, strlen(search_str_lower)) == 0) { // set pointer to last found ac->last_found = curr; @@ -347,16 +373,69 @@ _search_from(Autocomplete ac, GSList *curr, gboolean quote) gchar *result = quoted->str; g_string_free(quoted, FALSE); + g_free(search_str_lower); + g_free(curr_lower); return result; // otherwise just return the string } else { + g_free(search_str_lower); + g_free(curr_lower); return strdup(curr->data); } } - curr = g_slist_next(curr); + g_free(curr_lower); + curr = g_list_next(curr); } + g_free(search_str_lower); + return NULL; +} + +static gchar* +_search_prev(Autocomplete ac, GList *curr, gboolean quote) +{ + gchar *search_str_ascii = g_str_to_ascii(ac->search_str, NULL); + gchar *search_str_lower = g_ascii_strdown(search_str_ascii, -1); + g_free(search_str_ascii); + + while(curr) { + gchar *curr_ascii = g_str_to_ascii(curr->data, NULL); + gchar *curr_lower = g_ascii_strdown(curr_ascii, -1); + g_free(curr_ascii); + + // match found + if (strncmp(curr_lower, search_str_lower, strlen(search_str_lower)) == 0) { + + // set pointer to last found + ac->last_found = curr; + + // if contains space, quote before returning + if (quote && g_strrstr(curr->data, " ")) { + GString *quoted = g_string_new("\""); + g_string_append(quoted, curr->data); + g_string_append(quoted, "\""); + + gchar *result = quoted->str; + g_string_free(quoted, FALSE); + + g_free(search_str_lower); + g_free(curr_lower); + return result; + + // otherwise just return the string + } else { + g_free(search_str_lower); + g_free(curr_lower); + return strdup(curr->data); + } + } + + g_free(curr_lower); + curr = g_list_previous(curr); + } + + g_free(search_str_lower); return NULL; } diff --git a/src/tools/autocomplete.h b/src/tools/autocomplete.h index bead7f12..f62309ba 100644 --- a/src/tools/autocomplete.h +++ b/src/tools/autocomplete.h @@ -37,7 +37,7 @@ #include -typedef char* (*autocomplete_func)(const char *const); +typedef char* (*autocomplete_func)(const char *const, gboolean); typedef struct autocomplete_t *Autocomplete; // allocate new autocompleter with no items @@ -55,19 +55,19 @@ void autocomplete_remove(Autocomplete ac, const char *const item); void autocomplete_remove_all(Autocomplete ac, char **items); // find the next item prefixed with search string -gchar* autocomplete_complete(Autocomplete ac, const gchar *search_str, gboolean quote); +gchar* autocomplete_complete(Autocomplete ac, const gchar *search_str, gboolean quote, gboolean previous); -GSList* autocomplete_create_list(Autocomplete ac); +GList* autocomplete_create_list(Autocomplete ac); gint autocomplete_length(Autocomplete ac); char* autocomplete_param_with_func(const char *const input, char *command, - autocomplete_func func); + autocomplete_func func, gboolean previous); char* autocomplete_param_with_ac(const char *const input, char *command, - Autocomplete ac, gboolean quote); + Autocomplete ac, gboolean quote, gboolean previous); char* autocomplete_param_no_with_func(const char *const input, char *command, - int arg_number, autocomplete_func func); + int arg_number, autocomplete_func func, gboolean previous); void autocomplete_reset(Autocomplete ac); diff --git a/src/ui/console.c b/src/ui/console.c index 64f44c52..cb5a10b0 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -142,7 +142,7 @@ cons_show_help(const char *const cmd, CommandHelp *help) if (g_strv_length((gchar**)help->examples) > 0) { cons_show(""); - win_println(console, THEME_HELP_HEADER, '-', "Arguments"); + win_println(console, THEME_HELP_HEADER, '-', "Examples"); ui_show_lines(console, help->examples); } } @@ -505,7 +505,7 @@ cons_show_wins(gboolean unread) } void -cons_show_room_invites(GSList *invites) +cons_show_room_invites(GList *invites) { cons_show(""); if (invites == NULL) { @@ -514,7 +514,7 @@ cons_show_room_invites(GSList *invites) cons_show("Chat room invites, use /join or /decline commands:"); while (invites) { cons_show(" %s", invites->data); - invites = g_slist_next(invites); + invites = g_list_next(invites); } } @@ -608,17 +608,17 @@ cons_show_caps(const char *const fulljid, resource_presence_t presence) void cons_show_received_subs(void) { - GSList *received = presence_get_subscription_requests(); + GList *received = presence_get_subscription_requests(); if (received == NULL) { cons_show("No outstanding subscription requests."); } else { cons_show("Outstanding subscription requests from:", - g_slist_length(received)); + g_list_length(received)); while (received) { cons_show(" %s", received->data); - received = g_slist_next(received); + received = g_list_next(received); } - g_slist_free_full(received, g_free); + g_list_free_full(received, g_free); } cons_alert(); @@ -2224,6 +2224,7 @@ cons_theme_properties(void) _cons_theme_bar_prop(THEME_STATUS_BRACKET, "statusbar.brackets"); _cons_theme_bar_prop(THEME_STATUS_ACTIVE, "statusbar.active"); _cons_theme_bar_prop(THEME_STATUS_NEW, "statusbar.new"); + _cons_theme_bar_prop(THEME_STATUS_TIME, "statusbar.time"); _cons_theme_prop(THEME_TIME, "main.time"); _cons_theme_prop(THEME_TEXT, "main.text"); diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c index 9084b2a6..58a4d7d9 100644 --- a/src/ui/inputwin.c +++ b/src/ui/inputwin.c @@ -96,6 +96,7 @@ static void _inp_rl_addfuncs(void); static int _inp_rl_getc(FILE *stream); static void _inp_rl_linehandler(char *line); static int _inp_rl_tab_handler(int count, int key); +static int _inp_rl_shift_tab_handler(int count, int key); static int _inp_rl_win_clear_handler(int count, int key); static int _inp_rl_win_1_handler(int count, int key); static int _inp_rl_win_2_handler(int count, int key); @@ -429,6 +430,7 @@ _inp_rl_startup_hook(void) rl_bind_keyseq("\\el", _inp_rl_win_linedown_handler); rl_bind_key('\t', _inp_rl_tab_handler); + rl_bind_keyseq("\\e[Z", _inp_rl_shift_tab_handler); // unbind unwanted mappings rl_bind_keyseq("\\e=", NULL); @@ -457,10 +459,27 @@ _inp_rl_linehandler(char *line) inp_line = line; } +static gboolean shift_tab = FALSE; + static int _inp_rl_getc(FILE *stream) { int ch = rl_getc(stream); + + // 27, 91, 90 = Shift tab + if (ch == 27) { + shift_tab = TRUE; + return ch; + } + if (shift_tab && ch == 91) { + return ch; + } + if (shift_tab && ch == 90) { + return ch; + } + + shift_tab = FALSE; + if (_inp_printable(ch)) { ProfWin *window = wins_get_current(); cmd_ac_reset(window); @@ -485,7 +504,7 @@ _inp_rl_tab_handler(int count, int key) ProfWin *current = wins_get_current(); if ((strncmp(rl_line_buffer, "/", 1) != 0) && (current->type == WIN_MUC)) { - char *result = muc_autocomplete(current, rl_line_buffer); + char *result = muc_autocomplete(current, rl_line_buffer, FALSE); if (result) { rl_replace_line(result, 1); rl_point = rl_end; @@ -493,7 +512,35 @@ _inp_rl_tab_handler(int count, int key) } } else if (strncmp(rl_line_buffer, "/", 1) == 0) { ProfWin *window = wins_get_current(); - char *result = cmd_ac_complete(window, rl_line_buffer); + char *result = cmd_ac_complete(window, rl_line_buffer, FALSE); + if (result) { + rl_replace_line(result, 1); + rl_point = rl_end; + free(result); + } + } + + return 0; +} + +static int +_inp_rl_shift_tab_handler(int count, int key) +{ + if (rl_point != rl_end || !rl_line_buffer) { + return 0; + } + + ProfWin *current = wins_get_current(); + if ((strncmp(rl_line_buffer, "/", 1) != 0) && (current->type == WIN_MUC)) { + char *result = muc_autocomplete(current, rl_line_buffer, TRUE); + if (result) { + rl_replace_line(result, 1); + rl_point = rl_end; + free(result); + } + } else if (strncmp(rl_line_buffer, "/", 1) == 0) { + ProfWin *window = wins_get_current(); + char *result = cmd_ac_complete(window, rl_line_buffer, TRUE); if (result) { rl_replace_line(result, 1); rl_point = rl_end; diff --git a/src/ui/rosterwin.c b/src/ui/rosterwin.c index 30dedea6..bbeaba21 100644 --- a/src/ui/rosterwin.c +++ b/src/ui/rosterwin.c @@ -138,13 +138,13 @@ rosterwin_roster(void) _rosterwin_contacts_by_presence(layout, "dnd", "Do not disturb"); _rosterwin_contacts_by_presence(layout, "offline", "Offline"); } else if (g_strcmp0(by, "group") == 0) { - GSList *groups = roster_get_groups(); - GSList *curr_group = groups; + GList *groups = roster_get_groups(); + GList *curr_group = groups; while (curr_group) { _rosterwin_contacts_by_group(layout, curr_group->data); - curr_group = g_slist_next(curr_group); + curr_group = g_list_next(curr_group); } - g_slist_free_full(groups, free); + g_list_free_full(groups, free); _rosterwin_contacts_by_group(layout, NULL); } else { _rosterwin_contacts_all(layout); diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c index d19b5618..7998d7b4 100644 --- a/src/ui/statusbar.c +++ b/src/ui/statusbar.c @@ -459,6 +459,7 @@ _status_bar_draw(void) last_time = g_date_time_new_now(tz); int bracket_attrs = theme_attrs(THEME_STATUS_BRACKET); + int time_attrs = theme_attrs(THEME_STATUS_TIME); char *time_pref = prefs_get_string(PREF_TIME_STATUSBAR); if (g_strcmp0(time_pref, "off") != 0) { @@ -468,7 +469,9 @@ _status_bar_draw(void) wattron(status_bar, bracket_attrs); mvwaddch(status_bar, 0, 1, '['); wattroff(status_bar, bracket_attrs); + wattron(status_bar, time_attrs); mvwprintw(status_bar, 0, 2, date_fmt); + wattroff(status_bar, time_attrs); wattron(status_bar, bracket_attrs); mvwaddch(status_bar, 0, 2 + len, ']'); wattroff(status_bar, bracket_attrs); diff --git a/src/ui/ui.h b/src/ui/ui.h index a04dc9e6..c2c6a969 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -278,7 +278,7 @@ void cons_show_incoming_room_message(const char *const nick, const char *const r gboolean mention, GList *triggers, int unread); void cons_show_incoming_message(const char *const short_from, const int win_index, int unread); void cons_show_incoming_private_message(const char *const nick, const char *const room, const int win_index, int unread); -void cons_show_room_invites(GSList *invites); +void cons_show_room_invites(GList *invites); void cons_show_received_subs(void); void cons_show_sent_subs(void); void cons_alert(void); diff --git a/src/ui/window_list.c b/src/ui/window_list.c index cf16dbab..2d19ab32 100644 --- a/src/ui/window_list.c +++ b/src/ui/window_list.c @@ -1073,15 +1073,15 @@ wins_create_summary(gboolean unread) } char* -win_autocomplete(const char *const search_str) +win_autocomplete(const char *const search_str, gboolean previous) { - return autocomplete_complete(wins_ac, search_str, TRUE); + return autocomplete_complete(wins_ac, search_str, TRUE, previous); } char* -win_close_autocomplete(const char *const search_str) +win_close_autocomplete(const char *const search_str, gboolean previous) { - return autocomplete_complete(wins_close_ac, search_str, TRUE); + return autocomplete_complete(wins_close_ac, search_str, TRUE, previous); } void diff --git a/src/ui/window_list.h b/src/ui/window_list.h index 450175b7..dc1f3be4 100644 --- a/src/ui/window_list.h +++ b/src/ui/window_list.h @@ -91,9 +91,9 @@ gboolean wins_swap(int source_win, int target_win); void wins_hide_subwin(ProfWin *window); void wins_show_subwin(ProfWin *window); -char* win_autocomplete(const char *const search_str); +char* win_autocomplete(const char *const search_str, gboolean previous); void win_reset_search_attempts(void); -char* win_close_autocomplete(const char *const search_str); +char* win_close_autocomplete(const char *const search_str, gboolean previous); void win_close_reset_search_attempts(void); #endif diff --git a/src/xmpp/blocking.c b/src/xmpp/blocking.c index 05b80380..2a8fb316 100644 --- a/src/xmpp/blocking.c +++ b/src/xmpp/blocking.c @@ -92,9 +92,9 @@ blocked_list(void) } char* -blocked_ac_find(const char *const search_str) +blocked_ac_find(const char *const search_str, gboolean previous) { - return autocomplete_complete(blocked_ac, search_str, TRUE); + return autocomplete_complete(blocked_ac, search_str, TRUE, previous); } void diff --git a/src/xmpp/bookmark.c b/src/xmpp/bookmark.c index 84b5e4bb..99b2e20d 100644 --- a/src/xmpp/bookmark.c +++ b/src/xmpp/bookmark.c @@ -212,9 +212,9 @@ bookmark_get_list(void) } char* -bookmark_find(const char *const search_str) +bookmark_find(const char *const search_str, gboolean previous) { - return autocomplete_complete(bookmark_ac, search_str, TRUE); + return autocomplete_complete(bookmark_ac, search_str, TRUE, previous); } void diff --git a/src/xmpp/muc.c b/src/xmpp/muc.c index 7e926593..69cacba1 100644 --- a/src/xmpp/muc.c +++ b/src/xmpp/muc.c @@ -120,7 +120,7 @@ muc_invites_count(void) return autocomplete_length(invite_ac); } -GSList* +GList* muc_invites(void) { return autocomplete_create_list(invite_ac); @@ -135,17 +135,17 @@ muc_invite_password(const char *const room) gboolean muc_invites_contain(const char *const room) { - GSList *invites = autocomplete_create_list(invite_ac); - GSList *curr = invites; + GList *invites = autocomplete_create_list(invite_ac); + GList *curr = invites; while (curr) { if (strcmp(curr->data, room) == 0) { - g_slist_free_full(invites, g_free); + g_list_free_full(invites, g_free); return TRUE; } else { - curr = g_slist_next(curr); + curr = g_list_next(curr); } } - g_slist_free_full(invites, g_free); + g_list_free_full(invites, g_free); return FALSE; } @@ -157,9 +157,9 @@ muc_invites_reset_ac(void) } char* -muc_invites_find(const char *const search_str) +muc_invites_find(const char *const search_str, gboolean previous) { - return autocomplete_complete(invite_ac, search_str, TRUE); + return autocomplete_complete(invite_ac, search_str, TRUE, previous); } void @@ -663,7 +663,7 @@ muc_roster_nick_change_complete(const char *const room, const char *const nick) } char* -muc_autocomplete(ProfWin *window, const char *const input) +muc_autocomplete(ProfWin *window, const char *const input, gboolean previous) { if (window->type == WIN_MUC) { ProfMucWin *mucwin = (ProfMucWin*)window; @@ -686,7 +686,7 @@ muc_autocomplete(ProfWin *window, const char *const input) } } - char *result = autocomplete_complete(chat_room->nick_ac, search_str, FALSE); + char *result = autocomplete_complete(chat_room->nick_ac, search_str, FALSE, previous); if (result) { GString *replace_with = g_string_new(chat_room->autocomplete_prefix); g_string_append(replace_with, result); diff --git a/src/xmpp/muc.h b/src/xmpp/muc.h index fedabc2a..6c6408f3 100644 --- a/src/xmpp/muc.h +++ b/src/xmpp/muc.h @@ -120,10 +120,10 @@ char* muc_roster_nick_change_complete(const char *const room, const char *const void muc_invites_add(const char *const room, const char *const password); void muc_invites_remove(const char *const room); gint muc_invites_count(void); -GSList* muc_invites(void); +GList* muc_invites(void); gboolean muc_invites_contain(const char *const room); void muc_invites_reset_ac(void); -char* muc_invites_find(const char *const search_str); +char* muc_invites_find(const char *const search_str, gboolean previous); void muc_invites_clear(void); char* muc_invite_password(const char *const room); @@ -133,7 +133,7 @@ char* muc_subject(const char *const room); void muc_pending_broadcasts_add(const char *const room, const char *const message); GList* muc_pending_broadcasts(const char *const room); -char* muc_autocomplete(ProfWin *window, const char *const input); +char* muc_autocomplete(ProfWin *window, const char *const input, gboolean previous); void muc_autocomplete_reset(const char *const room); gboolean muc_requires_config(const char *const room); diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index f2772f59..97e3d461 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -141,7 +141,7 @@ presence_subscription(const char *const jid, const jabber_subscr_t action) xmpp_stanza_release(presence); } -GSList* +GList* presence_get_subscription_requests(void) { return autocomplete_create_list(sub_requests_ac); @@ -160,9 +160,9 @@ presence_clear_sub_requests(void) } char* -presence_sub_request_find(const char *const search_str) +presence_sub_request_find(const char *const search_str, gboolean previous) { - return autocomplete_complete(sub_requests_ac, search_str, TRUE); + return autocomplete_complete(sub_requests_ac, search_str, TRUE, previous); } gboolean @@ -170,16 +170,16 @@ presence_sub_request_exists(const char *const bare_jid) { gboolean result = FALSE; - GSList *requests = autocomplete_create_list(sub_requests_ac); - GSList *curr = requests; + GList *requests = autocomplete_create_list(sub_requests_ac); + GList *curr = requests; while (curr) { if (strcmp(curr->data, bare_jid) == 0) { result = TRUE; break; } - curr = g_slist_next(curr); + curr = g_list_next(curr); } - g_slist_free_full(requests, free); + g_list_free_full(requests, free); return result; } diff --git a/src/xmpp/roster_list.c b/src/xmpp/roster_list.c index 19d0ea06..839ea0b8 100644 --- a/src/xmpp/roster_list.c +++ b/src/xmpp/roster_list.c @@ -472,19 +472,19 @@ roster_has_pending_subscriptions(void) } char* -roster_contact_autocomplete(const char *const search_str) +roster_contact_autocomplete(const char *const search_str, gboolean previous) { assert(roster != NULL); - return autocomplete_complete(roster->name_ac, search_str, TRUE); + return autocomplete_complete(roster->name_ac, search_str, TRUE, previous); } char* -roster_fulljid_autocomplete(const char *const search_str) +roster_fulljid_autocomplete(const char *const search_str, gboolean previous) { assert(roster != NULL); - return autocomplete_complete(roster->fulljid_ac, search_str, TRUE); + return autocomplete_complete(roster->fulljid_ac, search_str, TRUE, previous); } GSList* @@ -526,7 +526,7 @@ roster_get_group(const char *const group, roster_ord_t order) return result; } -GSList* +GList* roster_get_groups(void) { assert(roster != NULL); @@ -535,19 +535,19 @@ roster_get_groups(void) } char* -roster_group_autocomplete(const char *const search_str) +roster_group_autocomplete(const char *const search_str, gboolean previous) { assert(roster != NULL); - return autocomplete_complete(roster->groups_ac, search_str, TRUE); + return autocomplete_complete(roster->groups_ac, search_str, TRUE, previous); } char* -roster_barejid_autocomplete(const char *const search_str) +roster_barejid_autocomplete(const char *const search_str, gboolean previous) { assert(roster != NULL); - return autocomplete_complete(roster->barejid_ac, search_str, TRUE); + return autocomplete_complete(roster->barejid_ac, search_str, TRUE, previous); } static gboolean diff --git a/src/xmpp/roster_list.h b/src/xmpp/roster_list.h index 971285c2..4e6b1d47 100644 --- a/src/xmpp/roster_list.h +++ b/src/xmpp/roster_list.h @@ -62,12 +62,12 @@ char* roster_barejid_from_name(const char *const name); GSList* roster_get_contacts(roster_ord_t order); GSList* roster_get_contacts_online(void); gboolean roster_has_pending_subscriptions(void); -char* roster_contact_autocomplete(const char *const search_str); -char* roster_fulljid_autocomplete(const char *const search_str); +char* roster_contact_autocomplete(const char *const search_str, gboolean previous); +char* roster_fulljid_autocomplete(const char *const search_str, gboolean previous); GSList* roster_get_group(const char *const group, roster_ord_t order); -GSList* roster_get_groups(void); -char* roster_group_autocomplete(const char *const search_str); -char* roster_barejid_autocomplete(const char *const search_str); +GList* roster_get_groups(void); +char* roster_group_autocomplete(const char *const search_str, gboolean previous); +char* roster_barejid_autocomplete(const char *const search_str, gboolean previous); GSList* roster_get_contacts_by_presence(const char *const presence); char* roster_get_msg_display_name(const char *const barejid, const char *const resource); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index dcbb7615..2befccd2 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -147,10 +147,10 @@ void message_send_gone(const char *const jid); void message_send_invite(const char *const room, const char *const contact, const char *const reason); void presence_subscription(const char *const jid, const jabber_subscr_t action); -GSList* presence_get_subscription_requests(void); +GList* presence_get_subscription_requests(void); gint presence_sub_request_count(void); void presence_reset_sub_request_search(void); -char* presence_sub_request_find(const char *const search_str); +char* presence_sub_request_find(const char *const search_str, gboolean previous); void presence_join_room(const char *const room, const char *const nick, const char *const passwd); void presence_change_room_nick(const char *const room, const char *const nick); void presence_leave_chat_room(const char *const room_jid); @@ -194,7 +194,7 @@ gboolean bookmark_update(const char *jid, const char *nick, const char *password gboolean bookmark_remove(const char *jid); gboolean bookmark_join(const char *jid); GList* bookmark_get_list(void); -char* bookmark_find(const char *const search_str); +char* bookmark_find(const char *const search_str, gboolean previous); void bookmark_autocomplete_reset(void); gboolean bookmark_exists(const char *const room); @@ -207,7 +207,7 @@ void roster_send_remove(const char *const barejid); GList* blocked_list(void); gboolean blocked_add(char *jid); gboolean blocked_remove(char *jid); -char* blocked_ac_find(const char *const search_str); +char* blocked_ac_find(const char *const search_str, gboolean previous); void blocked_ac_reset(void); void form_destroy(DataForm *form); diff --git a/tests/unittests/pgp/stub_gpg.c b/tests/unittests/pgp/stub_gpg.c index 02ccb4c8..edaab4e0 100644 --- a/tests/unittests/pgp/stub_gpg.c +++ b/tests/unittests/pgp/stub_gpg.c @@ -56,7 +56,7 @@ void p_gpg_free_keys(GHashTable *keys) {} void p_gpg_autocomplete_key_reset(void) {} -char * p_gpg_autocomplete_key(const char * const search_str) +char * p_gpg_autocomplete_key(const char * const search_str, gboolean previous) { return NULL; } diff --git a/tests/unittests/test_autocomplete.c b/tests/unittests/test_autocomplete.c index 2fd68b51..519973c4 100644 --- a/tests/unittests/test_autocomplete.c +++ b/tests/unittests/test_autocomplete.c @@ -24,7 +24,7 @@ void reset_after_create(void **state) void find_after_create(void **state) { Autocomplete ac = autocomplete_new(); - autocomplete_complete(ac, "hello", TRUE); + autocomplete_complete(ac, "hello", TRUE, FALSE); autocomplete_clear(ac); } @@ -43,7 +43,7 @@ void add_one_and_complete(void **state) { Autocomplete ac = autocomplete_new(); autocomplete_add(ac, "Hello"); - char *result = autocomplete_complete(ac, "Hel", TRUE); + char *result = autocomplete_complete(ac, "Hel", TRUE, FALSE); assert_string_equal("Hello", result); @@ -55,7 +55,7 @@ void add_two_and_complete_returns_first(void **state) Autocomplete ac = autocomplete_new(); autocomplete_add(ac, "Hello"); autocomplete_add(ac, "Help"); - char *result = autocomplete_complete(ac, "Hel", TRUE); + char *result = autocomplete_complete(ac, "Hel", TRUE, FALSE); assert_string_equal("Hello", result); @@ -67,8 +67,8 @@ void add_two_and_complete_returns_second(void **state) Autocomplete ac = autocomplete_new(); autocomplete_add(ac, "Hello"); autocomplete_add(ac, "Help"); - char *result1 = autocomplete_complete(ac, "Hel", TRUE); - char *result2 = autocomplete_complete(ac, result1, TRUE); + char *result1 = autocomplete_complete(ac, "Hel", TRUE, FALSE); + char *result2 = autocomplete_complete(ac, result1, TRUE, FALSE); assert_string_equal("Help", result2); @@ -117,3 +117,84 @@ void add_two_same_updates(void **state) autocomplete_clear(ac); g_slist_free_full(result, g_free); } + +void complete_accented_with_accented(void **state) +{ + Autocomplete ac = autocomplete_new(); + autocomplete_add(ac, "èâîô"); + + char *result = autocomplete_complete(ac, "èâ", TRUE, FALSE); + + assert_string_equal("èâîô", result); + + autocomplete_clear(ac); +} + +void complete_accented_with_base(void **state) +{ + Autocomplete ac = autocomplete_new(); + autocomplete_add(ac, "èâîô"); + + char *result = autocomplete_complete(ac, "ea", TRUE, FALSE); + + assert_string_equal("èâîô", result); + + autocomplete_clear(ac); +} + +void complete_both_with_accented(void **state) +{ + Autocomplete ac = autocomplete_new(); + autocomplete_add(ac, "eaooooo"); + autocomplete_add(ac, "èâîô"); + + char *result1 = autocomplete_complete(ac, "èâ", TRUE, FALSE); + char *result2 = autocomplete_complete(ac, result1, TRUE, FALSE); + + assert_string_equal("èâîô", result2); + + autocomplete_clear(ac); +} + +void complete_both_with_base(void **state) +{ + Autocomplete ac = autocomplete_new(); + autocomplete_add(ac, "eaooooo"); + autocomplete_add(ac, "èâîô"); + + char *result1 = autocomplete_complete(ac, "ea", TRUE, FALSE); + char *result2 = autocomplete_complete(ac, result1, TRUE, FALSE); + + assert_string_equal("èâîô", result2); + + autocomplete_clear(ac); +} + +void complete_ignores_case(void **state) +{ + Autocomplete ac = autocomplete_new(); + autocomplete_add(ac, "MyBuddy"); + + char *result = autocomplete_complete(ac, "myb", TRUE, FALSE); + + assert_string_equal("MyBuddy", result); + + autocomplete_clear(ac); +} + +void complete_previous(void **state) +{ + Autocomplete ac = autocomplete_new(); + autocomplete_add(ac, "MyBuddy1"); + autocomplete_add(ac, "MyBuddy2"); + autocomplete_add(ac, "MyBuddy3"); + + char *result1 = autocomplete_complete(ac, "myb", TRUE, FALSE); + char *result2 = autocomplete_complete(ac, result1, TRUE, FALSE); + char *result3 = autocomplete_complete(ac, result2, TRUE, FALSE); + char *result4 = autocomplete_complete(ac, result3, TRUE, TRUE); + + assert_string_equal("MyBuddy2", result4); + + autocomplete_clear(ac); +} diff --git a/tests/unittests/test_autocomplete.h b/tests/unittests/test_autocomplete.h index 4ad327c0..746ea2af 100644 --- a/tests/unittests/test_autocomplete.h +++ b/tests/unittests/test_autocomplete.h @@ -8,3 +8,9 @@ void add_two_and_complete_returns_second(void **state); void add_two_adds_two(void **state); void add_two_same_adds_one(void **state); void add_two_same_updates(void **state); +void complete_accented_with_accented(void **state); +void complete_accented_with_base(void **state); +void complete_both_with_accented(void **state); +void complete_both_with_base(void **state); +void complete_ignores_case(void **state); +void complete_previous(void **state); diff --git a/tests/unittests/test_roster_list.c b/tests/unittests/test_roster_list.c index c2c63a6b..5352e420 100644 --- a/tests/unittests/test_roster_list.c +++ b/tests/unittests/test_roster_list.c @@ -158,7 +158,7 @@ void find_first_exists(void **state) char *search = strdup("B"); - char *result = roster_contact_autocomplete(search); + char *result = roster_contact_autocomplete(search, FALSE); assert_string_equal("Bob", result); free(result); free(search); @@ -172,7 +172,7 @@ void find_second_exists(void **state) roster_add("Dave", NULL, NULL, NULL, FALSE); roster_add("Bob", NULL, NULL, NULL, FALSE); - char *result = roster_contact_autocomplete("Dav"); + char *result = roster_contact_autocomplete("Dav", FALSE); assert_string_equal("Dave", result); free(result); roster_destroy(); @@ -185,7 +185,7 @@ void find_third_exists(void **state) roster_add("Dave", NULL, NULL, NULL, FALSE); roster_add("Bob", NULL, NULL, NULL, FALSE); - char *result = roster_contact_autocomplete("Ja"); + char *result = roster_contact_autocomplete("Ja", FALSE); assert_string_equal("James", result); free(result); roster_destroy(); @@ -198,7 +198,7 @@ void find_returns_null(void **state) roster_add("Dave", NULL, NULL, NULL, FALSE); roster_add("Bob", NULL, NULL, NULL, FALSE); - char *result = roster_contact_autocomplete("Mike"); + char *result = roster_contact_autocomplete("Mike", FALSE); assert_null(result); roster_destroy(); } @@ -206,7 +206,7 @@ void find_returns_null(void **state) void find_on_empty_returns_null(void **state) { roster_create(); - char *result = roster_contact_autocomplete("James"); + char *result = roster_contact_autocomplete("James", FALSE); assert_null(result); roster_destroy(); } @@ -218,8 +218,8 @@ void find_twice_returns_second_when_two_match(void **state) roster_add("Jamie", NULL, NULL, NULL, FALSE); roster_add("Bob", NULL, NULL, NULL, FALSE); - char *result1 = roster_contact_autocomplete("Jam"); - char *result2 = roster_contact_autocomplete(result1); + char *result1 = roster_contact_autocomplete("Jam", FALSE); + char *result2 = roster_contact_autocomplete(result1, FALSE); assert_string_equal("Jamie", result2); free(result1); free(result2); @@ -240,11 +240,11 @@ void find_five_times_finds_fifth(void **state) roster_add("Jamy", NULL, NULL, NULL, FALSE); roster_add("Jamz", NULL, NULL, NULL, FALSE); - char *result1 = roster_contact_autocomplete("Jam"); - char *result2 = roster_contact_autocomplete(result1); - char *result3 = roster_contact_autocomplete(result2); - char *result4 = roster_contact_autocomplete(result3); - char *result5 = roster_contact_autocomplete(result4); + char *result1 = roster_contact_autocomplete("Jam", FALSE); + char *result2 = roster_contact_autocomplete(result1, FALSE); + char *result3 = roster_contact_autocomplete(result2, FALSE); + char *result4 = roster_contact_autocomplete(result3, FALSE); + char *result5 = roster_contact_autocomplete(result4, FALSE); assert_string_equal("Jamo", result5); free(result1); free(result2); @@ -261,9 +261,9 @@ void find_twice_returns_first_when_two_match_and_reset(void **state) roster_add("Jamie", NULL, NULL, NULL, FALSE); roster_add("Bob", NULL, NULL, NULL, FALSE); - char *result1 = roster_contact_autocomplete("Jam"); + char *result1 = roster_contact_autocomplete("Jam", FALSE); roster_reset_search_attempts(); - char *result2 = roster_contact_autocomplete(result1); + char *result2 = roster_contact_autocomplete(result1, FALSE); assert_string_equal("James", result2); free(result1); free(result2); diff --git a/tests/unittests/ui/stub_ui.c b/tests/unittests/ui/stub_ui.c index 7452e581..f2d8c5d7 100644 --- a/tests/unittests/ui/stub_ui.c +++ b/tests/unittests/ui/stub_ui.c @@ -408,7 +408,7 @@ void cons_check_version(gboolean not_available_msg) {} void cons_show_typing(const char * const barejid) {} void cons_show_incoming_room_message(const char *const nick, const char *const room, const int win_index, gboolean mention, GList *triggers, int unread) {} void cons_show_incoming_message(const char * const short_from, const int win_index, int unread) {} -void cons_show_room_invites(GSList *invites) {} +void cons_show_room_invites(GList *invites) {} void cons_show_received_subs(void) {} void cons_show_sent_subs(void) {} void cons_alert(void) {} diff --git a/tests/unittests/unittests.c b/tests/unittests/unittests.c index 71bdf1b1..41f99424 100644 --- a/tests/unittests/unittests.c +++ b/tests/unittests/unittests.c @@ -6,7 +6,9 @@ #include #include #include +#include #include +#include #include "config.h" #include "xmpp/chat_session.h" @@ -38,7 +40,21 @@ #include "test_plugins_disco.h" int main(int argc, char* argv[]) { - setlocale(LC_ALL, ""); + setlocale(LC_ALL, "en_GB.UTF-8"); + char *codeset = nl_langinfo(CODESET); + char *lang = getenv("LANG"); + + printf("Charset information:\n"); + + if (lang) { + printf(" LANG: %s\n", lang); + } + if (codeset) { + printf(" CODESET: %s\n", codeset); + } + printf(" MB_CUR_MAX: %d\n", MB_CUR_MAX); + printf(" MB_LEN_MAX: %d\n", MB_LEN_MAX); + const UnitTest all_tests[] = { unit_test(replace_one_substr), @@ -90,6 +106,12 @@ int main(int argc, char* argv[]) { unit_test(add_two_adds_two), unit_test(add_two_same_adds_one), unit_test(add_two_same_updates), + unit_test(complete_accented_with_accented), + unit_test(complete_accented_with_base), + unit_test(complete_both_with_accented), + unit_test(complete_both_with_base), + unit_test(complete_ignores_case), + unit_test(complete_previous), unit_test(create_jid_from_null_returns_null), unit_test(create_jid_from_empty_string_returns_null), diff --git a/tests/unittests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c index 38f7428e..630c0b19 100644 --- a/tests/unittests/xmpp/stub_xmpp.c +++ b/tests/unittests/xmpp/stub_xmpp.c @@ -128,7 +128,7 @@ void message_send_invite(const char * const room, const char * const contact, // presence functions void presence_subscription(const char * const jid, const jabber_subscr_t action) {} -GSList* presence_get_subscription_requests(void) +GList* presence_get_subscription_requests(void) { return NULL; } @@ -140,7 +140,7 @@ gint presence_sub_request_count(void) void presence_reset_sub_request_search(void) {} -char * presence_sub_request_find(const char * const search_str) +char * presence_sub_request_find(const char * const search_str, gboolean previous) { return NULL; } @@ -250,7 +250,7 @@ GList * bookmark_get_list(void) return (GList *)mock(); } -char * bookmark_find(const char * const search_str) +char * bookmark_find(const char * const search_str, gboolean previous) { return NULL; } @@ -298,7 +298,7 @@ gboolean blocked_remove(char *jid) return TRUE; } -char* blocked_ac_find(const char *const search_str) +char* blocked_ac_find(const char *const search_str, gboolean previous) { return NULL; }