summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/wee-command.c62
-rw-r--r--src/core/wee-completion.c26
-rw-r--r--src/core/wee-config.c149
-rw-r--r--src/core/wee-config.h2
-rw-r--r--src/gui/curses/gui-curses-key.c13
-rw-r--r--src/gui/curses/gui-curses.h2
-rw-r--r--src/gui/gui-buffer.c12
-rw-r--r--src/gui/gui-key.c333
-rw-r--r--src/gui/gui-key.h17
-rw-r--r--tests/unit/gui/test-gui-key.cpp318
10 files changed, 741 insertions, 193 deletions
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index 0d54f96a7..ab3290ee4 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -3812,8 +3812,10 @@ command_key_display_list (const char *message_no_key,
struct t_gui_key *ptr_key;
if (keys_count == 0)
+ {
gui_chat_printf (NULL, message_no_key,
gui_key_context_string[context]);
+ }
else
{
gui_chat_printf (NULL, "");
@@ -3997,7 +3999,7 @@ command_key_reset (int context, const char *key)
COMMAND_CALLBACK(key)
{
struct t_gui_key *ptr_new_key;
- int old_keys_count, keys_added, i, context, rc;
+ int old_keys_count, keys_added, context, rc;
/* make C compiler happy */
(void) pointer;
@@ -4007,17 +4009,20 @@ COMMAND_CALLBACK(key)
/* display all key bindings (current keys) */
if ((argc == 1) || (string_strcmp (argv[1], "list") == 0))
{
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
if ((argc < 3)
- || (string_strcmp (argv[2], gui_key_context_string[i]) == 0))
+ || (string_strcmp (argv[2],
+ gui_key_context_string[context]) == 0))
{
command_key_display_list (_("No key binding defined for "
"context \"%s\""),
/* TRANSLATORS: first "%d" is number of keys */
_("%d key bindings for context "
"\"%s\":"),
- i, gui_keys[i], gui_keys_count[i]);
+ context,
+ gui_keys[context],
+ gui_keys_count[context]);
}
}
return WEECHAT_RC_OK;
@@ -4026,12 +4031,13 @@ COMMAND_CALLBACK(key)
/* display redefined or key bindings added */
if (string_strcmp (argv[1], "listdiff") == 0)
{
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
if ((argc < 3)
- || (string_strcmp (argv[2], gui_key_context_string[i]) == 0))
+ || (string_strcmp (argv[2],
+ gui_key_context_string[context]) == 0))
{
- command_key_display_listdiff (i);
+ command_key_display_listdiff (context);
}
}
return WEECHAT_RC_OK;
@@ -4040,19 +4046,20 @@ COMMAND_CALLBACK(key)
/* display default key bindings */
if (string_strcmp (argv[1], "listdefault") == 0)
{
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
if ((argc < 3)
- || (string_strcmp (argv[2], gui_key_context_string[i]) == 0))
+ || (string_strcmp (argv[2],
+ gui_key_context_string[context]) == 0))
{
command_key_display_list (_("No default key binding for "
"context \"%s\""),
/* TRANSLATORS: first "%d" is number of keys */
_("%d default key bindings for "
"context \"%s\":"),
- i,
- gui_default_keys[i],
- gui_default_keys_count[i]);
+ context,
+ gui_default_keys[context],
+ gui_default_keys_count[context]);
}
}
return WEECHAT_RC_OK;
@@ -4258,18 +4265,22 @@ COMMAND_CALLBACK(key)
{
if ((argc >= 3) && (string_strcmp (argv[2], "-yes") == 0))
{
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
if ((argc < 4)
- || (string_strcmp (argv[3], gui_key_context_string[i]) == 0))
+ || (string_strcmp (argv[3],
+ gui_key_context_string[context]) == 0))
{
- gui_key_free_all (&gui_keys[i], &last_gui_key[i],
- &gui_keys_count[i]);
- gui_key_default_bindings (i);
+ gui_key_free_all (context,
+ &gui_keys[context],
+ &last_gui_key[context],
+ &gui_keys_count[context],
+ 1);
+ gui_key_default_bindings (context, 1);
gui_chat_printf (NULL,
_("Default key bindings restored for "
"context \"%s\""),
- gui_key_context_string[i]);
+ gui_key_context_string[context]);
}
}
}
@@ -4287,22 +4298,23 @@ COMMAND_CALLBACK(key)
/* add missing keys */
if (string_strcmp (argv[1], "missing") == 0)
{
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
if ((argc < 3)
- || (string_strcmp (argv[2], gui_key_context_string[i]) == 0))
+ || (string_strcmp (argv[2],
+ gui_key_context_string[context]) == 0))
{
- old_keys_count = gui_keys_count[i];
+ old_keys_count = gui_keys_count[context];
gui_key_verbose = 1;
- gui_key_default_bindings (i);
+ gui_key_default_bindings (context, 1);
gui_key_verbose = 0;
- keys_added = (gui_keys_count[i] > old_keys_count) ?
- gui_keys_count[i] - old_keys_count : 0;
+ keys_added = (gui_keys_count[context] > old_keys_count) ?
+ gui_keys_count[context] - old_keys_count : 0;
gui_chat_printf (NULL,
NG_("%d new key added", "%d new keys added "
"(context: \"%s\")", keys_added),
keys_added,
- gui_key_context_string[i]);
+ gui_key_context_string[context]);
}
}
return WEECHAT_RC_OK;
diff --git a/src/core/wee-completion.c b/src/core/wee-completion.c
index 4c5fbb12d..150ce8b1d 100644
--- a/src/core/wee-completion.c
+++ b/src/core/wee-completion.c
@@ -1648,7 +1648,7 @@ completion_list_add_keys_contexts_cb (const void *pointer, void *data,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
- int i;
+ int context;
/* make C compiler happy */
(void) pointer;
@@ -1656,9 +1656,9 @@ completion_list_add_keys_contexts_cb (const void *pointer, void *data,
(void) completion_item;
(void) buffer;
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
- gui_completion_list_add (completion, gui_key_context_string[i],
+ gui_completion_list_add (completion, gui_key_context_string[context],
0, WEECHAT_LIST_POS_END);
}
@@ -1675,7 +1675,7 @@ completion_list_add_keys_codes_cb (const void *pointer, void *data,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
- int i;
+ int context;
struct t_gui_key *ptr_key;
/* make C compiler happy */
@@ -1684,9 +1684,9 @@ completion_list_add_keys_codes_cb (const void *pointer, void *data,
(void) completion_item;
(void) buffer;
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
- for (ptr_key = gui_keys[i]; ptr_key; ptr_key = ptr_key->next_key)
+ for (ptr_key = gui_keys[context]; ptr_key; ptr_key = ptr_key->next_key)
{
gui_completion_list_add (completion, ptr_key->key,
0, WEECHAT_LIST_POS_SORT);
@@ -1707,7 +1707,7 @@ completion_list_add_keys_codes_for_reset_cb (const void *pointer, void *data,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
- int i;
+ int context;
struct t_gui_key *ptr_key, *ptr_default_key;
/* make C compiler happy */
@@ -1716,12 +1716,13 @@ completion_list_add_keys_codes_for_reset_cb (const void *pointer, void *data,
(void) completion_item;
(void) buffer;
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
/* keys added or redefined */
- for (ptr_key = gui_keys[i]; ptr_key; ptr_key = ptr_key->next_key)
+ for (ptr_key = gui_keys[context]; ptr_key; ptr_key = ptr_key->next_key)
{
- ptr_default_key = gui_key_search (gui_default_keys[i], ptr_key->key);
+ ptr_default_key = gui_key_search (gui_default_keys[context],
+ ptr_key->key);
if (!ptr_default_key
|| (strcmp (ptr_default_key->command, ptr_key->command) != 0))
{
@@ -1731,10 +1732,11 @@ completion_list_add_keys_codes_for_reset_cb (const void *pointer, void *data,
}
/* keys deleted */
- for (ptr_default_key = gui_default_keys[i]; ptr_default_key;
+ for (ptr_default_key = gui_default_keys[context]; ptr_default_key;
ptr_default_key = ptr_default_key->next_key)
{
- ptr_key = gui_key_search (gui_keys[i], ptr_default_key->key);
+ ptr_key = gui_key_search (gui_keys[context],
+ ptr_default_key->key);
if (!ptr_key)
{
gui_completion_list_add (completion, ptr_default_key->key,
diff --git a/src/core/wee-config.c b/src/core/wee-config.c
index 8aec0eb66..a89eb0540 100644
--- a/src/core/wee-config.c
+++ b/src/core/wee-config.c
@@ -73,6 +73,9 @@ struct t_config_section *weechat_config_section_proxy = NULL;
struct t_config_section *weechat_config_section_bar = NULL;
struct t_config_section *weechat_config_section_custom_bar_item = NULL;
struct t_config_section *weechat_config_section_notify = NULL;
+struct t_config_section *weechat_config_section_key[GUI_KEY_NUM_CONTEXTS] = {
+ NULL, NULL, NULL, NULL,
+};
/* config, startup section */
@@ -1454,7 +1457,7 @@ config_day_change_timer_cb (const void *pointer, void *data,
void
config_weechat_init_after_read ()
{
- int i;
+ int context;
util_setrlimit ();
@@ -1480,10 +1483,10 @@ config_weechat_init_after_read ()
gui_bar_item_custom_use_temp_items ();
/* if no key was found configuration file, then we use default bindings */
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
- if (!gui_keys[i])
- gui_key_default_bindings (i);
+ if (!gui_keys[context])
+ gui_key_default_bindings (context, 1);
}
/* apply filters on all buffers */
@@ -1578,17 +1581,20 @@ int
config_weechat_reload_cb (const void *pointer, void *data,
struct t_config_file *config_file)
{
- int i, rc;
+ int context, rc;
/* make C compiler happy */
(void) pointer;
(void) data;
/* remove all keys */
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
- gui_key_free_all (&gui_keys[i], &last_gui_key[i],
- &gui_keys_count[i]);
+ gui_key_free_all (context,
+ &gui_keys[context],
+ &last_gui_key[context],
+ &gui_keys_count[context],
+ 1);
}
/* remove all proxies */
@@ -1778,7 +1784,6 @@ config_weechat_palette_change_cb (const void *pointer, void *data,
/* make C compiler happy */
(void) pointer;
(void) data;
- (void) option;
error = NULL;
number = (int)strtol (option->name, &error, 10);
@@ -2602,87 +2607,82 @@ config_weechat_filter_write_cb (const void *pointer, void *data,
}
/*
- * Reads a key option in WeeChat configuration file.
+ * Searches key context with the section pointer.
+ *
+ * Returns key context, -1 if not found.
*/
int
-config_weechat_key_read_cb (const void *pointer, void *data,
- struct t_config_file *config_file,
- struct t_config_section *section,
- const char *option_name, const char *value)
+config_weechat_get_key_context (struct t_config_section *section)
+{
+ int context;
+
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
+ {
+ if (section == weechat_config_section_key[context])
+ return context;
+ }
+
+ /* this should never happen */
+ return -1;
+}
+
+/*
+ * Callback called when an option is created in one of these sections:
+ * key
+ * key_search
+ * key_cursor
+ * key_mouse
+ */
+
+int
+config_weechat_key_create_option_cb (const void *pointer, void *data,
+ struct t_config_file *config_file,
+ struct t_config_section *section,
+ const char *option_name,
+ const char *value)
{
int context;
- char *pos;
/* make C compiler happy */
(void) pointer;
(void) data;
(void) config_file;
- if (option_name)
- {
- context = GUI_KEY_CONTEXT_DEFAULT;
- pos = strchr (section->name, '_');
- if (pos)
- {
- context = gui_key_search_context (pos + 1);
- if (context < 0)
- context = GUI_KEY_CONTEXT_DEFAULT;
- }
+ if (!value)
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
- if (value && value[0])
- {
- /* bind key (overwrite any binding with same key) */
- gui_key_bind (NULL, context, option_name, value);
- }
- else
- {
- /* unbind key if no value given */
- gui_key_unbind (NULL, context, option_name);
- }
- }
+ context = config_weechat_get_key_context (section);
+ gui_key_bind (NULL, context, option_name, value);
return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
}
/*
- * Writes section "key" in WeeChat configuration file.
+ * Callback called when an option is deleted in one of these sections:
+ * key
+ * key_search
+ * key_cursor
+ * key_mouse
*/
int
-config_weechat_key_write_cb (const void *pointer, void *data,
- struct t_config_file *config_file,
- const char *section_name)
+config_weechat_key_delete_option_cb (const void *pointer, void *data,
+ struct t_config_file *config_file,
+ struct t_config_section *section,
+ struct t_config_option *option)
{
- struct t_gui_key *ptr_key;
- char *pos;
int context;
/* make C compiler happy */
(void) pointer;
(void) data;
+ (void) config_file;
- if (!config_file_write_line (config_file, section_name, NULL))
- return WEECHAT_CONFIG_WRITE_ERROR;
-
- context = GUI_KEY_CONTEXT_DEFAULT;
- pos = strchr (section_name, '_');
- if (pos)
- {
- context = gui_key_search_context (pos + 1);
- if (context < 0)
- context = GUI_KEY_CONTEXT_DEFAULT;
- }
- for (ptr_key = gui_keys[context]; ptr_key; ptr_key = ptr_key->next_key)
- {
- if (!config_file_write_line (config_file, ptr_key->key,
- "\"%s\"", ptr_key->command))
- {
- return WEECHAT_CONFIG_WRITE_ERROR;
- }
- }
+ context = config_weechat_get_key_context (section);
+ gui_key_unbind (NULL, context, option->name);
- return WEECHAT_CONFIG_WRITE_OK;
+ return WEECHAT_CONFIG_OPTION_UNSET_OK_REMOVED;
}
/*
@@ -2697,7 +2697,7 @@ int
config_weechat_init_options ()
{
struct t_config_section *ptr_section;
- int i;
+ int context;
char section_name[128];
weechat_config_file = config_file_new (
@@ -4946,26 +4946,29 @@ config_weechat_init_options ()
}
/* keys */
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
- snprintf (section_name, sizeof (section_name),
- "key%s%s",
- (i == GUI_KEY_CONTEXT_DEFAULT) ? "" : "_",
- (i == GUI_KEY_CONTEXT_DEFAULT) ? "" : gui_key_context_string[i]);
+ snprintf (
+ section_name, sizeof (section_name),
+ "key%s%s",
+ (context == GUI_KEY_CONTEXT_DEFAULT) ? "" : "_",
+ (context == GUI_KEY_CONTEXT_DEFAULT) ?
+ "" : gui_key_context_string[context]);
ptr_section = config_file_new_section (
weechat_config_file, section_name,
- 0, 0,
- &config_weechat_key_read_cb, NULL, NULL,
- &config_weechat_key_write_cb, NULL, NULL,
- &config_weechat_key_write_cb, NULL, NULL,
+ 1, 1,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
NULL, NULL, NULL,
- NULL, NULL, NULL);
+ &config_weechat_key_create_option_cb, NULL, NULL,
+ &config_weechat_key_delete_option_cb, NULL, NULL);
if (!ptr_section)
{
config_file_free (weechat_config_file);
weechat_config_file = NULL;
return 0;
}
+ weechat_config_section_key[context] = ptr_section;
}
return 1;
diff --git a/src/core/wee-config.h b/src/core/wee-config.h
index 921a06203..195efcd75 100644
--- a/src/core/wee-config.h
+++ b/src/core/wee-config.h
@@ -132,6 +132,7 @@ extern struct t_config_section *weechat_config_section_proxy;
extern struct t_config_section *weechat_config_section_bar;
extern struct t_config_section *weechat_config_section_custom_bar_item;
extern struct t_config_section *weechat_config_section_notify;
+extern struct t_config_section *weechat_config_section_key[];
extern struct t_config_option *config_startup_command_after_plugins;
extern struct t_config_option *config_startup_command_before_plugins;
@@ -387,6 +388,7 @@ extern void config_weechat_debug_set_all ();
extern int config_weechat_notify_set (struct t_gui_buffer *buffer,
const char *notify);
extern void config_get_item_time (char *text_time, int max_length);
+extern int config_weechat_get_key_context (struct t_config_section *section);
extern int config_weechat_init ();
extern int config_weechat_read ();
extern int config_weechat_write ();
diff --git a/src/gui/curses/gui-curses-key.c b/src/gui/curses/gui-curses-key.c
index 6d9a544c1..9dcb2c227 100644
--- a/src/gui/curses/gui-curses-key.c
+++ b/src/gui/curses/gui-curses-key.c
@@ -45,7 +45,8 @@
#include "../gui-window.h"
#include "gui-curses.h"
-#define BIND(key, command) gui_key_default_bind(context, key, command)
+#define BIND(key, command) \
+ gui_key_default_bind(context, key, command, create_option)
/*
@@ -53,21 +54,25 @@
*/
void
-gui_key_default_bind (int context, const char *key, const char *command)
+gui_key_default_bind (int context, const char *key, const char *command,
+ int create_option)
{
struct t_gui_key *ptr_key;
ptr_key = gui_key_search (gui_keys[context], key);
if (!ptr_key)
- gui_key_new (NULL, context, key, command);
+ gui_key_new (NULL, context, key, command, create_option);
}
/*
* Creates default key bindings for a given context.
+ *
+ * If create_option == 1, config options are created, otherwise keys are just
+ * added to linked list (gui_keys[]).
*/
void
-gui_key_default_bindings (int context)
+gui_key_default_bindings (int context, int create_option)
{
int i;
char key_str[32], command[32];
diff --git a/src/gui/curses/gui-curses.h b/src/gui/curses/gui-curses.h
index 1e7286d05..086a59edd 100644
--- a/src/gui/curses/gui-curses.h
+++ b/src/gui/curses/gui-curses.h
@@ -104,7 +104,7 @@ extern void gui_chat_calculate_line_diff (struct t_gui_window *window,
int *line_pos, int difference);
/* key functions */
-extern void gui_key_default_bindings (int context);
+extern void gui_key_default_bindings (int context, int create_option);
extern int gui_key_read_cb (const void *pointer, void *data, int fd);
/* window functions */
diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c
index 343e15908..4858bc49f 100644
--- a/src/gui/gui-buffer.c
+++ b/src/gui/gui-buffer.c
@@ -2384,11 +2384,13 @@ gui_buffer_set (struct t_gui_buffer *buffer, const char *property,
{
if (strcmp (property + 11, "*") == 0)
{
- gui_key_free_all (&buffer->keys, &buffer->last_key,
- &buffer->keys_count);
+ gui_key_free_all (-1, &buffer->keys, &buffer->last_key,
+ &buffer->keys_count, 0);
}
else
- gui_key_unbind (buffer, 0, property + 11);
+ {
+ gui_key_unbind (buffer, -1, property + 11);
+ }
}
else if (strcmp (property, "input") == 0)
{
@@ -3128,8 +3130,8 @@ gui_buffer_close (struct t_gui_buffer *buffer)
gui_nicklist_remove_group (buffer, buffer->nicklist_root);
if (buffer->hotlist_max_level_nicks)
hashtable_free (buffer->hotlist_max_level_nicks);
- gui_key_free_all (&buffer->keys, &buffer->last_key,
- &buffer->keys_count);
+ gui_key_free_all (-1, &buffer->keys, &buffer->last_key,
+ &buffer->keys_count, 0);
gui_buffer_local_var_remove_all (buffer);
hashtable_free (buffer->local_variables);
if (buffer->plugin_name_for_upgrade)
diff --git a/src/gui/gui-key.c b/src/gui/gui-key.c
index d5e916ab9..c801b2323 100644
--- a/src/gui/gui-key.c
+++ b/src/gui/gui-key.c
@@ -31,6 +31,7 @@
#include "../core/weechat.h"
#include "../core/wee-config.h"
+#include "../core/wee-config-file.h"
#include "../core/wee-eval.h"
#include "../core/wee-hashtable.h"
#include "../core/wee-hdata.h"
@@ -112,7 +113,7 @@ time_t gui_key_last_activity_time = 0; /* last activity time (key) */
void
gui_key_init ()
{
- int i;
+ int context;
gui_key_combo_buffer[0] = '\0';
gui_key_grab = 0;
@@ -120,21 +121,21 @@ gui_key_init ()
gui_key_last_activity_time = time (NULL);
/* create default keys and save them in a separate list */
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
- {
- gui_keys[i] = NULL;
- last_gui_key[i] = NULL;
- gui_default_keys[i] = NULL;
- last_gui_default_key[i] = NULL;
- gui_keys_count[i] = 0;
- gui_default_keys_count[i] = 0;
- gui_key_default_bindings (i);
- gui_default_keys[i] = gui_keys[i];
- last_gui_default_key[i] = last_gui_key[i];
- gui_default_keys_count[i] = gui_keys_count[i];
- gui_keys[i] = NULL;
- last_gui_key[i] = NULL;
- gui_keys_count[i] = 0;
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
+ {
+ gui_keys[context] = NULL;
+ last_gui_key[context] = NULL;
+ gui_default_keys[context] = NULL;
+ last_gui_default_key[context] = NULL;
+ gui_keys_count[context] = 0;
+ gui_default_keys_count[context] = 0;
+ gui_key_default_bindings (context, 0);
+ gui_default_keys[context] = gui_keys[context];
+ last_gui_default_key[context] = last_gui_key[context];
+ gui_default_keys_count[context] = gui_keys_count[context];
+ gui_keys[context] = NULL;
+ last_gui_key[context] = NULL;
+ gui_keys_count[context] = 0;
}
}
@@ -879,6 +880,71 @@ gui_key_legacy_to_alias (const char *key)
}
/*
+ * Amends key: transform upper case ctrl keys to lower case and replace " "
+ * by "space".
+ *
+ * Examples:
+ * "ctrl-a" => "ctrl-a" (unchanged)
+ * "meta-A" => "meta-A" (unchanged)
+ * 'return" => "return" (unchanged)
+ * "ctrl-G" => "ctrl-g"
+ * "ctrl-C,b" => "ctrl-c,b"
+ * " " => "space"
+ * "meta- " => "meta-space"
+ *
+ * Note: result must be freed after use.
+ */
+
+char *
+gui_key_amend (const char *key)
+{
+ char **result, str_key[2];
+ const char *ptr_key;
+ int length;
+
+ if (!key)
+ return NULL;
+
+ if ((key[0] == '@') && strchr (key, ':'))
+ return strdup (key);
+
+ result = string_dyn_alloc (strlen (key) + 1);
+ if (!result)
+ return NULL;
+
+ ptr_key = key;
+ while (ptr_key && ptr_key[0])
+ {
+ if (ptr_key[0] == ' ')
+ {
+ string_dyn_concat (result, "space", -1);
+ ptr_key++;
+ }
+ else if (strncmp (ptr_key, "ctrl-", 5) == 0)
+ {
+ string_dyn_concat (result, ptr_key, 5);
+ ptr_key += 5;
+ if (ptr_key[0])
+ {
+ str_key[0] = ((ptr_key[0] >= 'A') && (ptr_key[0] <= 'Z')) ?
+ ptr_key[0] + ('a' - 'A') : ptr_key[0];
+ str_key[1] = '\0';
+ string_dyn_concat (result, str_key, -1);
+ ptr_key++;
+ }
+ }
+ else
+ {
+ length = utf8_char_size (ptr_key);
+ string_dyn_concat (result, ptr_key, length);
+ ptr_key += length;
+ }
+ }
+
+ return string_dyn_free (result, 0);
+}
+
+/*
* Searches for position of a key (to keep keys sorted).
*/
@@ -1152,29 +1218,128 @@ gui_key_is_safe (int context, const char *key)
}
/*
+ * Callback for changes on a key option.
+ */
+
+void
+gui_key_option_change_cb (const void *pointer, void *data,
+ struct t_config_option *option)
+{
+ struct t_gui_key *ptr_key;
+ int context;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+
+ context = config_weechat_get_key_context (option->section);
+ if (context < 0)
+ return;
+
+ ptr_key = gui_key_search (gui_keys[context], option->name);
+ if (!ptr_key)
+ return;
+
+ if (ptr_key->command)
+ free (ptr_key->command);
+ ptr_key->command = strdup (CONFIG_STRING(option));
+}
+
+/*
+ * Creates a new key option.
+ *
+ * Returns pointer to existing or new option.
+ */
+
+struct t_config_option *
+gui_key_new_option (int context, const char *name, const char *value)
+{
+ struct t_config_option *ptr_option;
+ struct t_gui_key *ptr_key;
+ char str_description[1024];
+
+ if (!name || !value)
+ return NULL;
+
+ ptr_option = config_file_search_option (weechat_config_file,
+ weechat_config_section_key[context],
+ name);
+ if (ptr_option)
+ {
+ config_file_option_set (ptr_option, value, 1);
+ }
+ else
+ {
+ snprintf (str_description, sizeof (str_description),
+ _("key \"%s\" in context \"%s\""),
+ name,
+ gui_key_context_string[context]);
+ ptr_key = gui_key_search (gui_default_keys[context], name);
+ ptr_option = config_file_new_option (
+ weechat_config_file, weechat_config_section_key[context],
+ name, "string",
+ str_description,
+ NULL, 0, 0,
+ (ptr_key) ? ptr_key->command : "",
+ value,
+ 0,
+ NULL, NULL, NULL,
+ &gui_key_option_change_cb, NULL, NULL,
+ NULL, NULL, NULL);
+ }
+
+ return ptr_option;
+}
+
+/*
* Adds a new key in keys list.
*
* If buffer is not null, then key is specific to buffer, otherwise it's general
* key (for most keys).
*
+ * If create_option == 1, a config option is created as well.
+ *
* Returns pointer to new key, NULL if error.
*/
struct t_gui_key *
gui_key_new (struct t_gui_buffer *buffer, int context, const char *key,
- const char *command)
+ const char *command, int create_option)
{
+ char *key_amended;
+ struct t_config_option *ptr_option;
struct t_gui_key *new_key;
if (!key || !command)
return NULL;
+ key_amended = gui_key_amend (key);
+ if (!key_amended)
+ return NULL;
+
+ ptr_option = NULL;
+
+ if (!buffer && create_option)
+ {
+ ptr_option = gui_key_new_option (context, key_amended, command);
+ if (!ptr_option)
+ {
+ free (key_amended);
+ return NULL;
+ }
+ }
+
new_key = malloc (sizeof (*new_key));
if (!new_key)
+ {
+ if (ptr_option)
+ config_file_option_free (ptr_option, 0);
+ free (key_amended);
return NULL;
+ }
- new_key->key = strdup (key);
- new_key->chunks = string_split (key, ",", NULL, 0, 0,
+ new_key->key = key_amended;
+ new_key->chunks = string_split (key_amended, ",", NULL, 0, 0,
&new_key->chunks_count);
new_key->command = strdup (command);
gui_key_set_areas (new_key);
@@ -1182,14 +1347,17 @@ gui_key_new (struct t_gui_buffer *buffer, int context, const char *key,
if (buffer)
{
- gui_key_insert_sorted (&buffer->keys, &buffer->last_key,
- &buffer->keys_count, new_key);
+ gui_key_insert_sorted (&buffer->keys,
+ &buffer->last_key,
+ &buffer->keys_count,
+ new_key);
}
else
{
gui_key_insert_sorted (&gui_keys[context],
&last_gui_key[context],
- &gui_keys_count[context], new_key);
+ &gui_keys_count[context],
+ new_key);
}
if (gui_key_verbose)
@@ -1345,7 +1513,7 @@ gui_key_bind (struct t_gui_buffer *buffer, int context, const char *key,
gui_key_unbind (buffer, context, key);
- return gui_key_new (buffer, context, key, command);
+ return gui_key_new (buffer, context, key, command, 1);
}
/*
@@ -1374,7 +1542,7 @@ gui_key_bind_plugin_hashtable_map_cb (void *data,
ptr_key = gui_key_search (gui_keys[user_data[0]], key);
if (!ptr_key)
{
- if (gui_key_new (NULL, user_data[0], key, value))
+ if (gui_key_new (NULL, user_data[0], key, value, 1))
user_data[1]++;
}
}
@@ -1422,17 +1590,25 @@ gui_key_bind_plugin (const char *context, struct t_hashtable *keys)
int
gui_key_unbind (struct t_gui_buffer *buffer, int context, const char *key)
{
+ char *key_amended;
struct t_gui_key *ptr_key;
+ key_amended = gui_key_amend (key);
+ if (!key_amended)
+ return 0;
+
ptr_key = gui_key_search ((buffer) ? buffer->keys : gui_keys[context],
- key);
+ key_amended);
if (!ptr_key)
+ {
+ free (key_amended);
return 0;
+ }
if (buffer)
{
- gui_key_free (&buffer->keys, &buffer->last_key,
- &buffer->keys_count, ptr_key);
+ gui_key_free (-1, &buffer->keys, &buffer->last_key,
+ &buffer->keys_count, ptr_key, 0);
}
else
{
@@ -1440,15 +1616,17 @@ gui_key_unbind (struct t_gui_buffer *buffer, int context, const char *key)
{
gui_chat_printf (NULL,
_("Key \"%s\" unbound (context: \"%s\")"),
- key,
+ key_amended,
gui_key_context_string[context]);
}
- gui_key_free (&gui_keys[context], &last_gui_key[context],
- &gui_keys_count[context], ptr_key);
+ gui_key_free (context, &gui_keys[context], &last_gui_key[context],
+ &gui_keys_count[context], ptr_key, 1);
}
(void) hook_signal_send ("key_unbind",
- WEECHAT_HOOK_SIGNAL_STRING, (char *)key);
+ WEECHAT_HOOK_SIGNAL_STRING, key_amended);
+
+ free (key_amended);
return 1;
}
@@ -2070,17 +2248,31 @@ end:
/*
* Deletes a key binding.
+ *
+ * If delete_option == 1, the config option is deleted.
*/
void
-gui_key_free (struct t_gui_key **keys, struct t_gui_key **last_key,
- int *keys_count, struct t_gui_key *key)
+gui_key_free (int context,
+ struct t_gui_key **keys, struct t_gui_key **last_key,
+ int *keys_count, struct t_gui_key *key, int delete_option)
{
+ struct t_config_option *ptr_option;
int i;
if (!key)
return;
+ if (delete_option)
+ {
+ ptr_option = config_file_search_option (
+ weechat_config_file,
+ weechat_config_section_key[context],
+ key->key);
+ if (ptr_option)
+ config_file_option_free (ptr_option, 1);
+ }
+
/* free memory */
if (key->key)
free (key->key);
@@ -2113,15 +2305,19 @@ gui_key_free (struct t_gui_key **keys, struct t_gui_key **last_key,
/*
* Deletes all key bindings.
+ *
+ * If delete_option == 1, the config options are deleted.
*/
void
-gui_key_free_all (struct t_gui_key **keys, struct t_gui_key **last_key,
- int *keys_count)
+gui_key_free_all (int context, struct t_gui_key **keys,
+ struct t_gui_key **last_key,
+ int *keys_count, int delete_option)
{
while (*keys)
{
- gui_key_free (keys, last_key, keys_count, *keys);
+ gui_key_free (context, keys, last_key, keys_count, *keys,
+ delete_option);
}
}
@@ -2501,20 +2697,26 @@ gui_key_paste_cancel ()
void
gui_key_end ()
{
- int i;
+ int context;
/* free key buffer */
if (gui_key_buffer)
free (gui_key_buffer);
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
/* free keys */
- gui_key_free_all (&gui_keys[i], &last_gui_key[i],
- &gui_keys_count[i]);
+ gui_key_free_all (context,
+ &gui_keys[context],
+ &last_gui_key[context],
+ &gui_keys_count[context],
+ 0);
/* free default keys */
- gui_key_free_all (&gui_default_keys[i], &last_gui_default_key[i],
- &gui_default_keys_count[i]);
+ gui_key_free_all (context,
+ &gui_default_keys[context],
+ &last_gui_default_key[context],
+ &gui_default_keys_count[context],
+ 0);
}
}
@@ -2527,7 +2729,7 @@ gui_key_hdata_key_cb (const void *pointer, void *data,
const char *hdata_name)
{
struct t_hdata *hdata;
- int i;
+ int context;
char str_list[128];
/* make C compiler happy */
@@ -2546,28 +2748,32 @@ gui_key_hdata_key_cb (const void *pointer, void *data,
HDATA_VAR(struct t_gui_key, score, INTEGER, 0, NULL, NULL);
HDATA_VAR(struct t_gui_key, prev_key, POINTER, 0, NULL, hdata_name);
HDATA_VAR(struct t_gui_key, next_key, POINTER, 0, NULL, hdata_name);
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
snprintf (str_list, sizeof (str_list),
"gui_keys%s%s",
- (i == GUI_KEY_CONTEXT_DEFAULT) ? "" : "_",
- (i == GUI_KEY_CONTEXT_DEFAULT) ? "" : gui_key_context_string[i]);
- hdata_new_list (hdata, str_list, &gui_keys[i], 0);
+ (context == GUI_KEY_CONTEXT_DEFAULT) ? "" : "_",
+ (context == GUI_KEY_CONTEXT_DEFAULT) ?
+ "" : gui_key_context_string[context]);
+ hdata_new_list (hdata, str_list, &gui_keys[context], 0);
snprintf (str_list, sizeof (str_list),
"last_gui_key%s%s",
- (i == GUI_KEY_CONTEXT_DEFAULT) ? "" : "_",
- (i == GUI_KEY_CONTEXT_DEFAULT) ? "" : gui_key_context_string[i]);
- hdata_new_list (hdata, str_list, &last_gui_key[i], 0);
+ (context == GUI_KEY_CONTEXT_DEFAULT) ? "" : "_",
+ (context == GUI_KEY_CONTEXT_DEFAULT) ?
+ "" : gui_key_context_string[context]);
+ hdata_new_list (hdata, str_list, &last_gui_key[context], 0);
snprintf (str_list, sizeof (str_list),
"gui_default_keys%s%s",
- (i == GUI_KEY_CONTEXT_DEFAULT) ? "" : "_",
- (i == GUI_KEY_CONTEXT_DEFAULT) ? "" : gui_key_context_string[i]);
- hdata_new_list (hdata, str_list, &gui_default_keys[i], 0);
+ (context == GUI_KEY_CONTEXT_DEFAULT) ? "" : "_",
+ (context == GUI_KEY_CONTEXT_DEFAULT) ?
+ "" : gui_key_context_string[context]);
+ hdata_new_list (hdata, str_list, &gui_default_keys[context], 0);
snprintf (str_list, sizeof (str_list),
"last_gui_default_key%s%s",
- (i == GUI_KEY_CONTEXT_DEFAULT) ? "" : "_",
- (i == GUI_KEY_CONTEXT_DEFAULT) ? "" : gui_key_context_string[i]);
- hdata_new_list (hdata, str_list, &last_gui_default_key[i], 0);
+ (context == GUI_KEY_CONTEXT_DEFAULT) ? "" : "_",
+ (context == GUI_KEY_CONTEXT_DEFAULT) ?
+ "" : gui_key_context_string[context]);
+ hdata_new_list (hdata, str_list, &last_gui_default_key[context], 0);
}
}
return hdata;
@@ -2647,7 +2853,7 @@ void
gui_key_print_log (struct t_gui_buffer *buffer)
{
struct t_gui_key *ptr_key;
- int i;
+ int context;
if (buffer)
{
@@ -2662,15 +2868,16 @@ gui_key_print_log (struct t_gui_buffer *buffer)
}
else
{
- for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
{
log_printf ("");
- log_printf ("[keys for context: %s]", gui_key_context_string[i]);
- log_printf (" keys . . . . . . . . : 0x%lx", gui_keys[i]);
- log_printf (" last_key . . . . . . : 0x%lx", last_gui_key[i]);
- log_printf (" keys_count . . . . . : %d", gui_keys_count[i]);
+ log_printf ("[keys for context: %s]", gui_key_context_string[context]);
+ log_printf (" keys . . . . . . . . : 0x%lx", gui_keys[context]);
+ log_printf (" last_key . . . . . . : 0x%lx", last_gui_key[context]);
+ log_printf (" keys_count . . . . . : %d", gui_keys_count[context]);
- for (ptr_key = gui_keys[i]; ptr_key; ptr_key = ptr_key->next_key)
+ for (ptr_key = gui_keys[context]; ptr_key;
+ ptr_key = ptr_key->next_key)
{
log_printf ("");
gui_key_print_log_key (ptr_key, "");
diff --git a/src/gui/gui-key.h b/src/gui/gui-key.h
index fed8ca750..7110a0d9c 100644
--- a/src/gui/gui-key.h
+++ b/src/gui/gui-key.h
@@ -99,7 +99,8 @@ extern int gui_key_is_safe (int context, const char *key);
extern struct t_gui_key *gui_key_new (struct t_gui_buffer *buffer,
int context,
const char *key,
- const char *command);
+ const char *command,
+ int create_option);
extern struct t_gui_key *gui_key_search (struct t_gui_key *keys,
const char *key);
extern struct t_gui_key *gui_key_bind (struct t_gui_buffer *buffer,
@@ -112,13 +113,17 @@ extern int gui_key_unbind (struct t_gui_buffer *buffer, int context,
extern int gui_key_unbind_plugin (const char *context, const char *key);
extern int gui_key_focus (const char *key, int context);
extern int gui_key_pressed (const char *key_str);
-extern void gui_key_free (struct t_gui_key **keys,
+extern void gui_key_free (int context,
+ struct t_gui_key **keys,
struct t_gui_key **last_key,
int *keys_count,
- struct t_gui_key *key);
-extern void gui_key_free_all (struct t_gui_key **keys,
+ struct t_gui_key *key,
+ int delete_option);
+extern void gui_key_free_all (int context,
+ struct t_gui_key **keys,
struct t_gui_key **last_key,
- int *keys_count);
+ int *keys_count,
+ int delete_option);
extern void gui_key_buffer_reset ();
extern void gui_key_buffer_add (unsigned char key);
extern int gui_key_buffer_search (int start_index, int max_index,
@@ -145,6 +150,6 @@ extern void gui_key_print_log (struct t_gui_buffer *buffer);
/* key functions (GUI dependent) */
-extern void gui_key_default_bindings (int context);
+extern void gui_key_default_bindings (int context, int create_option);
#endif /* WEECHAT_GUI_KEY_H */
diff --git a/tests/unit/gui/test-gui-key.cpp b/tests/unit/gui/test-gui-key.cpp
index 1cb6323c5..f75294b5d 100644
--- a/tests/unit/gui/test-gui-key.cpp
+++ b/tests/unit/gui/test-gui-key.cpp
@@ -25,9 +25,24 @@
extern "C"
{
+#include "src/core/wee-config.h"
+#include "src/core/wee-input.h"
+#include "src/core/wee-string.h"
+#include "src/gui/gui-buffer.h"
#include "src/gui/gui-key.h"
+extern int gui_key_get_current_context ();
extern char *gui_key_legacy_internal_code (const char *key);
+extern char *gui_key_amend (const char *key);
+extern struct t_config_option *gui_key_new_option (int context,
+ const char *name,
+ const char *value);
+extern int gui_key_compare_chunks (const char **chunks, int chunks_count,
+ const char **key_chunks, int key_chunks_count);
+extern struct t_gui_key *gui_key_search_part (struct t_gui_buffer *buffer, int context,
+ const char **chunks1, int chunks1_count,
+ const char **chunks2, int chunks2_count,
+ int *exact_match);
}
#define WEE_CHECK_EXP_KEY(__rc, __key_name, __key_name_alias, __key) \
@@ -94,7 +109,19 @@ TEST(GuiKey, SearchContext)
TEST(GuiKey, GetCurrentContext)
{
- /* TODO: write tests */
+ LONGS_EQUAL(GUI_KEY_CONTEXT_DEFAULT, gui_key_get_current_context ());
+
+ input_data (gui_buffers, "/cursor", NULL);
+ LONGS_EQUAL(GUI_KEY_CONTEXT_CURSOR, gui_key_get_current_context ());
+
+ input_data (gui_buffers, "/cursor stop", NULL);
+ LONGS_EQUAL(GUI_KEY_CONTEXT_DEFAULT, gui_key_get_current_context ());
+
+ input_data (gui_buffers, "/input search_text_here", NULL);
+ LONGS_EQUAL(GUI_KEY_CONTEXT_SEARCH, gui_key_get_current_context ());
+
+ input_data (gui_buffers, "/input search_stop", NULL);
+ LONGS_EQUAL(GUI_KEY_CONTEXT_DEFAULT, gui_key_get_current_context ());
}
/*
@@ -836,6 +863,33 @@ TEST(GuiKey, LegacyToAlias)
/*
* Tests functions:
+ * gui_key_amend
+ */
+
+TEST(GuiKey, Amend)
+{
+ char *str;
+
+ WEE_TEST_STR(NULL, gui_key_amend (NULL));
+
+ /* no changes */
+ WEE_TEST_STR("", gui_key_amend (""));
+ WEE_TEST_STR("a", gui_key_amend ("a"));
+ WEE_TEST_STR("@chat:button1", gui_key_amend ("@chat:button1"));
+ WEE_TEST_STR("meta-A", gui_key_amend ("meta-A"));
+ WEE_TEST_STR("ctrl-a", gui_key_amend ("ctrl-a"));
+ WEE_TEST_STR("return", gui_key_amend ("return"));
+
+ /* changes */
+ WEE_TEST_STR("ctrl-a", gui_key_amend ("ctrl-A"));
+ WEE_TEST_STR("ctrl-c,b", gui_key_amend ("ctrl-C,b"));
+ WEE_TEST_STR("ctrl-c,ctrl-b,A", gui_key_amend ("ctrl-C,ctrl-B,A"));
+ WEE_TEST_STR("space", gui_key_amend (" "));
+ WEE_TEST_STR("meta-space", gui_key_amend ("meta- "));
+}
+
+/*
+ * Tests functions:
* gui_key_find_pos
*/
@@ -982,12 +1036,140 @@ TEST(GuiKey, IsSafe)
/*
* Tests functions:
+ * gui_key_option_change_cb
+ */
+
+TEST(GuiKey, OptionChangeCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_key_new_option
+ */
+
+TEST(GuiKey, NewOption)
+{
+ struct t_config_option *ptr_option;
+ int context;
+
+ POINTERS_EQUAL(NULL, gui_key_new_option (GUI_KEY_CONTEXT_DEFAULT,
+ NULL, NULL));
+ POINTERS_EQUAL(NULL, gui_key_new_option (GUI_KEY_CONTEXT_DEFAULT,
+ "meta-a,meta-b,meta-c", NULL));
+ POINTERS_EQUAL(NULL, gui_key_new_option (GUI_KEY_CONTEXT_DEFAULT,
+ NULL, "/mute"));
+
+ for (context = 0; context < GUI_KEY_NUM_CONTEXTS; context++)
+ {
+ POINTERS_EQUAL(NULL,
+ config_file_search_option (
+ weechat_config_file,
+ weechat_config_section_key[context],
+ "meta-a,meta-b,meta-c"));
+ ptr_option = gui_key_new_option (context,
+ "meta-a,meta-b,meta-c", "/mute");
+ CHECK(ptr_option);
+ POINTERS_EQUAL(ptr_option,
+ config_file_search_option (
+ weechat_config_file,
+ weechat_config_section_key[context],
+ "meta-a,meta-b,meta-c"));
+ STRCMP_EQUAL("/mute", CONFIG_STRING(ptr_option));
+ config_file_option_free (ptr_option, 0);
+ }
+}
+
+/*
+ * Tests functions:
* gui_key_new
*/
TEST(GuiKey, New)
{
- /* TODO: write tests */
+ struct t_gui_key *ptr_key;
+
+ POINTERS_EQUAL(NULL, gui_key_new (NULL, GUI_KEY_CONTEXT_DEFAULT,
+ NULL, NULL, 1));
+ POINTERS_EQUAL(NULL, gui_key_new (NULL, GUI_KEY_CONTEXT_DEFAULT,
+ "meta-a,meta-b,meta-c", NULL, 1));
+ POINTERS_EQUAL(NULL, gui_key_new (NULL, GUI_KEY_CONTEXT_DEFAULT,
+ NULL, "/mute", 1));
+
+ ptr_key = gui_key_new (NULL, GUI_KEY_CONTEXT_DEFAULT,
+ "meta-a,meta-b,meta-c", "/mute", 1);
+ CHECK(ptr_key);
+ STRCMP_EQUAL("meta-a,meta-b,meta-c", ptr_key->key);
+ LONGS_EQUAL(3, ptr_key->chunks_count);
+ STRCMP_EQUAL("meta-a", ptr_key->chunks[0]);
+ STRCMP_EQUAL("meta-b", ptr_key->chunks[1]);
+ STRCMP_EQUAL("meta-c", ptr_key->chunks[2]);
+ LONGS_EQUAL(GUI_KEY_FOCUS_ANY, ptr_key->area_type[0]);
+ LONGS_EQUAL(GUI_KEY_FOCUS_ANY, ptr_key->area_type[1]);
+ POINTERS_EQUAL(NULL, ptr_key->area_key);
+ STRCMP_EQUAL("/mute", ptr_key->command);
+ LONGS_EQUAL(0, ptr_key->score);
+ gui_key_free (GUI_KEY_CONTEXT_DEFAULT,
+ &gui_keys[GUI_KEY_CONTEXT_DEFAULT],
+ &last_gui_key[GUI_KEY_CONTEXT_DEFAULT],
+ &gui_keys_count[GUI_KEY_CONTEXT_DEFAULT],
+ ptr_key,
+ 1);
+
+ ptr_key = gui_key_new (NULL, GUI_KEY_CONTEXT_CURSOR,
+ "@chat:z", "/print z", 1);
+ CHECK(ptr_key);
+ STRCMP_EQUAL("@chat:z", ptr_key->key);
+ LONGS_EQUAL(1, ptr_key->chunks_count);
+ STRCMP_EQUAL("@chat:z", ptr_key->chunks[0]);
+ LONGS_EQUAL(GUI_KEY_FOCUS_CHAT, ptr_key->area_type[0]);
+ LONGS_EQUAL(GUI_KEY_FOCUS_ANY, ptr_key->area_type[1]);
+ STRCMP_EQUAL("z", ptr_key->area_key);
+ STRCMP_EQUAL("/print z", ptr_key->command);
+ LONGS_EQUAL(368, ptr_key->score);
+ gui_key_free (GUI_KEY_CONTEXT_CURSOR,
+ &gui_keys[GUI_KEY_CONTEXT_CURSOR],
+ &last_gui_key[GUI_KEY_CONTEXT_CURSOR],
+ &gui_keys_count[GUI_KEY_CONTEXT_CURSOR],
+ ptr_key,
+ 1);
+
+ ptr_key = gui_key_new (NULL, GUI_KEY_CONTEXT_MOUSE,
+ "@chat:wheelup", "/print wheelup", 1);
+ CHECK(ptr_key);
+ STRCMP_EQUAL("@chat:wheelup", ptr_key->key);
+ LONGS_EQUAL(1, ptr_key->chunks_count);
+ STRCMP_EQUAL("@chat:wheelup", ptr_key->chunks[0]);
+ LONGS_EQUAL(GUI_KEY_FOCUS_CHAT, ptr_key->area_type[0]);
+ LONGS_EQUAL(GUI_KEY_FOCUS_ANY, ptr_key->area_type[1]);
+ STRCMP_EQUAL("wheelup", ptr_key->area_key);
+ STRCMP_EQUAL("/print wheelup", ptr_key->command);
+ LONGS_EQUAL(368, ptr_key->score);
+ gui_key_free (GUI_KEY_CONTEXT_MOUSE,
+ &gui_keys[GUI_KEY_CONTEXT_MOUSE],
+ &last_gui_key[GUI_KEY_CONTEXT_MOUSE],
+ &gui_keys_count[GUI_KEY_CONTEXT_MOUSE],
+ ptr_key,
+ 1);
+
+ ptr_key = gui_key_new (NULL, GUI_KEY_CONTEXT_MOUSE,
+ "@bar(nicklist)>chat:button1", "/print button1", 1);
+ CHECK(ptr_key);
+ STRCMP_EQUAL("@bar(nicklist)>chat:button1", ptr_key->key);
+ LONGS_EQUAL(1, ptr_key->chunks_count);
+ STRCMP_EQUAL("@bar(nicklist)>chat:button1", ptr_key->chunks[0]);
+ LONGS_EQUAL(GUI_KEY_FOCUS_BAR, ptr_key->area_type[0]);
+ LONGS_EQUAL(GUI_KEY_FOCUS_CHAT, ptr_key->area_type[1]);
+ STRCMP_EQUAL("button1", ptr_key->area_key);
+ STRCMP_EQUAL("/print button1", ptr_key->command);
+ LONGS_EQUAL(272, ptr_key->score);
+ gui_key_free (GUI_KEY_CONTEXT_MOUSE,
+ &gui_keys[GUI_KEY_CONTEXT_MOUSE],
+ &last_gui_key[GUI_KEY_CONTEXT_MOUSE],
+ &gui_keys_count[GUI_KEY_CONTEXT_MOUSE],
+ ptr_key,
+ 1);
}
/*
@@ -997,7 +1179,79 @@ TEST(GuiKey, New)
TEST(GuiKey, Search)
{
- /* TODO: write tests */
+ struct t_gui_key *ptr_key;
+
+ POINTERS_EQUAL(NULL, gui_key_search (NULL, NULL));
+ POINTERS_EQUAL(NULL, gui_key_search (NULL, "meta-a"));
+ POINTERS_EQUAL(NULL,
+ gui_key_search (
+ gui_keys[GUI_KEY_CONTEXT_DEFAULT], NULL));
+ POINTERS_EQUAL(NULL,
+ gui_key_search (
+ gui_keys[GUI_KEY_CONTEXT_DEFAULT], ""));
+ POINTERS_EQUAL(NULL,
+ gui_key_search (
+ gui_keys[GUI_KEY_CONTEXT_DEFAULT], "meta-"));
+ POINTERS_EQUAL(NULL,
+ gui_key_search (
+ gui_keys[GUI_KEY_CONTEXT_DEFAULT], "unknown"));
+ POINTERS_EQUAL(NULL,
+ gui_key_search (
+ gui_keys[GUI_KEY_CONTEXT_SEARCH], "meta-a"));
+ POINTERS_EQUAL(NULL,
+ gui_key_search (
+ gui_keys[GUI_KEY_CONTEXT_CURSOR], "meta-a"));
+ POINTERS_EQUAL(NULL,
+ gui_key_search (
+ gui_keys[GUI_KEY_CONTEXT_MOUSE], "meta-a"));
+
+ ptr_key = gui_key_search (gui_keys[GUI_KEY_CONTEXT_DEFAULT], "meta-a");
+ CHECK(ptr_key);
+ STRCMP_EQUAL("meta-a", ptr_key->key);
+ STRCMP_EQUAL("/buffer jump smart", ptr_key->command);
+
+ ptr_key = gui_key_search (gui_keys[GUI_KEY_CONTEXT_DEFAULT],
+ "meta-w,meta-up");
+ CHECK(ptr_key);
+ STRCMP_EQUAL("meta-w,meta-up", ptr_key->key);
+ STRCMP_EQUAL("/window up", ptr_key->command);
+}
+
+/*
+ * Tests functions:
+ * gui_key_compare_chunks
+ */
+
+TEST(GuiKey, CompareChunks)
+{
+ struct t_gui_key *ptr_key1, *ptr_key2;
+
+ ptr_key1 = gui_key_search (gui_keys[GUI_KEY_CONTEXT_DEFAULT], "meta-a");
+ ptr_key2 = gui_key_search (gui_keys[GUI_KEY_CONTEXT_DEFAULT], "meta-w,meta-down");
+ LONGS_EQUAL(0,
+ gui_key_compare_chunks (
+ (const char **)ptr_key1->chunks, ptr_key1->chunks_count,
+ (const char **)ptr_key2->chunks, ptr_key2->chunks_count));
+
+ ptr_key1 = gui_key_new (NULL, GUI_KEY_CONTEXT_DEFAULT, "meta-w", "/mute", 1);
+ ptr_key2 = gui_key_search (gui_keys[GUI_KEY_CONTEXT_DEFAULT], "meta-w,meta-down");
+ LONGS_EQUAL(1,
+ gui_key_compare_chunks (
+ (const char **)ptr_key1->chunks, ptr_key1->chunks_count,
+ (const char **)ptr_key2->chunks, ptr_key2->chunks_count));
+ gui_key_free (GUI_KEY_CONTEXT_MOUSE,
+ &gui_keys[GUI_KEY_CONTEXT_MOUSE],
+ &last_gui_key[GUI_KEY_CONTEXT_MOUSE],
+ &gui_keys_count[GUI_KEY_CONTEXT_MOUSE],
+ ptr_key1,
+ 1);
+
+ ptr_key1 = gui_key_search (gui_keys[GUI_KEY_CONTEXT_DEFAULT], "meta-w,meta-down");
+ ptr_key2 = gui_key_search (gui_keys[GUI_KEY_CONTEXT_DEFAULT], "meta-w,meta-down");
+ LONGS_EQUAL(2,
+ gui_key_compare_chunks (
+ (const char **)ptr_key1->chunks, ptr_key1->chunks_count,
+ (const char **)ptr_key2->chunks, ptr_key2->chunks_count));
}
/*
@@ -1007,7 +1261,63 @@ TEST(GuiKey, Search)
TEST(GuiKey, SearchPart)
{
- /* TODO: write tests */
+ struct t_gui_key *new_key, *ptr_key;
+ char **chunks1, **chunks2;
+ int chunks1_count, chunks2_count, exact_match;
+
+ chunks1 = string_split ("meta-a", ",", NULL, 0, 0, &chunks1_count);
+ chunks2 = string_split ("meta-w", ",", NULL, 0, 0, &chunks2_count);
+
+ POINTERS_EQUAL(NULL, gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT,
+ NULL, 0, NULL, 0, NULL));
+ POINTERS_EQUAL(NULL, gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT,
+ (const char **)chunks1, 0,
+ NULL, 0,
+ NULL));
+ POINTERS_EQUAL(NULL, gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT,
+ NULL, 0,
+ (const char **)chunks2, 0,
+ NULL));
+ POINTERS_EQUAL(NULL, gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT,
+ (const char **)chunks1, 0,
+ (const char **)chunks2, 0,
+ NULL));
+
+ exact_match = -1;
+ ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT,
+ (const char **)chunks1, chunks1_count,
+ NULL, 0,
+ &exact_match);
+ CHECK(ptr_key);
+ STRCMP_EQUAL("meta-a", ptr_key->key);
+ LONGS_EQUAL(1, exact_match);
+
+ exact_match = -1;
+ ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT,
+ NULL, 0,
+ (const char **)chunks2, chunks2_count,
+ &exact_match);
+ CHECK(ptr_key);
+ STRCMP_EQUAL("meta-w,meta-b", ptr_key->key);
+ LONGS_EQUAL(0, exact_match);
+
+ new_key = gui_key_new (NULL, GUI_KEY_CONTEXT_DEFAULT, "meta-w", "/mute", 1);
+
+ exact_match = -1;
+ ptr_key = gui_key_search_part (NULL, GUI_KEY_CONTEXT_DEFAULT,
+ NULL, 0,
+ (const char **)chunks2, chunks2_count,
+ &exact_match);
+ CHECK(ptr_key);
+ STRCMP_EQUAL("meta-w", ptr_key->key);
+ LONGS_EQUAL(1, exact_match);
+
+ gui_key_free (GUI_KEY_CONTEXT_DEFAULT,
+ &gui_keys[GUI_KEY_CONTEXT_DEFAULT],
+ &last_gui_key[GUI_KEY_CONTEXT_DEFAULT],
+ &gui_keys_count[GUI_KEY_CONTEXT_DEFAULT],
+ new_key,
+ 1);
}
/*