/*
* cmd_ac.c
*
* Copyright (C) 2012 - 2016 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#define _GNU_SOURCE 1
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <libgen.h>
#include <dirent.h>
#include "common.h"
#include "config/preferences.h"
#include "config/scripts.h"
#include "command/cmd_ac.h"
#include "command/cmd_funcs.h"
#include "tools/parser.h"
#include "plugins/plugins.h"
#include "ui/win_types.h"
#include "ui/window_list.h"
#include "xmpp/muc.h"
#include "xmpp/xmpp.h"
#include "xmpp/roster_list.h"
#ifdef HAVE_LIBGPGME
#include "pgp/gpg.h"
#endif
static char* _complete_filepath(const char *const input, char *const startstr);
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* _titlebar_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* _script_autocomplete_func(const char *const prefix);
static char* _cmd_ac_complete_params(ProfWin *window, const char *const input);
static Autocomplete commands_ac;
static Autocomplete who_room_ac;
static Autocomplete who_roster_ac;
static Autocomplete help_ac;
static Autocomplete help_commands_ac;
static Autocomplete notify_ac;
static Autocomplete notify_chat_ac;
static Autocomplete notify_room_ac;
static Autocomplete notify_typing_ac;
static Autocomplete notify_mention_ac;
static Autocomplete notify_trigger_ac;
static Autocomplete prefs_ac;
static Autocomplete sub_ac;
static Autocomplete log_ac;
static Autocomplete autoaway_ac;
static Autocomplete autoaway_mode_ac;
static Autocomplete autoaway_presence_ac;
static Autocomplete autoconnect_ac;
static Autocomplete titlebar_ac;
static Autocomplete theme_ac;
static Autocomplete theme_load_ac;
static Autocomplete account_ac;
static Autocomplete account_set_ac;
static Autocomplete account_clear_ac;
static Autocomplete account_default_ac;
static Autocomplete account_status_ac;
static Autocomplete disco_ac;
static Autocomplete wins_ac;
static Autocomplete roster_ac;
static Autocomplete roster_show_ac;
static Autocomplete roster_by_ac;
static Autocomplete roster_count_ac;
static Autocomplete roster_order_ac;
static Autocomplete roster_header_ac;
static Autocomplete roster_contact_ac;
static Autocomplete roster_resource_ac;
static Autocomplete roster_presence_ac;
static Autocomplete roster_char_ac;
static Autocomplete roster_remove_all_ac;
static Autocomplete roster_room_ac;
static Autocomplete roster_room_position_ac;
static Autocomplete roster_room_by_ac;
static Autocomplete roster_room_order_ac;
static Autocomplete roster_unread_ac;
static Autocomplete roster_private_ac;
static Autocomplete group_ac;
static Autocomplete bookmark_ac;
static Autocomplete bookmark_property_ac;
static Autocomplete otr_ac;
static Autocomplete otr_log_ac;
static Autocomplete otr_policy_ac;
static Autocomplete connect_property_ac;
static Autocomplete tls_property_ac;
static Autocomplete alias_ac;
static Autocomplete aliases_ac;
static Autocomplete join_property_ac;
static Autocomplete room_ac;
static Autocomplete affiliation_ac;
static Autocomplete role_ac;
static Autocomplete privilege_cmd_ac;
static Autocomplete subject_ac;
static Autocomplete form_ac;
static Autocomplete form_field_multi_ac;
static Autocomplete occupants_ac;
static Autocomplete occupants_default_ac;
static Autocomplete occupants_show_ac;
static Autocomplete time_ac;
static Autocomplete time_format_ac;
static Autocomplete resource_ac;
static Autocomplete inpblock_ac;
static Autocomplete receipts_ac;
static Autocomplete pgp_ac;
static Autocomplete pgp_log_ac;
static Autocomplete tls_ac;
static Autocomplete tls_certpath_ac;
static Autocomplete script_ac;
static Autocomplete script_show_ac;
static Autocomplete console_ac;
static Autocomplete console_msg_ac;
static Autocomplete autoping_ac;
static Autocomplete plugins_ac;
static Autocomplete plugins_load_ac;
static Autocomplete plugins_unload_ac;
static Autocomplete plugins_reload_ac;
static Autocomplete filepath_ac;
static Autocomplete blocked_ac;
static Autocomplete tray_ac;
static Autocomplete presence_ac;
static Autocomplete presence_setting_ac;
void
cmd_ac_init(void)
{
commands_ac = autocomplete_new();
aliases_ac = autocomplete_new();
help_ac = autocomplete_new();
autocomplete_add(help_ac, "commands");
autocomplete_add(help_ac, "navigation");
help_commands_ac = autocomplete_new();
autocomplete_add(help_commands_ac, "chat");
autocomplete_add(help_commands_ac, "groupchat");
autocomplete_add(help_commands_ac, "roster");
autocomplete_add(help_commands_ac, "presence");
autocomplete_add(help_commands_ac, "discovery");
autocomplete_add(help_commands_ac, "connection");
autocomplete_add(help_commands_ac, "ui");
autocomplete_add(help_commands_ac, "plugins");
prefs_ac = autocomplete_new();
autocomplete_add(prefs_ac, "ui");
autocomplete_add(prefs_ac, "desktop");
autocomplete_add(prefs_ac, "chat");
autocomplete_add(prefs_ac, "log");
autocomplete_add(prefs_ac, "conn");
autocomplete_add(prefs_ac, "presence");
autocomplete_add(prefs_ac, "otr");
autocomplete_add(prefs_ac, "pgp");
notify_ac = autocomplete_new();
autocomplete_add(notify_ac, "chat");
autocomplete_add(notify_ac, "room");
autocomplete_add(notify_ac, "typing");
autocomplete_add(notify_ac, "remind");
autocomplete_add(notify_ac, "invite");
autocomplete_add(notify_ac, "sub");
autocomplete_add(notify_ac, "on");
autocomplete_add(notify_ac, "off");
autocomplete_add(notify_ac, "mention");
autocomplete_add(notify_ac, "trigger");
autocomplete_add(notify_ac, "reset");
notify_chat_ac = autocomplete_new();
autocomplete_add(notify_chat_ac, "on");
autocomplete_add(notify_chat_ac, "off");
autocomplete_add(notify_chat_ac, "current");
autocomplete_add(notify_chat_ac, "text");
notify_room_ac = autocomplete_new();
autocomplete_add(notify_room_ac, "on");
autocomplete_add(notify_room_ac, "off");
autocomplete_add(notify_room_ac, "mention");
autocomplete_add(notify_room_ac, "current");
autocomplete_add(notify_room_ac, "text");
autocomplete_add(notify_room_ac, "trigger");
notify_typing_ac = autocomplete_new();
autocomplete_add(notify_typing_ac, "on");
autocomplete_add(notify_typing_ac, "off");
autocomplete_add(notify_typing_ac, "current");
notify_mention_ac = autocomplete_new();
autocomplete_add(notify_mention_ac, "on");
autocomplete_add(notify_mention_ac, "off");
autocomplete_add(notify_mention_ac, "case_sensitive");
autocomplete_add(notify_mention_ac, "case_insensitive");
autocomplete_add(notify_mention_ac, "word_whole");
autocomplete_add(notify_mention_ac, "word_part");
notify_trigger_ac = autocomplete_new();
autocomplete_add(notify_trigger_ac, "add");
autocomplete_add(notify_trigger_ac, "remove");
autocomplete_add(notify_trigger_ac, "list");
autocomplete_add(notify_trigger_ac, "on");
autocomplete_add(notify_trigger_ac, "off");
sub_ac = autocomplete_new();
autocomplete_add(sub_ac, "request");
autocomplete_add(sub_ac, "allow");
autocomplete_add(sub_ac, "deny");
autocomplete_add(sub_ac, "show");
autocomplete_add(sub_ac, "sent");
autocomplete_add(sub_ac, "received");
titlebar_ac = autocomplete_new();
autocomplete_add(titlebar_ac, "show");
autocomplete_add(titlebar_ac, "goodbye");
log_ac = autocomplete_new();
autocomplete_add(log_ac, "maxsize");
autocomplete_add(log_ac, "rotate");
autocomplete_add(log_ac, "shared");
autocomplete_add(log_ac, "where");
autoaway_ac = autocomplete_new();
autocomplete_add(autoaway_ac, "mode");
autocomplete_add(autoaway_ac, "time");
autocomplete_add(autoaway_ac, "message");
autocomplete_add(autoaway_ac, "check");
autoaway_mode_ac = autocomplete_new();
autocomplete_add(autoaway_mode_ac, "away");
autocomplete_add(autoaway_mode_ac, "idle");
autocomplete_add(autoaway_mode_ac, "off");
autoaway_presence_ac = autocomplete_new();
autocomplete_add(autoaway_presence_ac, "away");
autocomplete_add(autoaway_presence_ac, "xa");
autoconnect_ac = autocomplete_new();
autocomplete_add(autoconnect_ac, "set");
autocomplete_add(autoconnect_ac, "off");
theme_ac = autocomplete_new();
autocomplete_add(theme_ac, "load");
autocomplete_add(theme_ac, "list");
autocomplete_add(theme_ac, "colours");
autocomplete_add(theme_ac, "properties");
disco_ac = autocomplete_new();
autocomplete_add(disco_ac, "info");
autocomplete_add(disco_ac, "items");
account_ac = autocomplete_new();
autocomplete_add(account_ac, "list");
autocomplete_add(account_ac, "show");
autocomplete_add(account_ac, "add");
autocomplete_add(account_ac, "remove");
autocomplete_add(account_ac, "enable");
autocomplete_add(account_ac, "disable");
autocomplete_add(account_ac, "default");
autocomplete_add(account_ac, "rename");
autocomplete_add(account_ac, "set");
autocomplete_add(account_ac, "clear");
account_set_ac = autocomplete_new();
autocomplete_add(account_set_ac, "jid");
autocomplete_add(account_set_ac, "server");
autocomplete_add(account_set_ac, "port");
autocomplete_add(account_set_ac, "status");
autocomplete_add(account_set_ac, "online");
autocomplete_add(account_set_ac, "chat");
autocomplete_add(account_set_ac, "away");
autocomplete_add(account_set_ac, "xa");
autocomplete_add(account_set_ac, "dnd");
autocomplete_add(account_set_ac, "resource");
autocomplete_add(account_set_ac, "password");
autocomplete_add(account_set_ac, "eval_password");
autocomplete_add(account_set_ac, "muc");
autocomplete_add(account_set_ac, "nick");
autocomplete_add(account_set_ac, "otr");
autocomplete_add(account_set_ac, "pgpkeyid");
autocomplete_add(account_set_ac, "startscript");
autocomplete_add(account_set_ac, "tls");
autocomplete_add(account_set_ac, "theme");
account_clear_ac = autocomplete_new();
autocomplete_add(account_clear_ac, "password");
autocomplete_add(account_clear_ac, "eval_password");
autocomplete_add(account_clear_ac, "server");
autocomplete_add(account_clear_ac, "port");
autocomplete_add(account_clear_ac, "otr");
autocomplete_add(account_clear_ac, "pgpkeyid");
autocomplete_add(account_clear_ac, "startscript");
autocomplete_add(account_clear_ac, "theme");
account_default_ac = autocomplete_new();
autocomplete_add(account_default_ac, "set");
autocomplete_add(account_default_ac, "off");
account_status_ac = autocomplete_new();
autocomplete_add(account_status_ac, "online");
autocomplete_add(account_status_ac, "chat");
autocomplete_add(account_status_ac, "away");
autocomplete_add(account_status_ac, "xa");
autocomplete_add(account_status_ac, "dnd");
autocomplete_add(account_status_ac, "last");
wins_ac = autocomplete_new();
autocomplete_add(wins_ac, "unread");
autocomplete_add(wins_ac, "prune");
autocomplete_add(wins_ac, "tidy");
autocomplete_add(wins_ac, "autotidy");
autocomplete_add(wins_ac, "swap");
roster_ac = autocomplete_new();
autocomplete_add(roster_ac, "add");
autocomplete_add(roster_ac, "online");
autocomplete_add(roster_ac, "nick");
autocomplete_add(roster_ac, "clearnick");
autocomplete_add(roster_ac, "remove");
autocomplete_add(roster_ac, "remove_all");
autocomplete_add(roster_ac, "show");
autocomplete_add(roster_ac, "hide");
autocomplete_add(roster_ac, "by");
autocomplete_add(roster_ac, "count");
autocomplete_add(roster_ac, "order");
autocomplete_add(roster_ac, "unread");
autocomplete_add(roster_ac, "room");
autocomplete_add(roster_ac, "size");
autocomplete_add(roster_ac, "wrap");
autocomplete_add(roster_ac, "header");
autocomplete_add(roster_ac, "contact");
autocomplete_add(roster_ac, "resource");
autocomplete_add(roster_ac, "presence");
autocomplete_add(roster_ac, "private");
roster_private_ac = autocomplete_new();
autocomplete_add(roster_private_ac, "room");
autocomplete_add(roster_private_ac, "group");
autocomplete_add(roster_private_ac, "off");
autocomplete_add(roster_private_ac, "char");
roster_header_ac = autocomplete_new();
autocomplete_add(roster_header_ac, "char");
roster_contact_ac = autocomplete_new();
autocomplete_add(roster_contact_ac, "char");
autocomplete_add(roster_contact_ac, "indent");
roster_resource_ac = autocomplete_new();
autocomplete_add(roster_resource_ac, "char");
autocomplete_add(roster_resource_ac, "indent");
autocomplete_add(roster_resource_ac, "join");
roster_presence_ac = autocomplete_new();
autocomplete_add(roster_presence_ac, "indent");
roster_char_ac = autocomplete_new();
autocomplete_add(roster_char_ac, "none");
roster_show_ac = autocomplete_new();
autocomplete_add(roster_show_ac, "offline");
autocomplete_add(roster_show_ac, "resource");
autocomplete_add(roster_show_ac, "presence");
autocomplete_add(roster_show_ac, "status");
autocomplete_add(roster_show_ac, "empty");
autocomplete_add(roster_show_ac, "priority");
autocomplete_add(roster_show_ac, "contacts");
autocomplete_add(roster_show_ac, "unsubscribed");
autocomplete_add(roster_show_ac, "rooms");
roster_by_ac = autocomplete_new();
autocomplete_add(roster_by_ac, "group");
autocomplete_add(roster_by_ac, "presence");
autocomplete_add(roster_by_ac, "none");
roster_count_ac = autocomplete_new();
autocomplete_add(roster_count_ac, "unread");
autocomplete_add(roster_count_ac, "items");
autocomplete_add(roster_count_ac, "off");
autocomplete_add(roster_count_ac, "zero");
roster_order_ac = autocomplete_new();
autocomplete_add(roster_order_ac, "name");
autocomplete_add(roster_order_ac, "presence");
roster_unread_ac = autocomplete_new();
autocomplete_add(roster_unread_ac, "before");
autocomplete_add(roster_unread_ac, "after");
autocomplete_add(roster_unread_ac, "off");
roster_room_ac = autocomplete_new();
autocomplete_add(roster_room_ac, "char");
autocomplete_add(roster_room_ac, "position");
autocomplete_add(roster_room_ac, "by");
autocomplete_add(roster_room_ac, "order");
autocomplete_add(roster_room_ac, "unread");
autocomplete_add(roster_room_ac, "private");
roster_room_by_ac = autocomplete_new();
autocomplete_add(roster_room_by_ac, "service");
autocomplete_add(roster_room_by_ac, "none");
roster_room_order_ac = autocomplete_new();
autocomplete_add(roster_room_order_ac, "name");
autocomplete_add(roster_room_order_ac, "unread");
roster_room_position_ac = autocomplete_new();
autocomplete_add(roster_room_position_ac, "first");
autocomplete_add(roster_room_position_ac, "last");
roster_remove_all_ac = autocomplete_new();
autocomplete_add(roster_remove_all_ac, "contacts");
group_ac = autocomplete_new();
autocomplete_add(group_ac, "show");
autocomplete_add(group_ac, "add");
autocomplete_add(group_ac, "remove");
theme_load_ac = NULL;
plugins_load_ac = NULL;
plugins_unload_ac = NULL;
plugins_reload_ac = NULL;
who_roster_ac = autocomplete_new();
autocomplete_add(who_roster_ac, "chat");
autocomplete_add(who_roster_ac, "online");
autocomplete_add(who_roster_ac, "away");
autocomplete_add(who_roster_ac, "xa");
autocomplete_add(who_roster_ac, "dnd");
autocomplete_add(who_roster_ac, "offline");
autocomplete_add(who_roster_ac, "available");
autocomplete_add(who_roster_ac, "unavailable");
autocomplete_add(who_roster_ac, "any");
who_room_ac = autocomplete_new();
autocomplete_add(who_room_ac, "chat");
autocomplete_add(who_room_ac, "online");
autocomplete_add(who_room_ac, "away");
autocomplete_add(who_room_ac, "xa");
autocomplete_add(who_room_ac, "dnd");
autocomplete_add(who_room_ac, "available");
autocomplete_add(who_room_ac, "unavailable");
autocomplete_add(who_room_ac, "moderator");
autocomplete_add(who_room_ac, "participant");
autocomplete_add(who_room_ac, "visitor");
autocomplete_add(who_room_ac, "owner");
autocomplete_add(who_room_ac, "admin");
autocomplete_add(who_room_ac, "member");
bookmark_ac = autocomplete_new();
autocomplete_add(bookmark_ac, "list");
autocomplete_add(bookmark_ac, "add");
autocomplete_add(bookmark_ac, "update");
autocomplete_add(bookmark_ac, "remove");
autocomplete_add(bookmark_ac, "join");
autocomplete_add(bookmark_ac, "invites");
bookmark_property_ac = autocomplete_new();
autocomplete_add(bookmark_property_ac, "nick");
autocomplete_add(bookmark_property_ac, "password");
autocomplete_add(bookmark_property_ac, "autojoin");
otr_ac = autocomplete_new();
autocomplete_add(otr_ac, "gen");
autocomplete_add(otr_ac, "start");
autocomplete_add(otr_ac, "end");
autocomplete_add(otr_ac, "myfp");
autocomplete_add(otr_ac, "theirfp");
autocomplete_add(otr_ac, "trust");
autocomplete_add(otr_ac, "untrust");
autocomplete_add(otr_ac, "secret");
autocomplete_add(otr_ac, "log");
autocomplete_add(otr_ac, "libver");
autocomplete_add(otr_ac, "policy");
autocomplete_add(otr_ac, "question");
autocomplete_add(otr_ac, "answer");
autocomplete_add(otr_ac, "char");
otr_log_ac = autocomplete_new();
autocomplete_add(otr_log_ac, "on");
autocomplete_add(otr_log_ac, "off");
autocomplete_add(otr_log_ac, "redact");
otr_policy_ac = autocomplete_new();
autocomplete_add(otr_policy_ac, "manual");
autocomplete_add(otr_policy_ac, "opportunistic");
autocomplete_add(otr_policy_ac, "always");
connect_property_ac = autocomplete_new();
autocomplete_add(connect_property_ac, "server");
autocomplete_add(connect_property_ac, "port");
autocomplete_add(connect_property_ac, "tls");
tls_property_ac = autocomplete_new();
autocomplete_add(tls_property_ac, "force");
autocomplete_add(tls_property_ac, "allow");
autocomplete_add(tls_property_ac, "disable");
join_property_ac = autocomplete_new();
autocomplete_add(join_property_ac, "nick");
autocomplete_add(join_property_ac, "password");
alias_ac = autocomplete_new();
autocomplete_add(alias_ac, "add");
autocomplete_add(alias_ac, "remove");
autocomplete_add(alias_ac, "list");
room_ac = autocomplete_new();
autocomplete_add(room_ac, "accept");
autocomplete_add(room_ac, "destroy");
autocomplete_add(room_ac, "config");
affiliation_ac = autocomplete_new();
autocomplete_add(affiliation_ac, "owner");
autocomplete_add(affiliation_ac, "admin");
autocomplete_add(affiliation_ac, "member");
autocomplete_add(affiliation_ac, "none");
autocomplete_add(affiliation_ac, "outcast");
role_ac = autocomplete_new();
autocomplete_add(role_ac, "moderator");
autocomplete_add(role_ac, "participant");
autocomplete_add(role_ac, "visitor");
autocomplete_add(role_ac, "none");
privilege_cmd_ac = autocomplete_new();
autocomplete_add(privilege_cmd_ac, "list");
autocomplete_add(privilege_cmd_ac, "set");
subject_ac = autocomplete_new();
autocomplete_add(subject_ac, "set");
autocomplete_add(subject_ac, "edit");
autocomplete_add(subject_ac, "prepend");
autocomplete_add(subject_ac, "append");
autocomplete_add(subject_ac, "clear");
form_ac = autocomplete_new();
autocomplete_add(form_ac, "submit");
autocomplete_add(form_ac, "cancel");
autocomplete_add(form_ac, "show");
autocomplete_add(form_ac, "help");
form_field_multi_ac = autocomplete_new();
autocomplete_add(form_field_multi_ac, "add");
autocomplete_add(form_field_multi_ac, "remove");
occupants_ac = autocomplete_new();
autocomplete_add(occupants_ac, "show");
autocomplete_add(occupants_ac, "hide");
autocomplete_add(occupants_ac, "default");
autocomplete_add(occupants_ac, "size");
occupants_default_ac = autocomplete_new();
autocomplete_add(occupants_default_ac, "show");
autocomplete_add(occupants_default_ac, "hide");
occupants_show_ac = autocomplete_new();
autocomplete_add(occupants_show_ac, "jid");
time_ac = autocomplete_new();
autocomplete_add(time_ac, "console");
autocomplete_add(time_ac, "chat");
autocomplete_add(time_ac, "muc");
autocomplete_add(time_ac, "mucconfig");
autocomplete_add(time_ac, "private");
autocomplete_add(time_ac, "xml");
autocomplete_add(time_ac, "statusbar");
autocomplete_add(time_ac, "lastactivity");
time_format_ac = autocomplete_new();
autocomplete_add(time_format_ac, "set");
autocomplete_add(time_format_ac, "off");
resource_ac = autocomplete_new();
autocomplete_add(resource_ac, "set");
autocomplete_add(resource_ac, "off");
autocomplete_add(resource_ac, "title");
autocomplete_add(resource_ac, "message");
inpblock_ac = autocomplete_new();
autocomplete_add(inpblock_ac, "timeout");
autocomplete_add(inpblock_ac, "dynamic");
receipts_ac = autocomplete_new();
autocomplete_add(receipts_ac, "send");
autocomplete_add(receipts_ac, "request");
pgp_ac = autocomplete_new();
autocomplete_add(pgp_ac, "keys");
autocomplete_add(pgp_ac, "contacts");
autocomplete_add(pgp_ac, "setkey");
autocomplete_add(pgp_ac, "libver");
autocomplete_add(pgp_ac, "start");
autocomplete_add(pgp_ac, "end");
autocomplete_add(pgp_ac, "log");
autocomplete_add(pgp_ac, "char");
pgp_log_ac = autocomplete_new();
autocomplete_add(pgp_log_ac, "on");
autocomplete_add(pgp_log_ac, "off");
autocomplete_add(pgp_log_ac, "redact");
tls_ac = autocomplete_new();
autocomplete_add(tls_ac, "allow");
autocomplete_add(tls_ac, "always");
autocomplete_add(tls_ac, "deny");
autocomplete_add(tls_ac, "cert");
autocomplete_add(tls_ac, "trust");
autocomplete_add(tls_ac, "trusted");
autocomplete_add(tls_ac, "revoke");
autocomplete_add(tls_ac, "certpath");
autocomplete_add(tls_ac, "show");
tls_certpath_ac = autocomplete_new();
autocomplete_add(tls_certpath_ac, "set");
autocomplete_add(tls_certpath_ac, "clear");
script_ac = autocomplete_new();
autocomplete_add(script_ac, "run");
autocomplete_add(script_ac, "list");
autocomplete_add(script_ac, "show");
script_show_ac = NULL;
console_ac = autocomplete_new();
autocomplete_add(console_ac, "chat");
autocomplete_add(console_ac, "muc");
autocomplete_add(console_ac, "private");
console_msg_ac = autocomplete_new();
autocomplete_add(console_msg_ac, "all");
autocomplete_add(console_msg_ac, "first");
autocomplete_add(console_msg_ac, "none");
autoping_ac = autocomplete_new();
autocomplete_add(autoping_ac, "set");
autocomplete_add(autoping_ac, "timeout");
plugins_ac = autocomplete_new();
autocomplete_add(plugins_ac, "install");
autocomplete_add(plugins_ac, "load");
autocomplete_add(plugins_ac, "unload");
autocomplete_add(plugins_ac, "reload");
autocomplete_add(plugins_ac, "python_version");
filepath_ac = autocomplete_new();
blocked_ac = autocomplete_new();
autocomplete_add(blocked_ac, "add");
autocomplete_add(blocked_ac, "remove");
tray_ac = autocomplete_new();
autocomplete_add(tray_ac, "on");
autocomplete_add(tray_ac, "off");
autocomplete_add(tray_ac, "read");
autocomplete_add(tray_ac, "timer");
presence_ac = autocomplete_new();
autocomplete_add(presence_ac, "titlebar");
autocomplete_add(presence_ac, "console");
autocomplete_add(presence_ac, "chat");
autocomplete_add(presence_ac, "room");
presence_setting_ac = autocomplete_new();
autocomplete_add(presence_setting_ac, "all");
autocomplete_add(presence_setting_ac, "online");
autocomplete_add(presence_setting_ac, "none");
}
void
cmd_ac_add(const char *const value)
{
if (commands_ac) {
autocomplete_add(commands_ac, value);
}
}
void
cmd_ac_add_help(const char *const value)
{
if (help_ac) {
autocomplete_add(help_ac, value);
}
}
void
cmd_ac_add_cmd(Command *command)
{
autocomplete_add(commands_ac, command->cmd);
autocomplete_add(help_ac, command->cmd+1);
}
void
cmd_ac_add_alias(ProfAlias *alias)
{
GString *ac_alias = g_string_new("/");
g_string_append(ac_alias, alias->name);
autocomplete_add(commands_ac, ac_alias->str);
autocomplete_add(aliases_ac, alias->name);
g_string_free(ac_alias, TRUE);
}
void
cmd_ac_add_alias_value(char *value)
{
if (aliases_ac) {
autocomplete_add(aliases_ac, value);
}
}
void
cmd_ac_remove_alias_value(char *value)
{
if (aliases_ac) {
autocomplete_remove(aliases_ac, value);
}
}
void
cmd_ac_remove(const char *const value)
{
if (commands_ac) {
autocomplete_remove(commands_ac, value);
}
}
void
cmd_ac_remove_help(const char *const value)
{
if (help_ac) {
autocomplete_remove(help_ac, value);
}
}
gboolean
cmd_ac_exists(char *cmd)
{
if (commands_ac == NULL) {
return FALSE;
} else {
return autocomplete_contains(commands_ac, cmd);
}
}
void
cmd_ac_add_form_fields(DataForm *form)
{
if (form == NULL) {
return;
}
GSList *fields = autocomplete_create_list(form->tag_ac);
GSList *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);
}
g_slist_free_full(fields, free);
}
void
cmd_ac_remove_form_fields(DataForm *form)
{
if (form == NULL) {
return;
}
GSList *fields = autocomplete_create_list(form->tag_ac);
GSList *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);
}
g_slist_free_full(fields, free);
}
char*
cmd_ac_complete(ProfWin *window, const char *const input)
{
// autocomplete command
if ((strncmp(input, "/", 1) == 0) && (!str_contains(input, strlen(input), ' '))) {
char *found = NULL;
found = autocomplete_complete(commands_ac, input, TRUE);
if (found) {
return found;
}
// autocomplete parameters
} else {
char *found = _cmd_ac_complete_params(window, input);
if (found) {
return found;
}
}
return NULL;
}
void
cmd_ac_reset(ProfWin *window)
{
jabber_conn_status_t conn_status = connection_get_status();
if (conn_status == JABBER_CONNECTED) {
roster_reset_search_attempts();
if (window->type == WIN_CHAT) {
ProfChatWin *chatwin = (ProfChatWin*)window;
assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
PContact contact = roster_get_contact(chatwin->barejid);
if (contact) {
p_contact_resource_ac_reset(contact);
}
}
}
muc_invites_reset_ac();
accounts_reset_all_search();
accounts_reset_enabled_search();
tlscerts_reset_ac();
prefs_reset_boolean_choice();
presence_reset_sub_request_search();
#ifdef HAVE_LIBGPGME
p_gpg_autocomplete_key_reset();
#endif
autocomplete_reset(help_ac);
autocomplete_reset(help_commands_ac);
autocomplete_reset(notify_ac);
autocomplete_reset(notify_chat_ac);
autocomplete_reset(notify_room_ac);
autocomplete_reset(notify_typing_ac);
autocomplete_reset(notify_mention_ac);
autocomplete_reset(notify_trigger_ac);
autocomplete_reset(sub_ac);
autocomplete_reset(filepath_ac);
autocomplete_reset(who_room_ac);
autocomplete_reset(who_roster_ac);
autocomplete_reset(prefs_ac);
autocomplete_reset(log_ac);
autocomplete_reset(commands_ac);
autocomplete_reset(autoaway_ac);
autocomplete_reset(autoaway_mode_ac);
autocomplete_reset(autoaway_presence_ac);
autocomplete_reset(autoconnect_ac);
autocomplete_reset(theme_ac);
if (theme_load_ac) {
autocomplete_free(theme_load_ac);
theme_load_ac = NULL;
}
if (plugins_load_ac) {
autocomplete_free(plugins_load_ac);
plugins_load_ac = NULL;
}
if (plugins_unload_ac) {
autocomplete_free(plugins_unload_ac);
plugins_unload_ac = NULL;
}
if (plugins_reload_ac) {
autocomplete_free(plugins_reload_ac);
plugins_reload_ac = NULL;
}
autocomplete_reset(account_ac);
autocomplete_reset(account_set_ac);
autocomplete_reset(account_clear_ac);
autocomplete_reset(account_default_ac);
autocomplete_reset(account_status_ac);
autocomplete_reset(disco_ac);
autocomplete_reset(wins_ac);
autocomplete_reset(roster_ac);
autocomplete_reset(roster_header_ac);
autocomplete_reset(roster_contact_ac);
autocomplete_reset(roster_resource_ac);
autocomplete_reset(roster_presence_ac);
autocomplete_reset(roster_char_ac);
autocomplete_reset(roster_show_ac);
autocomplete_reset(roster_by_ac);
autocomplete_reset(roster_count_ac);
autocomplete_reset(roster_order_ac);
autocomplete_reset(roster_room_ac);
autocomplete_reset(roster_room_by_ac);
autocomplete_reset(roster_unread_ac);
autocomplete_reset(roster_room_position_ac);
autocomplete_reset(roster_room_order_ac);
autocomplete_reset(roster_remove_all_ac);
autocomplete_reset(roster_private_ac);
autocomplete_reset(group_ac);
autocomplete_reset(titlebar_ac);
autocomplete_reset(bookmark_ac);
autocomplete_reset(bookmark_property_ac);
autocomplete_reset(otr_ac);
autocomplete_reset(otr_log_ac);
autocomplete_reset(otr_policy_ac);
autocomplete_reset(connect_property_ac);
autocomplete_reset(tls_property_ac);
autocomplete_reset(alias_ac);
autocomplete_reset(aliases_ac);
autocomplete_reset(join_property_ac);
autocomplete_reset(room_ac);
autocomplete_reset(affiliation_ac);
autocomplete_reset(role_ac);
autocomplete_reset(privilege_cmd_ac);
autocomplete_reset(subject_ac);
autocomplete_reset(form_ac);
autocomplete_reset(form_field_multi_ac);
autocomplete_reset(occupants_ac);
autocomplete_reset(occupants_default_ac);
autocomplete_reset(occupants_show_ac);
autocomplete_reset(time_ac);
autocomplete_reset(time_format_ac);
autocomplete_reset(resource_ac);
autocomplete_reset(inpblock_ac);
autocomplete_reset(receipts_ac);
autocomplete_reset(pgp_ac);
autocomplete_reset(pgp_log_ac);
autocomplete_reset(tls_ac);
autocomplete_reset(tls_certpath_ac);
autocomplete_reset(console_ac);
autocomplete_reset(console_msg_ac);
autocomplete_reset(autoping_ac);
autocomplete_reset(plugins_ac);
autocomplete_reset(blocked_ac);
autocomplete_reset(tray_ac);
autocomplete_reset(presence_ac);
autocomplete_reset(presence_setting_ac);
autocomplete_reset(script_ac);
if (script_show_ac) {
autocomplete_free(script_show_ac);
script_show_ac = NULL;
}
if (window->type == WIN_MUC) {
ProfMucWin *mucwin = (ProfMucWin*)window;
assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
muc_autocomplete_reset(mucwin->roomjid);
muc_jid_autocomplete_reset(mucwin->roomjid);
}
if (window->type == WIN_MUC_CONFIG) {
ProfMucConfWin *confwin = (ProfMucConfWin*)window;
assert(confwin->memcheck == PROFCONFWIN_MEMCHECK);
if (confwin->form) {
form_reset_autocompleters(confwin->form);
}
}
bookmark_autocomplete_reset();
blocked_ac_reset();
prefs_reset_room_trigger_ac();
win_reset_search_attempts();
win_close_reset_search_attempts();
plugins_reset_autocomplete();
}
void
cmd_ac_uninit(void)
{
autocomplete_free(commands_ac);
autocomplete_free(who_room_ac);
autocomplete_free(who_roster_ac);
autocomplete_free(help_ac);
autocomplete_free(help_commands_ac);
autocomplete_free(notify_ac);
autocomplete_free(notify_chat_ac);
autocomplete_free(notify_room_ac);
autocomplete_free(notify_typing_ac);
autocomplete_free(notify_mention_ac);
autocomplete_free(notify_trigger_ac);
autocomplete_free(sub_ac);
autocomplete_free(titlebar_ac);
autocomplete_free(log_ac);
autocomplete_free(prefs_ac);
autocomplete_free(autoaway_ac);
autocomplete_free(autoaway_mode_ac);
autocomplete_free(autoaway_presence_ac);
autocomplete_free(autoconnect_ac);
autocomplete_free(theme_ac);
autocomplete_free(theme_load_ac);
autocomplete_free(account_ac);
autocomplete_free(account_set_ac);
autocomplete_free(account_clear_ac);
autocomplete_free(account_default_ac);
autocomplete_free(account_status_ac);
autocomplete_free(disco_ac);
autocomplete_free(wins_ac);
autocomplete_free(roster_ac);
autocomplete_free(roster_header_ac);
autocomplete_free(roster_contact_ac);
autocomplete_free(roster_resource_ac);
autocomplete_free(roster_presence_ac);
autocomplete_free(roster_char_ac);
autocomplete_free(roster_show_ac);
autocomplete_free(roster_by_ac);
autocomplete_free(roster_count_ac);
autocomplete_free(roster_order_ac);
autocomplete_free(roster_room_ac);
autocomplete_free(roster_room_by_ac);
autocomplete_free(roster_unread_ac);
autocomplete_free(roster_room_position_ac);
autocomplete_free(roster_room_order_ac);
autocomplete_free(roster_remove_all_ac);
autocomplete_free(roster_private_ac);
autocomplete_free(group_ac);
autocomplete_free(bookmark_ac);
autocomplete_free(bookmark_property_ac);
autocomplete_free(otr_ac);
autocomplete_free(otr_log_ac);
autocomplete_free(otr_policy_ac);
autocomplete_free(connect_property_ac);
autocomplete_free(tls_property_ac);
autocomplete_free(alias_ac);
autocomplete_free(aliases_ac);
autocomplete_free(join_property_ac);
autocomplete_free(room_ac);
autocomplete_free(affiliation_ac);
autocomplete_free(role_ac);
autocomplete_free(privilege_cmd_ac);
autocomplete_free(subject_ac);
autocomplete_free(form_ac);
autocomplete_free(form_field_multi_ac);
autocomplete_free(occupants_ac);
autocomplete_free(occupants_default_ac);
autocomplete_free(occupants_show_ac);
autocomplete_free(time_ac);
autocomplete_free(time_format_ac);
autocomplete_free(resource_ac);
autocomplete_free(inpblock_ac);
autocomplete_free(receipts_ac);
autocomplete_free(pgp_ac);
autocomplete_free(pgp_log_ac);
autocomplete_free(tls_ac);
autocomplete_free(tls_certpath_ac);
autocomplete_free(script_ac);
autocomplete_free(script_show_ac);
autocomplete_free(console_ac);
autocomplete_free(console_msg_ac);
autocomplete_free(autoping_ac);
autocomplete_free(plugins_ac);
autocomplete_free(plugins_load_ac);
autocomplete_free(plugins_unload_ac);
autocomplete_free(plugins_reload_ac);
autocomplete_free(filepath_ac);
autocomplete_free(blocked_ac);
autocomplete_free(tray_ac);
autocomplete_free(presence_ac);
autocomplete_free(presence_setting_ac);
}
static char*
_cmd_ac_complete_params(ProfWin *window, const char *const input)
{
int i;
char *result = NULL;
jabber_conn_status_t conn_status = connection_get_status();
// autocomplete boolean settings
gchar *boolean_choices[] = { "/beep", "/intype", "/states", "/outtype", "/flash", "/splash", "/chlog", "/grlog",
"/history", "/vercheck", "/privileges", "/wrap", "/winstidy", "/carbons", "/encwarn",
"/lastactivity" };
for (i = 0; i < ARRAY_SIZE(boolean_choices); i++) {
result = autocomplete_param_with_func(input, boolean_choices[i], prefs_autocomplete_boolean_choice);
if (result) {
return result;
}
}
// autocomplete nickname in chat rooms
if (window->type == WIN_MUC) {
ProfMucWin *mucwin = (ProfMucWin*)window;
assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
Autocomplete nick_ac = muc_roster_ac(mucwin->roomjid);
if (nick_ac) {
gchar *nick_choices[] = { "/msg", "/info", "/caps", "/status", "/software" } ;
// 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);
if (result) {
free(unquoted);
return result;
}
}
free(unquoted);
}
// otherwise autocomplete using roster
} else if (conn_status == JABBER_CONNECTED) {
gchar *contact_choices[] = { "/msg", "/info", "/status" };
// 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);
if (result) {
free(unquoted);
return result;
}
}
free(unquoted);
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);
if (result) {
return result;
}
}
}
if (conn_status == JABBER_CONNECTED) {
result = autocomplete_param_with_func(input, "/invite", roster_contact_autocomplete);
if (result) {
return result;
}
}
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);
if (result) {
return result;
}
}
gchar *cmds[] = { "/prefs", "/disco", "/room", "/autoping" };
Autocomplete completers[] = { prefs_ac, disco_ac, room_ac, autoping_ac };
for (i = 0; i < ARRAY_SIZE(cmds); i++) {
result = autocomplete_param_with_ac(input, cmds[i], completers[i], TRUE);
if (result) {
return result;
}
}
GHashTable *ac_funcs = g_hash_table_new(g_str_hash, g_str_equal);
g_hash_table_insert(ac_funcs, "/help", _help_autocomplete);
g_hash_table_insert(ac_funcs, "/who", _who_autocomplete);
g_hash_table_insert(ac_funcs, "/sub", _sub_autocomplete);
g_hash_table_insert(ac_funcs, "/notify", _notify_autocomplete);
g_hash_table_insert(ac_funcs, "/autoaway", _autoaway_autocomplete);
g_hash_table_insert(ac_funcs, "/theme", _theme_autocomplete);
g_hash_table_insert(ac_funcs, "/log", _log_autocomplete);
g_hash_table_insert(ac_funcs, "/account", _account_autocomplete);
g_hash_table_insert(ac_funcs, "/roster", _roster_autocomplete);
g_hash_table_insert(ac_funcs, "/group", _group_autocomplete);
g_hash_table_insert(ac_funcs, "/bookmark", _bookmark_autocomplete);
g_hash_table_insert(ac_funcs, "/autoconnect", _autoconnect_autocomplete);
g_hash_table_insert(ac_funcs, "/otr", _otr_autocomplete);
g_hash_table_insert(ac_funcs, "/pgp", _pgp_autocomplete);
g_hash_table_insert(ac_funcs, "/connect", _connect_autocomplete);
g_hash_table_insert(ac_funcs, "/alias", _alias_autocomplete);
g_hash_table_insert(ac_funcs, "/join", _join_autocomplete);
g_hash_table_insert(ac_funcs, "/form", _form_autocomplete);
g_hash_table_insert(ac_funcs, "/occupants", _occupants_autocomplete);
g_hash_table_insert(ac_funcs, "/kick", _kick_autocomplete);
g_hash_table_insert(ac_funcs, "/ban", _ban_autocomplete);
g_hash_table_insert(ac_funcs, "/affiliation", _affiliation_autocomplete);
g_hash_table_insert(ac_funcs, "/role", _role_autocomplete);
g_hash_table_insert(ac_funcs, "/resource", _resource_autocomplete);
g_hash_table_insert(ac_funcs, "/titlebar", _titlebar_autocomplete);
g_hash_table_insert(ac_funcs, "/inpblock", _inpblock_autocomplete);
g_hash_table_insert(ac_funcs, "/time", _time_autocomplete);
g_hash_table_insert(ac_funcs, "/receipts", _receipts_autocomplete);
g_hash_table_insert(ac_funcs, "/wins", _wins_autocomplete);
g_hash_table_insert(ac_funcs, "/tls", _tls_autocomplete);
g_hash_table_insert(ac_funcs, "/script", _script_autocomplete);
g_hash_table_insert(ac_funcs, "/subject", _subject_autocomplete);
g_hash_table_insert(ac_funcs, "/console", _console_autocomplete);
g_hash_table_insert(ac_funcs, "/win", _win_autocomplete);
g_hash_table_insert(ac_funcs, "/close", _close_autocomplete);
g_hash_table_insert(ac_funcs, "/plugins", _plugins_autocomplete);
g_hash_table_insert(ac_funcs, "/sendfile", _sendfile_autocomplete);
g_hash_table_insert(ac_funcs, "/blocked", _blocked_autocomplete);
g_hash_table_insert(ac_funcs, "/tray", _tray_autocomplete);
g_hash_table_insert(ac_funcs, "/presence", _presence_autocomplete);
int len = strlen(input);
char parsed[len+1];
i = 0;
while (i < len) {
if (input[i] == ' ') {
break;
} else {
parsed[i] = input[i];
}
i++;
}
parsed[i] = '\0';
char * (*ac_func)(ProfWin*, const char * const) = g_hash_table_lookup(ac_funcs, parsed);
if (ac_func) {
result = ac_func(window, input);
if (result) {
g_hash_table_destroy(ac_funcs);
return result;
}
}
g_hash_table_destroy(ac_funcs);
result = plugins_autocomplete(input);
if (result) {
return result;
}
if (g_str_has_prefix(input, "/field")) {
result = _form_field_autocomplete(window, input);
if (result) {
return result;
}
}
return NULL;
}
static char*
_sub_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_func(input, "/sub allow", presence_sub_request_find);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/sub deny", presence_sub_request_find);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/sub", sub_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_tray_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_func(input, "/tray read", prefs_autocomplete_boolean_choice);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/tray", tray_ac, FALSE);
if (result) {
return result;
}
return NULL;
}
static char*
_who_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
if (window->type == WIN_MUC) {
result = autocomplete_param_with_ac(input, "/who", who_room_ac, TRUE);
if (result) {
return result;
}
} else {
jabber_conn_status_t conn_status = connection_get_status();
if (conn_status == JABBER_CONNECTED) {
int i = 0;
gchar *group_commands[] = { "/who any", "/who online", "/who offline",
"/who chat", "/who away", "/who xa", "/who dnd", "/who available",
"/who unavailable" };
for (i = 0; i < ARRAY_SIZE(group_commands); i++) {
result = autocomplete_param_with_func(input, group_commands[i], roster_group_autocomplete);
if (result) {
return result;
}
}
}
result = autocomplete_param_with_ac(input, "/who", who_roster_ac, TRUE);
if (result) {
return result;
}
}
return result;
}
static char*
_roster_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_ac(input, "/roster room private char", roster_char_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster room private", roster_header_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster header char", roster_char_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster contact char", roster_char_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster room char", roster_char_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster private char", roster_char_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster resource char", roster_char_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/roster resource join", prefs_autocomplete_boolean_choice);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster room position", roster_room_position_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster room by", roster_room_by_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster room order", roster_room_order_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster room unread", roster_unread_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/roster count zero", prefs_autocomplete_boolean_choice);
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);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/roster clearnick", roster_barejid_autocomplete);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/roster remove", roster_barejid_autocomplete);
if (result) {
return result;
}
}
result = autocomplete_param_with_ac(input, "/roster remove_all", roster_remove_all_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster show", roster_show_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster hide", roster_show_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster by", roster_by_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster count", roster_count_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster order", roster_order_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster unread", roster_unread_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster room", roster_room_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/roster wrap", prefs_autocomplete_boolean_choice);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster header", roster_header_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster contact", roster_contact_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster resource", roster_resource_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster presence", roster_presence_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster private", roster_private_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/roster", roster_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_group_autocomplete(ProfWin *window, const char *const input)
{
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);
if (result) {
return result;
}
result = autocomplete_param_no_with_func(input, "/group add", 4, roster_contact_autocomplete);
if (result) {
return result;
}
result = autocomplete_param_no_with_func(input, "/group remove", 4, roster_contact_autocomplete);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/group add", roster_group_autocomplete);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/group remove", roster_group_autocomplete);
if (result) {
return result;
}
}
result = autocomplete_param_with_ac(input, "/group", group_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_blocked_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_func(input, "/blocked remove", blocked_ac_find);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/blocked", blocked_ac, FALSE);
if (result) {
return result;
}
return NULL;
}
static char*
_bookmark_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
gboolean result;
gchar **args = parse_args(input, 2, 8, &result);
if (result && ((strcmp(args[0], "add") == 0) || (strcmp(args[0], "update") == 0)) ) {
gboolean space_at_end = g_str_has_suffix(input, " ");
GString *beginning = g_string_new("/bookmark");
int num_args = g_strv_length(args);
if ((num_args == 2 && space_at_end) || (num_args == 3 && !space_at_end)) {
g_string_append_printf(beginning, " %s %s", args[0], args[1]);
found = autocomplete_param_with_ac(input, beginning->str, bookmark_property_ac, TRUE);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 3 && space_at_end && (g_strcmp0(args[2], "autojoin") == 0))
|| (num_args == 4 && (g_strcmp0(args[2], "autojoin") == 0) && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 4 && space_at_end) || (num_args == 5 && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 5 && space_at_end && (g_strcmp0(args[4], "autojoin") == 0))
|| (num_args == 6 && (g_strcmp0(args[4], "autojoin") == 0) && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 6 && space_at_end) || (num_args == 7 && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 7 && space_at_end && (g_strcmp0(args[6], "autojoin") == 0))
|| (num_args == 8 && (g_strcmp0(args[6], "autojoin") == 0) && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
}
g_strfreev(args);
found = autocomplete_param_with_func(input, "/bookmark remove", bookmark_find);
if (found) {
return found;
}
found = autocomplete_param_with_func(input, "/bookmark join", bookmark_find);
if (found) {
return found;
}
found = autocomplete_param_with_func(input, "/bookmark update", bookmark_find);
if (found) {
return found;
}
found = autocomplete_param_with_func(input, "/bookmark invites", prefs_autocomplete_boolean_choice);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/bookmark", bookmark_ac, TRUE);
return found;
}
static char*
_notify_autocomplete(ProfWin *window, const char *const input)
{
int i = 0;
char *result = NULL;
result = autocomplete_param_with_func(input, "/notify room trigger remove", prefs_autocomplete_room_trigger);
if (result) {
return result;
}
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);
if (result) {
return result;
}
}
result = autocomplete_param_with_ac(input, "/notify room mention", notify_mention_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/notify room trigger", notify_trigger_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/notify room", notify_room_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/notify chat", notify_chat_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/notify typing", notify_typing_ac, TRUE);
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);
if (result) {
return result;
}
}
result = autocomplete_param_with_ac(input, "/notify", notify_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_autoaway_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_ac(input, "/autoaway mode", autoaway_mode_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/autoaway time", autoaway_presence_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/autoaway message", autoaway_presence_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/autoaway check", prefs_autocomplete_boolean_choice);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/autoaway", autoaway_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_log_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_func(input, "/log rotate", prefs_autocomplete_boolean_choice);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/log shared", prefs_autocomplete_boolean_choice);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/log", log_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_autoconnect_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_func(input, "/autoconnect set", accounts_find_enabled);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/autoconnect", autoconnect_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_otr_autocomplete(ProfWin *window, const char *const input)
{
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);
if (found) {
return found;
}
}
found = autocomplete_param_with_ac(input, "/otr log", otr_log_ac, TRUE);
if (found) {
return found;
}
// /otr policy always user@server.com
if (conn_status == JABBER_CONNECTED) {
gboolean result;
gchar **args = parse_args(input, 2, 3, &result);
if (result && (strcmp(args[0], "policy") == 0)) {
GString *beginning = g_string_new("/otr ");
g_string_append(beginning, args[0]);
g_string_append(beginning, " ");
if (args[1]) {
g_string_append(beginning, args[1]);
}
found = autocomplete_param_with_func(input, beginning->str, roster_contact_autocomplete);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
g_strfreev(args);
}
found = autocomplete_param_with_ac(input, "/otr policy", otr_policy_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/otr", otr_ac, TRUE);
if (found) {
return found;
}
return NULL;
}
static char*
_pgp_autocomplete(ProfWin *window, const char *const input)
{
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);
if (found) {
return found;
}
}
found = autocomplete_param_with_ac(input, "/pgp log", pgp_log_ac, TRUE);
if (found) {
return found;
}
#ifdef HAVE_LIBGPGME
gboolean result;
gchar **args = parse_args(input, 2, 3, &result);
if ((strncmp(input, "/pgp", 4) == 0) && (result == TRUE)) {
GString *beginning = g_string_new("/pgp ");
g_string_append(beginning, args[0]);
if (args[1]) {
g_string_append(beginning, " ");
g_string_append(beginning, args[1]);
}
found = autocomplete_param_with_func(input, beginning->str, p_gpg_autocomplete_key);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
g_strfreev(args);
#endif
if (conn_status == JABBER_CONNECTED) {
found = autocomplete_param_with_func(input, "/pgp setkey", roster_barejid_autocomplete);
if (found) {
return found;
}
}
found = autocomplete_param_with_ac(input, "/pgp", pgp_ac, TRUE);
if (found) {
return found;
}
return NULL;
}
static char*
_plugins_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
if (strncmp(input, "/plugins install ", 17) == 0) {
return _complete_filepath(input, "/plugins install");
}
if (strncmp(input, "/plugins load ", 14) == 0) {
if (plugins_load_ac == NULL) {
plugins_load_ac = autocomplete_new();
GSList *plugins = plugins_unloaded_list();
GSList *curr = plugins;
while (curr) {
autocomplete_add(plugins_load_ac, curr->data);
curr = g_slist_next(curr);
}
g_slist_free_full(plugins, g_free);
}
result = autocomplete_param_with_ac(input, "/plugins load", plugins_load_ac, TRUE);
if (result) {
return result;
}
}
if (strncmp(input, "/plugins reload ", 16) == 0) {
if (plugins_reload_ac == NULL) {
plugins_reload_ac = autocomplete_new();
GList *plugins = plugins_loaded_list();
GList *curr = plugins;
while (curr) {
autocomplete_add(plugins_reload_ac, curr->data);
curr = g_list_next(curr);
}
g_list_free(plugins);
}
result = autocomplete_param_with_ac(input, "/plugins reload", plugins_reload_ac, TRUE);
if (result) {
return result;
}
}
if (strncmp(input, "/plugins unload ", 16) == 0) {
if (plugins_unload_ac == NULL) {
plugins_unload_ac = autocomplete_new();
GList *plugins = plugins_loaded_list();
GList *curr = plugins;
while (curr) {
autocomplete_add(plugins_unload_ac, curr->data);
curr = g_list_next(curr);
}
g_list_free(plugins);
}
result = autocomplete_param_with_ac(input, "/plugins unload", plugins_unload_ac, TRUE);
if (result) {
return result;
}
}
result = autocomplete_param_with_ac(input, "/plugins", plugins_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_theme_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
if (strncmp(input, "/theme load ", 12) == 0) {
if (theme_load_ac == NULL) {
theme_load_ac = autocomplete_new();
GSList *themes = theme_list();
GSList *curr = themes;
while (curr) {
autocomplete_add(theme_load_ac, curr->data);
curr = g_slist_next(curr);
}
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);
if (result) {
return result;
}
}
result = autocomplete_param_with_ac(input, "/theme", theme_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_script_autocomplete_func(const char *const prefix)
{
if (script_show_ac == NULL) {
script_show_ac = autocomplete_new();
GSList *scripts = scripts_list();
GSList *curr = scripts;
while (curr) {
autocomplete_add(script_show_ac, curr->data);
curr = g_slist_next(curr);
}
g_slist_free_full(scripts, g_free);
}
return autocomplete_complete(script_show_ac, prefix, FALSE);
}
static char*
_script_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
if (strncmp(input, "/script show ", 13) == 0) {
result = autocomplete_param_with_func(input, "/script show", _script_autocomplete_func);
if (result) {
return result;
}
}
if (strncmp(input, "/script run ", 12) == 0) {
result = autocomplete_param_with_func(input, "/script run", _script_autocomplete_func);
if (result) {
return result;
}
}
result = autocomplete_param_with_ac(input, "/script", script_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_resource_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
jabber_conn_status_t conn_status = connection_get_status();
if (conn_status == JABBER_CONNECTED && window->type == WIN_CHAT) {
ProfChatWin *chatwin = (ProfChatWin*)window;
assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
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);
if (found) {
return found;
}
}
}
found = autocomplete_param_with_func(input, "/resource title", prefs_autocomplete_boolean_choice);
if (found) {
return found;
}
found = autocomplete_param_with_func(input, "/resource message", prefs_autocomplete_boolean_choice);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/resource", resource_ac, FALSE);
if (found) {
return found;
}
return NULL;
}
static char*
_titlebar_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
found = autocomplete_param_with_func(input, "/titlebar show", prefs_autocomplete_boolean_choice);
if (found) {
return found;
}
found = autocomplete_param_with_func(input, "/titlebar goodbye", prefs_autocomplete_boolean_choice);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/titlebar", titlebar_ac, FALSE);
if (found) {
return found;
}
return NULL;
}
static char*
_inpblock_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
found = autocomplete_param_with_func(input, "/inpblock dynamic", prefs_autocomplete_boolean_choice);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/inpblock", inpblock_ac, FALSE);
if (found) {
return found;
}
return NULL;
}
static char*
_form_autocomplete(ProfWin *window, const char *const input)
{
if (window->type != WIN_MUC_CONFIG) {
return NULL;
}
char *found = NULL;
ProfMucConfWin *confwin = (ProfMucConfWin*)window;
DataForm *form = confwin->form;
if (form) {
found = autocomplete_param_with_ac(input, "/form help", form->tag_ac, TRUE);
if (found) {
return found;
}
}
found = autocomplete_param_with_ac(input, "/form", form_ac, TRUE);
if (found) {
return found;
}
return NULL;
}
static char*
_form_field_autocomplete(ProfWin *window, const char *const input)
{
if (window->type != WIN_MUC_CONFIG) {
return NULL;
}
char *found = NULL;
ProfMucConfWin *confwin = (ProfMucConfWin*)window;
DataForm *form = confwin->form;
if (form == NULL) {
return NULL;
}
gchar **split = g_strsplit(input, " ", 0);
if (g_strv_length(split) == 3) {
char *field_tag = split[0]+1;
if (form_tag_exists(form, field_tag)) {
form_field_type_t field_type = form_get_field_type(form, field_tag);
Autocomplete value_ac = form_get_value_ac(form, field_tag);;
GString *beginning = g_string_new(split[0]);
g_string_append(beginning, " ");
g_string_append(beginning, split[1]);
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);
} else if ((g_strcmp0(split[1], "remove") == 0) && field_type == FIELD_TEXT_MULTI) {
found = autocomplete_param_with_ac(input, beginning->str, value_ac, TRUE);
} else if ((g_strcmp0(split[1], "remove") == 0) && field_type == FIELD_JID_MULTI) {
found = autocomplete_param_with_ac(input, beginning->str, value_ac, TRUE);
}
g_string_free(beginning, TRUE);
}
} else if (g_strv_length(split) == 2) {
char *field_tag = split[0]+1;
if (form_tag_exists(form, field_tag)) {
form_field_type_t field_type = form_get_field_type(form, field_tag);
Autocomplete value_ac = form_get_value_ac(form, field_tag);;
switch (field_type)
{
case FIELD_BOOLEAN:
found = autocomplete_param_with_func(input, split[0], prefs_autocomplete_boolean_choice);
break;
case FIELD_LIST_SINGLE:
found = autocomplete_param_with_ac(input, split[0], value_ac, TRUE);
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);
break;
default:
break;
}
}
}
g_strfreev(split);
return found;
}
static char*
_occupants_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
found = autocomplete_param_with_ac(input, "/occupants default show", occupants_show_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/occupants default hide", occupants_show_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/occupants default", occupants_default_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/occupants show", occupants_show_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/occupants hide", occupants_show_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/occupants", occupants_ac, TRUE);
if (found) {
return found;
}
return NULL;
}
static char*
_time_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
found = autocomplete_param_with_ac(input, "/time statusbar", time_format_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/time lastactivity", time_format_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/time console", time_format_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/time chat", time_format_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/time muc", time_format_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/time mucconfig", time_format_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/time private", time_format_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/time xml", time_format_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/time", time_ac, TRUE);
if (found) {
return found;
}
return NULL;
}
static char*
_kick_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
if (window->type == WIN_MUC) {
ProfMucWin *mucwin = (ProfMucWin*)window;
assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
Autocomplete nick_ac = muc_roster_ac(mucwin->roomjid);
if (nick_ac) {
result = autocomplete_param_with_ac(input, "/kick", nick_ac, TRUE);
if (result) {
return result;
}
}
}
return result;
}
static char*
_ban_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
if (window->type == WIN_MUC) {
ProfMucWin *mucwin = (ProfMucWin*)window;
assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
Autocomplete jid_ac = muc_roster_jid_ac(mucwin->roomjid);
if (jid_ac) {
result = autocomplete_param_with_ac(input, "/ban", jid_ac, TRUE);
if (result) {
return result;
}
}
}
return result;
}
static char*
_affiliation_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
if (window->type == WIN_MUC) {
ProfMucWin *mucwin = (ProfMucWin*)window;
assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
gboolean parse_result;
Autocomplete jid_ac = muc_roster_jid_ac(mucwin->roomjid);
gchar **args = parse_args(input, 2, 3, &parse_result);
if ((strncmp(input, "/affiliation", 12) == 0) && (parse_result == TRUE)) {
GString *beginning = g_string_new("/affiliation ");
g_string_append(beginning, args[0]);
g_string_append(beginning, " ");
if (args[1]) {
g_string_append(beginning, args[1]);
}
result = autocomplete_param_with_ac(input, beginning->str, jid_ac, TRUE);
g_string_free(beginning, TRUE);
if (result) {
g_strfreev(args);
return result;
}
}
g_strfreev(args);
}
result = autocomplete_param_with_ac(input, "/affiliation set", affiliation_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/affiliation list", affiliation_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/affiliation", privilege_cmd_ac, TRUE);
if (result) {
return result;
}
return result;
}
static char*
_role_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
if (window->type == WIN_MUC) {
ProfMucWin *mucwin = (ProfMucWin*)window;
assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
gboolean parse_result;
Autocomplete nick_ac = muc_roster_ac(mucwin->roomjid);
gchar **args = parse_args(input, 2, 3, &parse_result);
if ((strncmp(input, "/role", 5) == 0) && (parse_result == TRUE)) {
GString *beginning = g_string_new("/role ");
g_string_append(beginning, args[0]);
g_string_append(beginning, " ");
if (args[1]) {
g_string_append(beginning, args[1]);
}
result = autocomplete_param_with_ac(input, beginning->str, nick_ac, TRUE);
g_string_free(beginning, TRUE);
if (result) {
g_strfreev(args);
return result;
}
}
g_strfreev(args);
}
result = autocomplete_param_with_ac(input, "/role set", role_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/role list", role_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/role", privilege_cmd_ac, TRUE);
if (result) {
return result;
}
return result;
}
static char*
_wins_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_func(input, "/wins autotidy", prefs_autocomplete_boolean_choice);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/wins", wins_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_tls_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_func(input, "/tls revoke", tlscerts_complete);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/tls cert", tlscerts_complete);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/tls certpath", tls_certpath_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/tls show", prefs_autocomplete_boolean_choice);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/tls", tls_ac, TRUE);
if (result) {
return result;
}
return result;
}
static char*
_receipts_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_func(input, "/receipts send", prefs_autocomplete_boolean_choice);
if (result) {
return result;
}
result = autocomplete_param_with_func(input, "/receipts request", prefs_autocomplete_boolean_choice);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/receipts", receipts_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_alias_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_ac(input, "/alias remove", aliases_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/alias", alias_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_connect_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
gboolean result = FALSE;
gchar **args = parse_args(input, 1, 7, &result);
if (result) {
gboolean space_at_end = g_str_has_suffix(input, " ");
GString *beginning = g_string_new("/connect");
int num_args = g_strv_length(args);
if ((num_args == 1 && space_at_end) || (num_args == 2 && !space_at_end)) {
g_string_append_printf(beginning, " %s", args[0]);
found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 2 && space_at_end && (g_strcmp0(args[1], "tls") == 0))
|| (num_args == 3 && (g_strcmp0(args[1], "tls") == 0) && !space_at_end)) {
g_string_append_printf(beginning, " %s %s", args[0], args[1]);
found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 3 && space_at_end) || (num_args == 4 && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 4 && space_at_end && (g_strcmp0(args[3], "tls") == 0))
|| (num_args == 5 && (g_strcmp0(args[3], "tls") == 0) && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 5 && space_at_end) || (num_args == 6 && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 6 && space_at_end && (g_strcmp0(args[5], "tls") == 0))
|| (num_args == 7 && (g_strcmp0(args[5], "tls") == 0) && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
g_string_free(beginning, TRUE);
}
g_strfreev(args);
found = autocomplete_param_with_func(input, "/connect", accounts_find_enabled);
if (found) {
return found;
}
return NULL;
}
static char*
_help_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_ac(input, "/help commands", help_commands_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/help", help_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_join_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
gboolean result = FALSE;
gchar **args = parse_args(input, 1, 5, &result);
if (result) {
gboolean space_at_end = g_str_has_suffix(input, " ");
int num_args = g_strv_length(args);
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
}
g_strfreev(args);
found = autocomplete_param_with_func(input, "/join", bookmark_find);
if (found) {
return found;
}
return NULL;
}
static char*
_console_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
result = autocomplete_param_with_ac(input, "/console chat", console_msg_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/console muc", console_msg_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/console private", console_msg_ac, TRUE);
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/console", console_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_win_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
found = autocomplete_param_with_func(input, "/win", win_autocomplete);
if (found) {
return found;
}
return NULL;
}
static char*
_close_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
found = autocomplete_param_with_func(input, "/close", win_close_autocomplete);
if (found) {
return found;
}
return NULL;
}
static char*
_sendfile_autocomplete(ProfWin *window, const char *const input)
{
return _complete_filepath(input, "/sendfile");
}
static char*
_subject_autocomplete(ProfWin *window, const char *const input)
{
char *result = NULL;
if (window->type == WIN_MUC) {
if ((g_strcmp0(input, "/subject e") == 0)
|| (g_strcmp0(input, "/subject ed") == 0)
|| (g_strcmp0(input, "/subject edi") == 0)
|| (g_strcmp0(input, "/subject edit") == 0)
|| (g_strcmp0(input, "/subject edit ") == 0)
|| (g_strcmp0(input, "/subject edit \"") == 0)) {
ProfMucWin *mucwin = (ProfMucWin*)window;
assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
char *subject = muc_subject(mucwin->roomjid);
if (subject) {
GString *result_str = g_string_new("/subject edit \"");
g_string_append(result_str, subject);
g_string_append(result_str, "\"");
result = result_str->str;
g_string_free(result_str, FALSE);
}
}
}
if (result) {
return result;
}
result = autocomplete_param_with_ac(input, "/subject", subject_ac, TRUE);
if (result) {
return result;
}
return NULL;
}
static char*
_account_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
gboolean result = FALSE;
gchar **args = parse_args(input, 2, 4, &result);
if (result && (strcmp(args[0], "set") == 0)) {
gboolean space_at_end = g_str_has_suffix(input, " ");
GString *beginning = g_string_new("/account");
int num_args = g_strv_length(args);
if ((num_args == 2 && space_at_end) || (num_args == 3 && !space_at_end)) {
g_string_append_printf(beginning, " %s %s", args[0], args[1]);
found = autocomplete_param_with_ac(input, beginning->str, account_set_ac, TRUE);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 3 && space_at_end && (g_strcmp0(args[2], "otr") == 0))
|| (num_args == 4 && (g_strcmp0(args[2], "otr") == 0) && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 3 && space_at_end && (g_strcmp0(args[2], "status") == 0))
|| (num_args == 4 && (g_strcmp0(args[2], "status") == 0) && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 3 && space_at_end && (g_strcmp0(args[2], "tls") == 0))
|| (num_args == 4 && (g_strcmp0(args[2], "tls") == 0) && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 3 && space_at_end && (g_strcmp0(args[2], "startscript") == 0))
|| (num_args == 4 && (g_strcmp0(args[2], "startscript") == 0) && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
if ((num_args == 3 && space_at_end && (g_strcmp0(args[2], "theme") == 0))
|| (num_args == 4 && (g_strcmp0(args[2], "theme") == 0) && !space_at_end)) {
g_string_append_printf(beginning, " %s %s %s", args[0], args[1], args[2]);
if (theme_load_ac == NULL) {
theme_load_ac = autocomplete_new();
GSList *themes = theme_list();
GSList *curr = themes;
while (curr) {
autocomplete_add(theme_load_ac, curr->data);
curr = g_slist_next(curr);
}
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
#ifdef HAVE_LIBGPGME
if ((num_args == 3 && space_at_end && (g_strcmp0(args[2], "pgpkeyid") == 0))
|| (num_args == 4 && (g_strcmp0(args[2], "pgpkeyid") == 0) && !space_at_end)) {
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
#endif
}
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);
g_string_free(beginning, TRUE);
if (found) {
g_strfreev(args);
return found;
}
}
g_strfreev(args);
found = autocomplete_param_with_ac(input, "/account default", account_default_ac, TRUE);
if(found){
return found;
}
int i = 0;
gchar *account_choice[] = { "/account set", "/account show", "/account enable",
"/account disable", "/account rename", "/account clear", "/account remove",
"/account default set" };
for (i = 0; i < ARRAY_SIZE(account_choice); i++) {
found = autocomplete_param_with_func(input, account_choice[i], accounts_find_all);
if (found) {
return found;
}
}
found = autocomplete_param_with_ac(input, "/account", account_ac, TRUE);
return found;
}
static char*
_presence_autocomplete(ProfWin *window, const char *const input)
{
char *found = NULL;
found = autocomplete_param_with_func(input, "/presence titlebar", prefs_autocomplete_boolean_choice);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/presence console", presence_setting_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/presence chat", presence_setting_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/presence room", presence_setting_ac, TRUE);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/presence", presence_ac, TRUE);
if (found) {
return found;
}
return NULL;
}
static char*
_complete_filepath(const char *const input, char *const startstr)
{
static char* last_directory = NULL;
unsigned int output_off = 0;
char *result = NULL;
char *tmp;
// strip command
char *inpcp = (char*)input + strlen(startstr);
while (*inpcp == ' ') {
inpcp++;
}
inpcp = strdup(inpcp);
// strip quotes
if (*inpcp == '"') {
tmp = strchr(inpcp+1, '"');
if (tmp) {
*tmp = '\0';
}
tmp = strdup(inpcp+1);
free(inpcp);
inpcp = tmp;
}
// expand ~ to $HOME
if (inpcp[0] == '~' && inpcp[1] == '/') {
if (asprintf(&tmp, "%s/%sfoo", getenv("HOME"), inpcp+2) == -1) {
return NULL;
}
output_off = strlen(getenv("HOME"))+1;
} else {
if (asprintf(&tmp, "%sfoo", inpcp) == -1) {
return NULL;
}
}
free(inpcp);
inpcp = tmp;
char* inpcp2 = strdup(inpcp);
char* foofile = strdup(basename(inpcp2));
char* directory = strdup(dirname(inpcp));
free(inpcp);
free(inpcp2);
if (!last_directory || strcmp(last_directory, directory) != 0) {
free(last_directory);
last_directory = directory;
autocomplete_reset(filepath_ac);
struct dirent *dir;
DIR *d = opendir(directory);
if (d) {
while ((dir = readdir(d)) != NULL) {
if (strcmp(dir->d_name, ".") == 0) {
continue;
} else if (strcmp(dir->d_name, "..") == 0) {
continue;
} else if (*(dir->d_name) == '.' && *foofile != '.') {
// only show hidden files on explicit request
continue;
}
char * acstring;
if (output_off) {
if (asprintf(&tmp, "%s/%s", directory, dir->d_name) == -1) {
return NULL;
}
if (asprintf(&acstring, "~/%s", tmp+output_off) == -1) {
return NULL;
}
free(tmp);
} else if (strcmp(directory, "/") == 0) {
if (asprintf(&acstring, "/%s", dir->d_name) == -1) {
return NULL;
}
} else {
if (asprintf(&acstring, "%s/%s", directory, dir->d_name) == -1) {
return NULL;
}
}
autocomplete_add(filepath_ac, acstring);
free(acstring);
}
closedir(d);
}
} else {
free(foofile);
free(directory);
}
result = autocomplete_param_with_ac(input, startstr, filepath_ac, TRUE);
if (result) {
return result;
}
return NULL;
}