[gnome-builder] vim command bar: allow to override GAction commands
- From: Sebastien Lafargue <slafargue src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] vim command bar: allow to override GAction commands
- Date: Wed, 29 Apr 2015 20:54:43 +0000 (UTC)
commit 18c7f17c543c74f7ceb5cf203e2f65b134336e03
Author: Sebastien Lafargue <slafargue gnome org>
Date: Mon Apr 27 22:32:15 2015 +0200
vim command bar: allow to override GAction commands
As GAction discovering give us duplicate names for commands,
we need a way to circumvent that problem:
In gb-command-gaction-provider, GbActionCommandMap action_maps []
gives us a way to define custom commands and the prefix/action name
they mask.
https://bugzilla.gnome.org/show_bug.cgi?id=748652
src/commands/gb-command-gaction-provider.c | 198 ++++++++++++++++++++++++----
1 files changed, 175 insertions(+), 23 deletions(-)
---
diff --git a/src/commands/gb-command-gaction-provider.c b/src/commands/gb-command-gaction-provider.c
index 90ebd63..3fc846a 100644
--- a/src/commands/gb-command-gaction-provider.c
+++ b/src/commands/gb-command-gaction-provider.c
@@ -20,6 +20,7 @@
#include <ide.h>
#include <string.h>
+#include <glib.h>
#include "gb-editor-workspace.h"
#include "gb-editor-view.h"
@@ -30,6 +31,19 @@
G_DEFINE_TYPE (GbCommandGactionProvider, gb_command_gaction_provider, GB_TYPE_COMMAND_PROVIDER)
+typedef struct
+{
+ GActionGroup *group;
+ gchar *prefix;
+} GbGroup;
+
+typedef struct
+{
+ const gchar *command_name;
+ const gchar *prefix;
+ const gchar *action_name;
+} GbActionCommandMap;
+
GbCommandProvider *
gb_command_gaction_provider_new (GbWorkbench *workbench)
{
@@ -38,6 +52,31 @@ gb_command_gaction_provider_new (GbWorkbench *workbench)
NULL);
}
+static GbGroup *
+gb_group_new (GActionGroup *group, const gchar *prefix)
+{
+ GbGroup *gb_group;
+
+ g_assert (group != NULL);
+ g_assert (prefix != NULL && prefix [0] != '\0');
+
+ gb_group = g_new (GbGroup, 1);
+
+ gb_group->group = group;
+ gb_group->prefix = g_strdup (prefix);
+
+ return gb_group;
+}
+
+static void
+gb_group_free (GbGroup *gb_group)
+{
+ g_assert (gb_group != NULL);
+
+ g_free (gb_group->prefix);
+ g_free (gb_group);
+}
+
static GList *
discover_groups (GbCommandGactionProvider *provider)
{
@@ -45,6 +84,7 @@ discover_groups (GbCommandGactionProvider *provider)
GApplication *application;
GbWorkbench *workbench;
GtkWidget *widget;
+ GbGroup *gb_group = NULL;
GList *list = NULL;
gint type;
@@ -68,14 +108,15 @@ discover_groups (GbCommandGactionProvider *provider)
if (prefixes)
{
- GActionGroup *group;
-
for (i = 0; prefixes [i]; i++)
{
- group = gtk_widget_get_action_group (widget, prefixes [i]);
+ GActionGroup *group = gtk_widget_get_action_group (widget, prefixes [i]);
if (G_IS_ACTION_GROUP (group))
- list = g_list_append (list, group);
+ {
+ gb_group = gb_group_new (group, prefixes [i]);
+ list = g_list_append (list, gb_group);
+ }
}
g_free (prefixes);
@@ -83,10 +124,12 @@ discover_groups (GbCommandGactionProvider *provider)
}
workbench = gb_command_provider_get_workbench (GB_COMMAND_PROVIDER (provider));
- list = g_list_append (list, G_ACTION_GROUP (workbench));
+ gb_group = gb_group_new (G_ACTION_GROUP (workbench), "workbench");
+ list = g_list_append (list, gb_group);
application = g_application_get_default ();
- list = g_list_append (list, G_ACTION_GROUP (application));
+ gb_group = gb_group_new (G_ACTION_GROUP (application), "app");
+ list = g_list_append (list, gb_group);
return list;
}
@@ -150,6 +193,64 @@ failure:
return FALSE;
}
+/*
+ * Command names mapping and masking:
+ *
+ * Format: command_name, prefix, action_name
+ * command_name can be NULL so that the specific (prefix, action_name)
+ * is masked in this case.
+ *
+ * As we allow a NULL command_name, you must closed the array with a triple NULL.
+ */
+static const GbActionCommandMap action_maps [] = {
+ { NULL, NULL, NULL }
+};
+
+static gboolean
+search_command_in_maps (const gchar *action_name,
+ const gchar *prefix,
+ const gchar **command_name)
+{
+ guint i;
+
+ for (i = 0; (action_maps [i].prefix != NULL) && (action_maps [i].action_name != NULL); i++)
+ {
+ if (!g_strcmp0 (action_maps [i].prefix, prefix) &&
+ g_str_equal (action_maps [i].action_name, action_name))
+ {
+ *command_name = action_maps [i].command_name;
+ return TRUE;
+ }
+ }
+
+ *command_name = NULL;
+ return FALSE;
+}
+
+static gboolean
+search_action_in_maps (const gchar *command_name,
+ const gchar **action_name,
+ const gchar **prefix)
+{
+ guint i;
+
+ for (i = 0; (action_maps [i].prefix != NULL) && (action_maps [i].action_name != NULL); i++)
+ {
+ if (action_maps [i].command_name == NULL)
+ continue;
+
+ if (!g_strcmp0 (command_name, action_maps [i].command_name))
+ {
+ *action_name = action_maps [i].action_name;
+ *prefix = action_maps [i].prefix;
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
static GbCommand *
gb_command_gaction_provider_lookup (GbCommandProvider *provider,
const gchar *command_text)
@@ -157,38 +258,78 @@ gb_command_gaction_provider_lookup (GbCommandProvider *provider,
GbCommandGactionProvider *self = (GbCommandGactionProvider *)provider;
GbCommand *command = NULL;
GVariant *params = NULL;
- GList *groups;
+ GList *gb_groups;
+ GbGroup *gb_group = NULL;
+ GActionGroup *group = NULL;
GList *iter;
- gchar *action_name = NULL;
+ gchar *command_name = NULL;
+ const gchar *new_command_name = NULL;
+ const gchar *action_name = NULL;
+ const gchar *prefix = NULL;
+ gboolean result = FALSE;
IDE_ENTRY;
g_return_val_if_fail (GB_IS_COMMAND_GACTION_PROVIDER (self), NULL);
g_return_val_if_fail (command_text, NULL);
- if (!parse_command_text (command_text, &action_name, ¶ms))
+ if (!parse_command_text (command_text, &command_name, ¶ms))
IDE_RETURN (NULL);
- groups = discover_groups (self);
+ gb_groups = discover_groups (self);
- for (iter = groups; iter; iter = iter->next)
+ if (search_action_in_maps (command_name, &action_name, &prefix))
{
- GActionGroup *group = G_ACTION_GROUP (iter->data);
+ /* We double-check that the action really exist */
+ for (iter = gb_groups; iter; iter = iter->next)
+ {
+ gb_group = (GbGroup *)iter->data;
+ group = G_ACTION_GROUP (gb_group->group);
- if (g_action_group_has_action (group, action_name))
+ if (g_str_equal (prefix, gb_group->prefix) && g_action_group_has_action (group, action_name))
+ {
+ result = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (!result)
+ {
+ for (iter = gb_groups; iter; iter = iter->next)
{
- command = g_object_new (GB_TYPE_COMMAND_GACTION,
- "action-group", group,
- "action-name", action_name,
- "parameters", params,
- NULL);
- break;
+ gb_group = (GbGroup *)iter->data;
+ group = G_ACTION_GROUP (gb_group->group);
+
+ if (g_action_group_has_action (group, command_name))
+ {
+ /* We must be sure that the action is not masked or overridden */
+ prefix = gb_group->prefix;
+ if (search_command_in_maps (command_name, prefix, &new_command_name))
+ {
+ result = FALSE;
+ break;
+ }
+
+ action_name = command_name;
+ result = TRUE;
+ break;
+ }
}
}
+ if (result)
+ {
+ command = g_object_new (GB_TYPE_COMMAND_GACTION,
+ "action-group", group,
+ "action-name", action_name,
+ "parameters", params,
+ NULL);
+ }
+
g_clear_pointer (¶ms, g_variant_unref);
- g_list_free (groups);
- g_free (action_name);
+ g_free (command_name);
+ g_list_free_full (gb_groups, (GDestroyNotify)gb_group_free);
IDE_RETURN (command);
}
@@ -211,8 +352,11 @@ gb_command_gaction_provider_complete (GbCommandProvider *provider,
for (iter = groups; iter; iter = iter->next)
{
- GActionGroup *group = iter->data;
+ GbGroup *gb_group = iter->data;
+ GActionGroup *group = gb_group->group;
+ gchar *prefix = gb_group->prefix;
gchar **names;
+ const gchar *command_name;
guint i;
g_assert (G_IS_ACTION_GROUP (group));
@@ -221,6 +365,14 @@ gb_command_gaction_provider_complete (GbCommandProvider *provider,
for (i = 0; names [i]; i++)
{
+ if (search_command_in_maps (names [i], prefix, &command_name))
+ {
+ if (command_name != NULL && g_str_has_prefix (command_name, initial_command_text))
+ g_ptr_array_add (completions, g_strdup (command_name));
+
+ continue;
+ }
+
if (g_str_has_prefix (names [i], initial_command_text))
g_ptr_array_add (completions, g_strdup (names [i]));
}
@@ -228,7 +380,7 @@ gb_command_gaction_provider_complete (GbCommandProvider *provider,
g_free (names);
}
- g_list_free (groups);
+ g_list_free_full (groups, (GDestroyNotify)gb_group_free);
IDE_EXIT;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]