Revision: 1326 http://geany-plugins.svn.sourceforge.net/geany-plugins/?rev=1326&view=re... Author: colombanw Date: 2010-05-01 17:48:14 +0000 (Sat, 01 May 2010)
Log Message: ----------- GeanyGenDoc: Fix tag scope detection for non-c-style languages
Don't use hard-coded "::" separator but try to find the right separator for the file type.
Modified Paths: -------------- trunk/geanygendoc/src/ggd-tag-utils.c trunk/geanygendoc/src/ggd-tag-utils.h trunk/geanygendoc/src/ggd.c
Modified: trunk/geanygendoc/src/ggd-tag-utils.c =================================================================== --- trunk/geanygendoc/src/ggd-tag-utils.c 2010-05-01 17:47:37 UTC (rev 1325) +++ trunk/geanygendoc/src/ggd-tag-utils.c 2010-05-01 17:48:14 UTC (rev 1326) @@ -28,6 +28,29 @@ #include "ggd-plugin.h" /* to access Geany data/funcs */
+/* symbols_get_context_separator() borrowed from Geany since it isn't in the + * plugin API yet (API v183) */ +/* FIXME: replace calls to this function with Geany's + * symbols_get_context_separator() when it gets into the plugin API */ +static const gchar * +ggd_tag_utils_get_context_separator (filetype_id geany_ft) +{ + switch (geany_ft) { + case GEANY_FILETYPES_C: /* for C++ .h headers or C structs */ + case GEANY_FILETYPES_CPP: + case GEANY_FILETYPES_GLSL: /* for structs */ + return "::"; + + /* avoid confusion with other possible separators in group/section name */ + case GEANY_FILETYPES_CONF: + case GEANY_FILETYPES_REST: + return ":::"; + + default: + return "."; + } +} + /* * tag_cmp_by_line: * @a: A #TMTag @@ -190,6 +213,7 @@ /** * ggd_tag_find_parent: * @tags: A #GPtrArray of #TMTag<!-- -->s containing @tag + * @geany_ft: The Geany's file type identifier for which tags were generated * @child: A #TMTag, child of the tag to find * * Finds the parent tag of a #TMTag. @@ -198,6 +222,7 @@ */ TMTag * ggd_tag_find_parent (const GPtrArray *tags, + filetype_id geany_ft, const TMTag *child) { TMTag *tag = NULL; @@ -213,17 +238,22 @@ const gchar *tmp; guint i; TMTag *el; + const gchar *separator; + gsize separator_len;
- /* scope is of the form a::b::c */ + /* scope is of the form a<sep>b<sep>c */ parent_name = child->atts.entry.scope; - while ((tmp = strstr (parent_name, "::")) != NULL) { - parent_name = &tmp[2]; + separator = ggd_tag_utils_get_context_separator (geany_ft); + separator_len = strlen (separator); + while ((tmp = strstr (parent_name, separator)) != NULL) { + parent_name = &tmp[separator_len]; } /* if parent have scope */ if (parent_name != child->atts.entry.scope) { /* the parent scope is the "dirname" of the child's scope */ parent_scope = g_strndup (child->atts.entry.scope, - parent_name - child->atts.entry.scope - 2); + parent_name - child->atts.entry.scope - + separator_len); } /*g_debug ("%s: parent_name = %s", G_STRFUNC, parent_name); g_debug ("%s: parent_scope = %s", G_STRFUNC, parent_scope);*/ @@ -333,6 +363,7 @@ /** * ggd_tag_resolve_type_hierarchy: * @tags: The tag array that contains @tag + * @geany_ft: The Geany's file type identifier for which tags were generated * @tag: A #TMTag to which get the type hierarchy * * Gets the type hierarchy of a tag as a string, each element separated by a @@ -346,6 +377,7 @@ */ gchar * ggd_tag_resolve_type_hierarchy (const GPtrArray *tags, + filetype_id geany_ft, const TMTag *tag) { gchar *scope = NULL; @@ -358,12 +390,12 @@ } else { TMTag *parent_tag;
- parent_tag = ggd_tag_find_parent (tags, tag); + parent_tag = ggd_tag_find_parent (tags, geany_ft, tag); scope = g_strdup (ggd_tag_get_type_name (tag)); if (parent_tag) { gchar *parent_scope;
- parent_scope = ggd_tag_resolve_type_hierarchy (tags, parent_tag); + parent_scope = ggd_tag_resolve_type_hierarchy (tags, geany_ft, parent_tag); if (! parent_scope) { /*g_debug ("no parent scope");*/ } else { @@ -416,6 +448,7 @@ * scope_child_matches: * @a: parent scope * @b: child scope + * @geany_ft: The Geany's file type identifier for which tags were generated * @maxdepth: maximum sub-child level that matches, or < 0 for all to match * * Checks if scope @b is inside scope @a. @maxdepth make possible to only match @@ -427,22 +460,27 @@ static gboolean scope_child_matches (const gchar *a, const gchar *b, + filetype_id geany_ft, gint maxdepth) { gboolean matches = FALSE;
+ /*g_debug ("trying to match %s against %s", b, a);*/ if (a && b) { for (; *a && *b && *a == *b; a++, b++); if (! *a /* we're at the end of the prefix and it matched */) { + const gchar *separator; + + separator = ggd_tag_utils_get_context_separator (geany_ft); if (maxdepth < 0) { - if (! *b || (b[0] == ':' && b[1] == ':')) { + if (! *b || strncmp (b, separator, strlen (separator)) == 0) { matches = TRUE; } } else { while (! matches && maxdepth >= 0) { const gchar *tmp;
- tmp = strstr (b, "::"); + tmp = strstr (b, separator); if (tmp) { b = &tmp[2]; maxdepth --; @@ -465,6 +503,7 @@ * ggd_tag_find_children: * @tags: Array of tags that contains @parent * @parent: Tag for which get children + * @geany_ft: The Geany's file type identifier for which tags were generated * @depth: Maximum depth for children to be found (< 0 means infinite) * @filter: A logical OR of the TMTagType<!-- -->s to match * @@ -477,6 +516,7 @@ GList * ggd_tag_find_children_filtered (const GPtrArray *tags, const TMTag *parent, + filetype_id geany_ft, gint depth, TMTagType filter) { @@ -489,12 +529,15 @@ g_return_val_if_fail (parent != NULL, NULL);
if (parent->atts.entry.scope) { - fake_scope = g_strconcat (parent->atts.entry.scope, parent->name, NULL); + fake_scope = g_strconcat (parent->atts.entry.scope, + ggd_tag_utils_get_context_separator (geany_ft), + parent->name, NULL); } else { fake_scope = g_strdup (parent->name); } GGD_PTR_ARRAY_FOR (tags, i, el) { - if (scope_child_matches (fake_scope, el->atts.entry.scope, depth) && + if (scope_child_matches (fake_scope, el->atts.entry.scope, + geany_ft, depth) && el->type & filter) { children = g_list_insert_sorted_with_data (children, el, tag_cmp_by_line, @@ -510,6 +553,7 @@ * ggd_tag_find_children: * @tags: Array of tags that contains @parent * @parent: Tag for which get children + * @geany_ft: The Geany's file type identifier for which tags were generated * @depth: Maximum depth for children to be found (< 0 means infinite) * * Finds children tags of a #TMTag. @@ -521,7 +565,9 @@ GList * ggd_tag_find_children (const GPtrArray *tags, const TMTag *parent, + filetype_id geany_ft, gint depth) { - return ggd_tag_find_children_filtered (tags, parent, depth, tm_tag_max_t); + return ggd_tag_find_children_filtered (tags, parent, geany_ft, + depth, tm_tag_max_t); }
Modified: trunk/geanygendoc/src/ggd-tag-utils.h =================================================================== --- trunk/geanygendoc/src/ggd-tag-utils.h 2010-05-01 17:47:37 UTC (rev 1325) +++ trunk/geanygendoc/src/ggd-tag-utils.h 2010-05-01 17:48:14 UTC (rev 1326) @@ -51,15 +51,19 @@ gulong line); TMTag *ggd_tag_find_at_current_pos (GeanyDocument *doc); TMTag *ggd_tag_find_parent (const GPtrArray *tags, + filetype_id geany_ft, const TMTag *child); GList *ggd_tag_find_children_filtered (const GPtrArray *tags, const TMTag *parent, + filetype_id geany_ft, gint depth, TMTagType filter); GList *ggd_tag_find_children (const GPtrArray *tags, const TMTag *parent, + filetype_id geany_ft, gint depth); gchar *ggd_tag_resolve_type_hierarchy (const GPtrArray *tags, + filetype_id geany_ft, const TMTag *tag); TMTag *ggd_tag_find_from_name (const GPtrArray *tags, const gchar *name);
Modified: trunk/geanygendoc/src/ggd.c =================================================================== --- trunk/geanygendoc/src/ggd.c 2010-05-01 17:47:37 UTC (rev 1325) +++ trunk/geanygendoc/src/ggd.c 2010-05-01 17:48:14 UTC (rev 1326) @@ -143,11 +143,12 @@ static CtplEnviron * get_env_for_tag (GgdFileType *ft, GgdDocSetting *setting, - GPtrArray *tag_array, + GeanyDocument *doc, const TMTag *tag) { CtplEnviron *env; GList *children = NULL; + GPtrArray *tag_array = doc->tm_file->tags_array;
env = ctpl_environ_new (); ctpl_environ_push_string (env, "cursor", GGD_CURSOR_IDENTIFIER); @@ -171,7 +172,8 @@ ctpl_environ_push_int (env, "returns", returns); } /* get direct children tags */ - children = ggd_tag_find_children (tag_array, tag, 0); + children = ggd_tag_find_children (tag_array, tag, + FILETYPE_ID (doc->file_type), 0); if (setting->merge_children) { CtplValue *v;
@@ -224,7 +226,7 @@ static gchar * get_comment (GgdFileType *ft, GgdDocSetting *setting, - GPtrArray *tag_array, + GeanyDocument *doc, const TMTag *tag, gint *cursor_offset) { @@ -234,7 +236,7 @@ GError *err = NULL; CtplEnviron *env;
- env = get_env_for_tag (ft, setting, tag_array, tag); + env = get_env_for_tag (ft, setting, doc, tag); ctpl_environ_merge (env, ft->user_env, FALSE); if (! ctpl_environ_add_from_string (env, GGD_OPT_environ, &err)) { msgwin_status_add (_("Failed to add global environment, skipping: %s"), @@ -320,7 +322,6 @@ /* inserts the comment for @tag in @sci according to @setting */ static gboolean do_insert_comment (GeanyDocument *doc, - GPtrArray *tag_array, const TMTag *tag, GgdFileType *ft, GgdDocSetting *setting) @@ -329,8 +330,9 @@ gchar *comment; gint cursor_offset = 0; ScintillaObject *sci = doc->editor->sci; + GPtrArray *tag_array = doc->tm_file->tags_array;
- comment = get_comment (ft, setting, tag_array, tag, &cursor_offset); + comment = get_comment (ft, setting, doc, tag, &cursor_offset); if (comment) { gint pos;
@@ -368,21 +370,24 @@ * Since a policy may forward documenting to a parent, tag that actually applies * is returned in @real_tag. */ static GgdDocSetting * -get_setting_from_tag (GgdDocType *doctype, - GPtrArray *tag_array, - const TMTag *tag, - const TMTag **real_tag) +get_setting_from_tag (GgdDocType *doctype, + GeanyDocument *doc, + const TMTag *tag, + const TMTag **real_tag) { GgdDocSetting *setting; gchar *hierarchy; gint nth_child; + GPtrArray *tag_array = doc->tm_file->tags_array; + filetype_id geany_ft = FILETYPE_ID (doc->file_type);
- hierarchy = ggd_tag_resolve_type_hierarchy (tag_array, tag); + hierarchy = ggd_tag_resolve_type_hierarchy (tag_array, geany_ft, tag); + /*g_debug ("type hierarchy for tag %s is: %s", tag->name, hierarchy);*/ setting = ggd_doc_type_resolve_setting (doctype, hierarchy, &nth_child); *real_tag = tag; if (setting) { for (; nth_child > 0; nth_child--) { - *real_tag = ggd_tag_find_parent (tag_array, *real_tag); + *real_tag = ggd_tag_find_parent (tag_array, geany_ft, *real_tag); } } g_free (hierarchy); @@ -449,23 +454,21 @@ { gboolean success = FALSE; GList *node; - GPtrArray *tag_array; ScintillaObject *sci = doc->editor->sci; GHashTable *tag_done_table; /* keeps the list of documented tags. * Useful since documenting a tag might * actually document another one */
success = TRUE; - tag_array = doc->tm_file->tags_array; tag_done_table = g_hash_table_new (NULL, NULL); sci_start_undo_action (sci); for (node = sorted_tag_list; node; node = node->next) { GgdDocSetting *setting; const TMTag *tag = node->data;
- setting = get_setting_from_tag (doctype, tag_array, tag, &tag); + setting = get_setting_from_tag (doctype, doc, tag, &tag); if (setting && ! g_hash_table_lookup (tag_done_table, tag)) { - if (! do_insert_comment (doc, tag_array, tag, filetype, setting)) { + if (! do_insert_comment (doc, tag, filetype, setting)) { success = FALSE; break; } else { @@ -520,10 +523,11 @@ GgdDocSetting *setting; GList *tag_list = NULL;
- setting = get_setting_from_tag (doctype, tag_array, tag, &tag); + setting = get_setting_from_tag (doctype, doc, tag, &tag); if (setting && setting->autodoc_children) { - tag_list = ggd_tag_find_children_filtered (tag_array, tag, 0, - setting->matches); + tag_list = ggd_tag_find_children_filtered (tag_array, tag, + FILETYPE_ID (doc->file_type), + 0, setting->matches); } /* we assume that a parent always comes before any children, then simply add * it at the end */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
plugins-commits@lists.geany.org