[gnome-builder] xml-pack: start autocompletion on attributes value
- From: Sébastien Lafargue <slafargue src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] xml-pack: start autocompletion on attributes value
- Date: Tue, 18 Jul 2017 16:44:36 +0000 (UTC)
commit 997fedf20099846f79a81264710dc8ed0cf188b3
Author: Sebastien Lafargue <slafargue gnome org>
Date: Tue Jul 18 18:35:34 2017 +0200
xml-pack: start autocompletion on attributes value
plugins/xml-pack/ide-xml-completion-attributes.c | 23 +-
plugins/xml-pack/ide-xml-completion-attributes.h | 10 +-
plugins/xml-pack/ide-xml-completion-provider.c | 98 +++++++-
plugins/xml-pack/ide-xml-completion-values.c | 301 ++++++++++++++++++++++
plugins/xml-pack/ide-xml-completion-values.h | 42 +++
plugins/xml-pack/ide-xml-parser.c | 26 +--
plugins/xml-pack/ide-xml-position.c | 17 +-
plugins/xml-pack/ide-xml-rng-define.c | 4 +-
plugins/xml-pack/ide-xml-rng-parser.c | 5 +-
plugins/xml-pack/ide-xml-symbol-node.c | 88 +++++--
plugins/xml-pack/ide-xml-symbol-node.h | 8 +-
plugins/xml-pack/meson.build | 2 +
12 files changed, 551 insertions(+), 73 deletions(-)
---
diff --git a/plugins/xml-pack/ide-xml-completion-attributes.c
b/plugins/xml-pack/ide-xml-completion-attributes.c
index ea1f5e3..3efe176 100644
--- a/plugins/xml-pack/ide-xml-completion-attributes.c
+++ b/plugins/xml-pack/ide-xml-completion-attributes.c
@@ -36,9 +36,10 @@ static GPtrArray * process_matching_state (MatchingState *state,
IdeXmlRngDefine *define);
static MatchItem *
-match_item_new (const gchar *attr_name,
- gint attr_pos,
- gboolean is_optional)
+match_item_new (IdeXmlRngDefine *define,
+ const gchar *attr_name,
+ gint attr_pos,
+ gboolean is_optional)
{
MatchItem *item;
@@ -46,6 +47,7 @@ match_item_new (const gchar *attr_name,
item = g_slice_new0 (MatchItem);
+ item->define = define;
item->name = g_strdup (attr_name);
item->pos = attr_pos;
item->is_optional = is_optional;
@@ -83,7 +85,7 @@ match_children_add (GPtrArray *to_children,
for (gint i = 0; i < from_children->len; ++i)
{
from_item = g_ptr_array_index (from_children, i);
- to_item = match_item_new (from_item->name, from_item->pos, from_item->is_optional);
+ to_item = match_item_new (from_item->define, from_item->name, from_item->pos, from_item->is_optional);
g_ptr_array_add (to_children, to_item);
}
}
@@ -132,7 +134,7 @@ process_attribute (MatchingState *state)
if (ide_str_empty0 (name))
return match_children;
- item = match_item_new (name, state->define->pos, state->is_optional);
+ item = match_item_new (state->define, name, state->define->pos, state->is_optional);
g_ptr_array_add (match_children, item);
return match_children;
@@ -367,7 +369,7 @@ create_initial_matching_state (IdeXmlRngDefine *define,
IdeXmlSymbolNode *node)
{
MatchingState *state;
- const gchar **attributes;
+ gchar **attributes;
g_assert (define != NULL);
@@ -378,6 +380,8 @@ create_initial_matching_state (IdeXmlRngDefine *define,
{
for (gint i = 0; attributes [i] != NULL; i++)
g_ptr_array_add (state->node_attr, (gchar *)attributes [i]);
+
+ g_free (attributes);
}
}
@@ -555,7 +559,8 @@ set_attributes_position (MatchingState *state,
/* Return an array of MatchItem */
GPtrArray *
ide_xml_completion_attributes_get_matches (IdeXmlRngDefine *define,
- IdeXmlSymbolNode *node)
+ IdeXmlSymbolNode *node,
+ gboolean filtered)
{
MatchingState *initial_state;
GPtrArray *match_children;
@@ -571,7 +576,9 @@ ide_xml_completion_attributes_get_matches (IdeXmlRngDefine *define,
initial_state->is_initial_state = TRUE;
match_children = process_matching_state (initial_state, define);
- match_children_filter (match_children, initial_state->node_attr);
+
+ if (filtered)
+ match_children_filter (match_children, initial_state->node_attr);
matching_state_free (initial_state);
return match_children;
diff --git a/plugins/xml-pack/ide-xml-completion-attributes.h
b/plugins/xml-pack/ide-xml-completion-attributes.h
index bcd7cef..a029485 100644
--- a/plugins/xml-pack/ide-xml-completion-attributes.h
+++ b/plugins/xml-pack/ide-xml-completion-attributes.h
@@ -30,13 +30,15 @@ G_BEGIN_DECLS
typedef struct _MatchItem
{
- gchar *name;
- gint pos;
- gboolean is_optional;
+ IdeXmlRngDefine *define;
+ gchar *name;
+ gint pos;
+ gboolean is_optional;
} MatchItem;
GPtrArray *ide_xml_completion_attributes_get_matches (IdeXmlRngDefine *define,
- IdeXmlSymbolNode *node);
+ IdeXmlSymbolNode *node,
+ gboolean filtered);
G_END_DECLS
diff --git a/plugins/xml-pack/ide-xml-completion-provider.c b/plugins/xml-pack/ide-xml-completion-provider.c
index bdc2750..f19e147 100644
--- a/plugins/xml-pack/ide-xml-completion-provider.c
+++ b/plugins/xml-pack/ide-xml-completion-provider.c
@@ -24,6 +24,7 @@
#include "ide.h"
#include "ide-xml-completion-attributes.h"
+#include "ide-xml-completion-values.h"
#include "ide-xml-path.h"
#include "ide-xml-position.h"
#include "ide-xml-rng-define.h"
@@ -776,12 +777,12 @@ get__element_proposals (IdeXmlPosition *position,
if (ide_xml_position_get_kind (position) == IDE_XML_POSITION_KIND_IN_CONTENT)
start = "<";
- for (gint j = 0; j < items->len; ++j)
+ for (gint i = 0; i < items->len; ++i)
{
g_autofree gchar *label = NULL;
g_autofree gchar *text = NULL;
- completion_item = g_ptr_array_index (items, j);
+ completion_item = g_ptr_array_index (items, i);
label = g_strconcat ("<", completion_item->label, ">", NULL);
text = g_strconcat (start, completion_item->label, ">", "</", completion_item->label, ">", NULL);
item = g_object_new (GTK_SOURCE_TYPE_COMPLETION_ITEM,
@@ -805,15 +806,15 @@ get_attributes_proposals (IdeXmlPosition *position,
GList *results = NULL;
node = ide_xml_position_get_child_node (position);
- if (NULL != (attributes = ide_xml_completion_attributes_get_matches (define, node)))
+ if (NULL != (attributes = ide_xml_completion_attributes_get_matches (define, node, TRUE)))
{
- for (gint j = 0; j < attributes->len; ++j)
+ for (gint i = 0; i < attributes->len; ++i)
{
g_autofree gchar *name = NULL;
g_autofree gchar *text = NULL;
MatchItem *match_item;
- match_item = g_ptr_array_index (attributes, j);
+ match_item = g_ptr_array_index (attributes, i);
/* XXX: can't get the markup working, add () */
if (match_item->is_optional)
name = g_strconcat ("<i>(", match_item->name, ")</i>", NULL);
@@ -833,6 +834,65 @@ get_attributes_proposals (IdeXmlPosition *position,
return results;
}
+static GList *
+get_values_proposals (IdeXmlPosition *position,
+ IdeXmlRngDefine *define)
+{
+ IdeXmlSymbolNode *node;
+ IdeXmlRngDefine *attr_define = NULL;
+ g_autoptr(GPtrArray) attributes = NULL;
+ g_autoptr(GPtrArray) values = NULL;
+ GtkSourceCompletionItem *item;
+ GList *results = NULL;
+
+ node = ide_xml_position_get_child_node (position);
+ g_assert (!ide_str_empty0 (position->detail_name));
+
+ if (NULL != (attributes = ide_xml_completion_attributes_get_matches (define, node, FALSE)))
+ {
+ MatchItem *match_item;
+ const gchar *detail_name;
+ const gchar *detail_value;
+ const gchar *content;
+
+ detail_name = ide_xml_position_get_detail_name (position);
+ detail_value = ide_xml_position_get_detail_value (position);
+
+ for (gint j = 0; j < attributes->len; ++j)
+ {
+ match_item = g_ptr_array_index (attributes, j);
+ if (ide_str_equal0 (detail_name, match_item->name))
+ {
+ attr_define = match_item->define;
+ break;
+ }
+ }
+
+ if (attr_define != NULL)
+ {
+ ide_xml_symbol_node_print (node, 0, FALSE, TRUE, TRUE);
+ content = ide_xml_symbol_node_get_attribute_value (node, match_item->name);
+
+ if (NULL != (values = ide_xml_completion_values_get_matches (attr_define, content, detail_value)))
+ {
+ for (gint i = 0; i < values->len; ++i)
+ {
+ ValueMatchItem *value_match_item = g_ptr_array_index (values, i);
+
+ item = g_object_new (GTK_SOURCE_TYPE_COMPLETION_ITEM,
+ "markup", value_match_item->name,
+ "text", value_match_item->name,
+ NULL);
+
+ results = g_list_prepend (results, item);
+ }
+ }
+ }
+ }
+
+ return results;
+}
+
static void
populate_cb (GObject *object,
GAsyncResult *result,
@@ -854,7 +914,8 @@ populate_cb (GObject *object,
g_autoptr (GPtrArray) items = NULL;
GError *error = NULL;
gint child_pos;
- gboolean complete_attributes;
+ gboolean complete_attributes = FALSE;
+ gboolean complete_values = FALSE;
g_assert (IDE_IS_XML_COMPLETION_PROVIDER (self));
g_assert (IDE_IS_XML_SERVICE (service));
@@ -868,10 +929,15 @@ populate_cb (GObject *object,
detail = ide_xml_position_get_detail (position);
child_pos = ide_xml_position_get_child_pos (position);
- complete_attributes = ((kind == IDE_XML_POSITION_KIND_IN_START_TAG || kind ==
IDE_XML_POSITION_KIND_IN_END_TAG) &&
- detail == IDE_XML_POSITION_DETAIL_IN_ATTRIBUTE_NAME);
+ if (kind == IDE_XML_POSITION_KIND_IN_START_TAG || kind == IDE_XML_POSITION_KIND_IN_END_TAG)
+ {
+ if (detail == IDE_XML_POSITION_DETAIL_IN_ATTRIBUTE_NAME)
+ complete_attributes = TRUE;
+ else if (detail == IDE_XML_POSITION_DETAIL_IN_ATTRIBUTE_VALUE)
+ complete_values = TRUE;
+ }
- if (complete_attributes)
+ if (complete_attributes || complete_values)
{
IdeXmlSymbolNode *child_node;
@@ -902,6 +968,20 @@ populate_cb (GObject *object,
TRUE);
}
}
+ else if (complete_values)
+ {
+ for (gint i = 0; i < candidates->len; ++i)
+ {
+ g_autoptr (GList) results = NULL;
+
+ def = g_ptr_array_index (candidates, i);
+ results = get_values_proposals (position, def);
+ gtk_source_completion_context_add_proposals (state->completion_context,
+ GTK_SOURCE_COMPLETION_PROVIDER (self),
+ results,
+ TRUE);
+ }
+ }
else
{
g_autoptr (GList) results = NULL;
diff --git a/plugins/xml-pack/ide-xml-completion-values.c b/plugins/xml-pack/ide-xml-completion-values.c
new file mode 100644
index 0000000..333c16d
--- /dev/null
+++ b/plugins/xml-pack/ide-xml-completion-values.c
@@ -0,0 +1,301 @@
+/* ide-xml-completion-values.c
+ *
+ * Copyright (C) 2017 Sebastien Lafargue <slafargue gnome org>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ide-xml-completion-values.h"
+#include "ide-xml-position.h"
+
+typedef struct _MatchingState
+{
+ IdeXmlRngDefine *define;
+ GPtrArray *match_values;
+ const gchar *values;
+ const gchar *prefix;
+
+ guint is_initial_state : 1;
+} MatchingState;
+
+static GPtrArray * process_matching_state (MatchingState *state,
+ IdeXmlRngDefine *define);
+
+static ValueMatchItem *
+value_match_item_new (const gchar *value)
+{
+ ValueMatchItem *item;
+
+ g_assert (!ide_str_empty0 (value));
+
+ item = g_slice_new0 (ValueMatchItem);
+ item->name = g_strdup (value);
+
+ return item;
+}
+
+static void
+value_match_item_free (gpointer data)
+{
+ ValueMatchItem *item = (ValueMatchItem *)data;
+
+ g_clear_pointer (&item->name, g_free);
+ g_slice_free (ValueMatchItem, item);
+}
+
+static GPtrArray *
+match_values_new (void)
+{
+ GPtrArray *ar;
+
+ ar = g_ptr_array_new_with_free_func ((GDestroyNotify)value_match_item_free);
+ return ar;
+}
+
+static void
+match_values_add (GPtrArray *to_values,
+ GPtrArray *from_values)
+{
+ ValueMatchItem *to_item;
+ ValueMatchItem *from_item;
+
+ g_assert (to_values != NULL);
+
+ if (from_values == NULL)
+ return;
+
+ for (gint i = 0; i < from_values->len; ++i)
+ {
+ from_item = g_ptr_array_index (from_values, i);
+ to_item = value_match_item_new (from_item->name);
+ g_ptr_array_add (to_values, to_item);
+ }
+}
+
+static MatchingState *
+matching_state_new (IdeXmlRngDefine *define,
+ const gchar *values,
+ const gchar *prefix)
+{
+ MatchingState *state;
+
+ g_assert (define != NULL);
+
+ state = g_slice_new0 (MatchingState);
+
+ state->define = define;
+ state->values = (values != NULL) ? g_strdup (values) : NULL;
+ state->prefix = (prefix != NULL) ? g_strdup (prefix) : NULL;
+
+ state->is_initial_state = FALSE;
+
+ return state;
+}
+
+static void
+matching_state_free (MatchingState *state)
+{
+ g_clear_pointer (&state->values, g_free);
+ g_clear_pointer (&state->prefix, g_free);
+}
+
+static GPtrArray *
+process_value (MatchingState *state)
+{
+ GPtrArray *match_values = NULL;
+ ValueMatchItem *item;
+ const gchar *value;
+
+ g_assert (state->define->type == IDE_XML_RNG_DEFINE_VALUE);
+
+ value = (gchar *)state->define->name;
+
+ if (!ide_str_empty0 (value) &&
+ (ide_str_empty0 (state->prefix) || g_str_has_prefix (value, state->prefix)))
+ {
+ match_values = match_values_new ();
+ item = value_match_item_new (value);
+ g_ptr_array_add (match_values, item);
+ }
+
+ return match_values;
+}
+
+static GPtrArray *
+process_choice (MatchingState *state)
+{
+ GPtrArray *match_values = NULL;
+ IdeXmlRngDefine *defines;
+
+ g_assert (state->define->type == IDE_XML_RNG_DEFINE_CHOICE);
+
+ if (NULL != (defines = state->define->content))
+ {
+ match_values = match_values_new ();
+ while (defines != NULL)
+ {
+ g_autoptr (GPtrArray) match = NULL;
+
+ if (NULL != (match = process_matching_state (state, defines)))
+ {
+ /* TODO: use move */
+ match_values_add (match_values, match);
+ }
+
+ defines = defines->next;
+ }
+ }
+
+ return match_values;
+}
+
+static GPtrArray *
+process_group (MatchingState *state)
+{
+ GPtrArray *match_values = NULL;
+ IdeXmlRngDefine *defines;
+
+ g_assert (state->define->type == IDE_XML_RNG_DEFINE_GROUP ||
+ state->define->type == IDE_XML_RNG_DEFINE_ATTRIBUTE ||
+ state->define->type == IDE_XML_RNG_DEFINE_ZEROORMORE ||
+ state->define->type == IDE_XML_RNG_DEFINE_ONEORMORE ||
+ state->define->type == IDE_XML_RNG_DEFINE_OPTIONAL);
+
+ if (NULL != (defines = state->define->content))
+ {
+ while (defines != NULL)
+ {
+ g_autoptr (GPtrArray) match = NULL;
+
+ match_values = match_values_new ();
+ if (NULL != (match = process_matching_state (state, defines)))
+ {
+ match_values_add (match_values, match);
+ }
+
+ defines = defines->next;
+ }
+ }
+
+ return match_values;
+}
+
+static GPtrArray *
+process_matching_state (MatchingState *state,
+ IdeXmlRngDefine *define)
+{
+ IdeXmlRngDefine *old_define;
+ IdeXmlRngDefineType type;
+ GPtrArray *match_values;
+
+ g_assert (state != NULL);
+ g_assert (define != NULL);
+
+ old_define = state->define;
+ state->define = define;
+
+ if (state->is_initial_state)
+ {
+ state->is_initial_state = FALSE;
+ type = IDE_XML_RNG_DEFINE_GROUP;
+ }
+ else
+ type = define->type;
+
+ switch (type)
+ {
+ case IDE_XML_RNG_DEFINE_VALUE:
+ match_values = process_value (state);
+ break;
+
+ case IDE_XML_RNG_DEFINE_ATTRIBUTE:
+ case IDE_XML_RNG_DEFINE_ATTRIBUTES_GROUP:
+ case IDE_XML_RNG_DEFINE_NOOP:
+ case IDE_XML_RNG_DEFINE_NOTALLOWED:
+ case IDE_XML_RNG_DEFINE_TEXT:
+ case IDE_XML_RNG_DEFINE_DATATYPE:
+ case IDE_XML_RNG_DEFINE_EMPTY:
+ case IDE_XML_RNG_DEFINE_ELEMENT:
+ case IDE_XML_RNG_DEFINE_START:
+ case IDE_XML_RNG_DEFINE_PARAM:
+ case IDE_XML_RNG_DEFINE_EXCEPT:
+ case IDE_XML_RNG_DEFINE_LIST:
+ match_values = NULL;
+ break;
+
+ case IDE_XML_RNG_DEFINE_DEFINE:
+ case IDE_XML_RNG_DEFINE_REF:
+ case IDE_XML_RNG_DEFINE_PARENTREF:
+ case IDE_XML_RNG_DEFINE_EXTERNALREF:
+ match_values = process_matching_state (state, define->content);
+ break;
+
+ case IDE_XML_RNG_DEFINE_INTERLEAVE:
+ case IDE_XML_RNG_DEFINE_GROUP:
+ case IDE_XML_RNG_DEFINE_ZEROORMORE:
+ case IDE_XML_RNG_DEFINE_ONEORMORE:
+ case IDE_XML_RNG_DEFINE_OPTIONAL:
+ match_values = process_group (state);
+ break;
+
+ case IDE_XML_RNG_DEFINE_CHOICE:
+ match_values = process_choice (state);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ state->define = old_define;
+
+ return match_values;
+}
+
+static MatchingState *
+create_initial_matching_state (IdeXmlRngDefine *define,
+ const gchar *values,
+ const gchar *prefix)
+{
+ MatchingState *state;
+
+ g_assert (define != NULL);
+
+ state = matching_state_new (define, values, prefix);
+ state->is_initial_state = TRUE;
+
+ return state;
+}
+
+/* Return an array of ValueMatchItem */
+GPtrArray *
+ide_xml_completion_values_get_matches (IdeXmlRngDefine *define,
+ const gchar *values,
+ const gchar *prefix)
+{
+ MatchingState *initial_state;
+ GPtrArray *match_values = NULL;
+
+ g_return_val_if_fail (define != NULL, NULL);
+
+ if (define->content != NULL)
+ {
+ initial_state = create_initial_matching_state (define, values, prefix);
+
+ initial_state->is_initial_state = TRUE;
+ match_values = process_matching_state (initial_state, define);
+ matching_state_free (initial_state);
+ }
+
+ return match_values;
+}
diff --git a/plugins/xml-pack/ide-xml-completion-values.h b/plugins/xml-pack/ide-xml-completion-values.h
new file mode 100644
index 0000000..07baae7
--- /dev/null
+++ b/plugins/xml-pack/ide-xml-completion-values.h
@@ -0,0 +1,42 @@
+/* ide-xml-completion-values.h
+ *
+ * Copyright (C) 2017 Sebastien Lafargue <slafargue gnome org>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IDE_XML_COMPLETION_VALUES_H
+#define IDE_XML_COMPLETION_VALUES_H
+
+#include <glib.h>
+
+#include <ide.h>
+
+#include "ide-xml-rng-define.h"
+#include "ide-xml-symbol-node.h"
+
+G_BEGIN_DECLS
+
+typedef struct _ValueMatchItem
+{
+ gchar *name;
+} ValueMatchItem;
+
+GPtrArray *ide_xml_completion_values_get_matches (IdeXmlRngDefine *define,
+ const gchar *values,
+ const gchar *prefix);
+
+G_END_DECLS
+
+#endif /* IDE_XML_COMPLETION_VALUES_H */
diff --git a/plugins/xml-pack/ide-xml-parser.c b/plugins/xml-pack/ide-xml-parser.c
index cfa399a..3a6cc83 100644
--- a/plugins/xml-pack/ide-xml-parser.c
+++ b/plugins/xml-pack/ide-xml-parser.c
@@ -150,28 +150,6 @@ ide_xml_parser_create_diagnostic (ParserState *state,
return diagnostic;
}
-static gchar **
-fetch_attributes_names (IdeXmlParser *self,
- const gchar **attributes)
-{
- GPtrArray *attrs;
-
- g_assert (IDE_IS_XML_PARSER (self));
-
- if (attributes == NULL)
- return NULL;
-
- attrs = g_ptr_array_new ();
- while (attributes [0] != NULL)
- {
- g_ptr_array_add (attrs, g_strdup (attributes [0]));
- attributes += 2;
- }
-
- g_ptr_array_add (attrs, NULL);
- return (gchar**)g_ptr_array_free (attrs, FALSE);
-}
-
void
ide_xml_parser_state_processing (IdeXmlParser *self,
ParserState *state,
@@ -236,7 +214,7 @@ ide_xml_parser_state_processing (IdeXmlParser *self,
ide_xml_symbol_node_take_internal_child (state->parent_node, node);
state->parent_node = node;
- ide_xml_symbol_node_take_attributes_names (node, fetch_attributes_names (self, state->attributes));
+ ide_xml_symbol_node_set_attributes (node, state->attributes);
state->attributes = NULL;
}
else if (callback_type == IDE_XML_SAX_CALLBACK_TYPE_END_ELEMENT)
@@ -292,7 +270,7 @@ ide_xml_parser_state_processing (IdeXmlParser *self,
ide_xml_symbol_node_take_child (state->parent_node, node);
state->parent_node = node;
- ide_xml_symbol_node_take_attributes_names (node, fetch_attributes_names (self, state->attributes));
+ ide_xml_symbol_node_set_attributes (node, state->attributes);
state->attributes = NULL;
}
else if (callback_type == IDE_XML_SAX_CALLBACK_TYPE_END_ELEMENT)
diff --git a/plugins/xml-pack/ide-xml-position.c b/plugins/xml-pack/ide-xml-position.c
index bcd95ae..29312d3 100644
--- a/plugins/xml-pack/ide-xml-position.c
+++ b/plugins/xml-pack/ide-xml-position.c
@@ -296,16 +296,25 @@ ide_xml_position_print (IdeXmlPosition *self)
if (self->node != NULL)
{
- const gchar **attributes_names;
+ gchar **attributes_names;
+ gchar **attributes_names_cursor;
IdeXmlSymbolNode *node;
if (NULL != (attributes_names = ide_xml_symbol_node_get_attributes_names (self->node)))
{
- while (attributes_names [0] != NULL)
+ attributes_names_cursor = attributes_names;
+ while (attributes_names_cursor [0] != NULL)
{
- printf ("attr:%s\n", *attributes_names);
- ++attributes_names;
+ g_autofree gchar *name = NULL;
+ const gchar *value;
+
+ name = g_strdup (attributes_names [0]);
+ value = ide_xml_symbol_node_get_attribute_value (self->node, name);
+ printf ("attr:%s=%s\n", name, value);
+ ++attributes_names_cursor;
}
+
+ g_strfreev (attributes_names);
}
if ((n_children = ide_xml_symbol_node_get_n_direct_children (self->node)) > 0)
diff --git a/plugins/xml-pack/ide-xml-rng-define.c b/plugins/xml-pack/ide-xml-rng-define.c
index a8f0f5d..9e60f74 100644
--- a/plugins/xml-pack/ide-xml-rng-define.c
+++ b/plugins/xml-pack/ide-xml-rng-define.c
@@ -170,10 +170,10 @@ ide_xml_rng_define_free (IdeXmlRngDefine *self)
if (self->content != NULL)
ide_xml_rng_define_unref (self->content);
- if (self->content != NULL)
+ if (self->attributes != NULL)
ide_xml_rng_define_unref (self->attributes);
- if (self->content != NULL)
+ if (self->name_class != NULL)
ide_xml_rng_define_unref (self->name_class);
g_slice_free (IdeXmlRngDefine, self);
diff --git a/plugins/xml-pack/ide-xml-rng-parser.c b/plugins/xml-pack/ide-xml-rng-parser.c
index 6aaf957..335fc28 100644
--- a/plugins/xml-pack/ide-xml-rng-parser.c
+++ b/plugins/xml-pack/ide-xml-rng-parser.c
@@ -809,11 +809,14 @@ parse_value (IdeXmlRngParser *self,
xmlNode *node)
{
IdeXmlRngDefine *def = NULL;
+ guchar *name;
g_assert (IDE_IS_XML_RNG_PARSER (self));
g_assert (node != NULL);
- /* TODO: not done for now */
+ /* TODO: datatype library part */
+ name = _strip (xmlNodeGetContent(node));
+ def = ide_xml_rng_define_new (node, self->current_def, name, IDE_XML_RNG_DEFINE_VALUE);
return def;
}
diff --git a/plugins/xml-pack/ide-xml-symbol-node.c b/plugins/xml-pack/ide-xml-symbol-node.c
index d93c9e6..e0c5809 100644
--- a/plugins/xml-pack/ide-xml-symbol-node.c
+++ b/plugins/xml-pack/ide-xml-symbol-node.c
@@ -21,6 +21,12 @@
#include "ide-xml-symbol-node.h"
+typedef struct _Attribute
+{
+ gchar *name;
+ gchar *value;
+} Attribute;
+
typedef struct _NodeEntry
{
IdeXmlSymbolNode *node;
@@ -47,7 +53,7 @@ struct _IdeXmlSymbolNode
gint nb_children;
gint nb_internal_children;
GFile *file;
- gchar **attributes_names;
+ GArray *attributes;
gchar *ns;
IdeXmlSymbolNodeState state;
NodeRange start_tag;
@@ -115,6 +121,7 @@ ide_xml_symbol_node_finalize (GObject *object)
IdeXmlSymbolNode *self = (IdeXmlSymbolNode *)object;
g_clear_pointer (&self->children, g_array_unref);
+ g_clear_pointer (&self->attributes, g_array_unref);
g_clear_pointer (&self->element_name, g_free);
g_clear_pointer (&self->value, g_free);
@@ -122,9 +129,6 @@ ide_xml_symbol_node_finalize (GObject *object)
g_clear_object (&self->file);
g_clear_object (&self->parent);
- if (self->attributes_names != NULL)
- g_strfreev (self->attributes_names);
-
G_OBJECT_CLASS (ide_xml_symbol_node_parent_class)->finalize (object);
}
@@ -661,23 +665,69 @@ ide_xml_symbol_node_compare_location (IdeXmlSymbolNode *ref_node,
}
void
-ide_xml_symbol_node_take_attributes_names (IdeXmlSymbolNode *self,
- gchar **attributes_names)
+ide_xml_symbol_node_set_attributes (IdeXmlSymbolNode *self,
+ const gchar **attributes)
{
+ Attribute attr;
+
g_return_if_fail (IDE_IS_XML_SYMBOL_NODE (self));
- if (self->attributes_names != NULL)
- g_strfreev (self->attributes_names);
+ g_clear_pointer (&self->attributes, g_array_unref);
+ if (attributes == NULL)
+ return;
- self->attributes_names = attributes_names;
+ self->attributes = g_array_new (FALSE, FALSE, sizeof (Attribute));
+ while (attributes [0] != NULL)
+ {
+ attr.name = g_strdup (attributes [0]);
+ attr.value = (attributes [1] != NULL) ? g_strdup (attributes [1]) : NULL;
+ g_array_append_val (self->attributes, attr);
+ attributes += 2;
+ }
}
-const gchar **
+gchar **
ide_xml_symbol_node_get_attributes_names (IdeXmlSymbolNode *self)
{
+ Attribute *attr;
+ GPtrArray *ar_names;
+
+ g_return_val_if_fail (IDE_IS_XML_SYMBOL_NODE (self), NULL);
+
+ if (self->attributes == NULL)
+ return NULL;
+
+ ar_names = g_ptr_array_new ();
+ for (gint i = 0; i < self->attributes->len; ++i)
+ {
+ attr = &g_array_index (self->attributes, Attribute, i);
+ g_ptr_array_add (ar_names, g_strdup (attr->name));
+ }
+
+ g_ptr_array_add (ar_names, NULL);
+
+ return (gchar **)g_ptr_array_free (ar_names, FALSE);
+}
+
+const gchar *
+ide_xml_symbol_node_get_attribute_value (IdeXmlSymbolNode *self,
+ const gchar *name)
+{
+ Attribute *attr;
+
g_return_val_if_fail (IDE_IS_XML_SYMBOL_NODE (self), NULL);
- return (const gchar **)self->attributes_names;
+ if (self->attributes == NULL || name == NULL)
+ return NULL;
+
+ for (gint i = 0; i < self->attributes->len; ++i)
+ {
+ attr = &g_array_index (self->attributes, Attribute, i);
+ if (ide_str_equal0 (name, attr->name))
+ return attr->value;
+ }
+
+ return NULL;
}
void
@@ -688,9 +738,9 @@ ide_xml_symbol_node_print (IdeXmlSymbolNode *self,
gboolean show_attributes)
{
g_autofree gchar *spacer;
- gchar **attributes = self->attributes_names;
guint n_children;
IdeXmlSymbolNode *child;
+ Attribute *attr;
g_return_if_fail (IDE_IS_XML_SYMBOL_NODE (self));
@@ -704,12 +754,14 @@ ide_xml_symbol_node_print (IdeXmlSymbolNode *self,
printf ("%s%s state:%d ", spacer, self->element_name, self->state);
print_node_ranges (self);
- if (show_attributes && self->attributes_names != NULL)
- while (*attributes != NULL)
- {
- printf ("%s%s\n", spacer, *attributes);
- ++attributes;
- }
+ if (show_attributes && self->attributes != NULL)
+ {
+ for (gint i = 0; i < self->attributes->len; ++i)
+ {
+ attr = &g_array_index (self->attributes, Attribute, i);
+ printf ("attr '%s':'%s'\n", attr->name, attr->value);
+ }
+ }
if (show_value && self->value != NULL)
printf ("%svalue:%s\n", spacer, self->value);
diff --git a/plugins/xml-pack/ide-xml-symbol-node.h b/plugins/xml-pack/ide-xml-symbol-node.h
index 9a15b80..acbd231 100644
--- a/plugins/xml-pack/ide-xml-symbol-node.h
+++ b/plugins/xml-pack/ide-xml-symbol-node.h
@@ -112,9 +112,11 @@ void ide_xml_symbol_node_set_state
IdeXmlSymbolNodeState
state);
void ide_xml_symbol_node_set_value (IdeXmlSymbolNode
*self,
const gchar
*value);
-const gchar **ide_xml_symbol_node_get_attributes_names (IdeXmlSymbolNode
*self);
-void ide_xml_symbol_node_take_attributes_names (IdeXmlSymbolNode
*self,
- gchar
**attributes_names);
+gchar **ide_xml_symbol_node_get_attributes_names (IdeXmlSymbolNode
*self);
+const gchar *ide_xml_symbol_node_get_attribute_value (IdeXmlSymbolNode
*self,
+ const gchar
*name);
+void ide_xml_symbol_node_set_attributes (IdeXmlSymbolNode
*self,
+ const gchar
**attributes);
G_END_DECLS
diff --git a/plugins/xml-pack/meson.build b/plugins/xml-pack/meson.build
index 593d244..7baa841 100644
--- a/plugins/xml-pack/meson.build
+++ b/plugins/xml-pack/meson.build
@@ -11,6 +11,8 @@ xml_pack_sources = [
'ide-xml-analysis.h',
'ide-xml-completion-attributes.c',
'ide-xml-completion-attributes.h',
+ 'ide-xml-completion-values.c',
+ 'ide-xml-completion-values.h',
'ide-xml-completion-provider.c',
'ide-xml-completion-provider.h',
'ide-xml-diagnostic-provider.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]