[geany/geany] 65f84d: Improve Goto Symbol popup contents

Jiří Techet git-noreply at xxxxx
Fri Jun 10 21:57:17 UTC 2016


Branch:      refs/heads/master
Author:      Jiří Techet <techet at gmail.com>
Committer:   Jiří Techet <techet at gmail.com>
Date:        Fri, 11 Mar 2016 10:29:50 UTC
Commit:      65f84df5cae544deaf3a4ca56c7f29d8e13329d3
             https://github.com/geany/geany/commit/65f84df5cae544deaf3a4ca56c7f29d8e13329d3

Log Message:
-----------
Improve Goto Symbol popup contents

* always filter-out symbol from the current line from the list
* when clicked on a symbol on the current line always swap
  definition/declaration search even if there are more symbols from the
  current search direction

Fixes #950


Modified Paths:
--------------
    src/symbols.c

Modified: src/symbols.c
130 lines changed, 71 insertions(+), 59 deletions(-)
===================================================================
@@ -2071,102 +2071,114 @@ static TMTag *find_best_goto_tag(GeanyDocument *doc, GPtrArray *tags)
 }
 
 
+static GPtrArray *filter_tags(GPtrArray *tags, TMTag *current_tag, gboolean definition)
+{
+	const TMTagType forward_types = tm_tag_prototype_t | tm_tag_externvar_t;
+	TMTag *tmtag, *last_tag = NULL;
+	GPtrArray *filtered_tags = g_ptr_array_new();
+	guint i;
+
+	foreach_ptr_array(tmtag, i, tags)
+	{
+		if (definition && !(tmtag->type & forward_types) ||
+			!definition && (tmtag->type & forward_types))
+		{
+			/* If there are typedefs of e.g. a struct such as
+			 * "typedef struct Foo {} Foo;", filter out the typedef unless
+			 * cursor is at the struct name. */
+			if (last_tag != NULL && last_tag->file == tmtag->file &&
+				last_tag->type != tm_tag_typedef_t && tmtag->type == tm_tag_typedef_t)
+			{
+				if (last_tag == current_tag)
+					g_ptr_array_add(filtered_tags, tmtag);
+			}
+			else if (tmtag != current_tag)
+				g_ptr_array_add(filtered_tags, tmtag);
+
+			last_tag = tmtag;
+		}
+	}
+
+	return filtered_tags;
+}
+
+
 static gboolean goto_tag(const gchar *name, gboolean definition)
 {
 	const TMTagType forward_types = tm_tag_prototype_t | tm_tag_externvar_t;
-	TMTagType type;
-	TMTag *tmtag, *last_tag;
+	TMTag *tmtag, *current_tag = NULL;
 	GeanyDocument *old_doc = document_get_current();
 	gboolean found = FALSE;
 	const GPtrArray *all_tags;
-	GPtrArray *workspace_tags, *filtered_tags;
+	GPtrArray *tags, *filtered_tags;
 	guint i;
 	guint current_line = sci_get_current_line(old_doc->editor->sci) + 1;
 
-	/* goto tag definition: all except prototypes / forward declarations / externs */
-	type = (definition) ? tm_tag_max_t - forward_types : forward_types;
-	all_tags = tm_workspace_find(name, NULL, type, NULL, old_doc->file_type->lang);
+	all_tags = tm_workspace_find(name, NULL, tm_tag_max_t, NULL, old_doc->file_type->lang);
 
-	/* get rid of global tags */
-	workspace_tags = g_ptr_array_new();
+	/* get rid of global tags and find tag at current line */
+	tags = g_ptr_array_new();
 	foreach_ptr_array(tmtag, i, all_tags)
 	{
 		if (tmtag->file)
-			g_ptr_array_add(workspace_tags, tmtag);
-	}
-
-	/* If there are typedefs of e.g. a struct such as "typedef struct Foo {} Foo;",
-	 * keep just one of the names in the list - when the cursor is on the struct
-	 * name, keep the typename, otherwise keep the struct name. */
-	last_tag = NULL;
-	filtered_tags = g_ptr_array_new();
-	foreach_ptr_array(tmtag, i, workspace_tags)
-	{
-		if (last_tag != NULL && last_tag->file == tmtag->file &&
-			last_tag->type != tm_tag_typedef_t && tmtag->type == tm_tag_typedef_t)
 		{
-			if (last_tag->line == current_line && filtered_tags->len > 0)
-				/* if cursor on struct, replace struct with the typedef */
-				filtered_tags->pdata[filtered_tags->len-1] = tmtag;
-			/* if cursor anywhere else, use struct (already added) and discard typedef */
+			g_ptr_array_add(tags, tmtag);
+			if (tmtag->file == old_doc->tm_file && tmtag->line == current_line)
+				current_tag = tmtag;
 		}
-		else
-			g_ptr_array_add(filtered_tags, tmtag);
+	}
+
+	if (current_tag)
+		/* swap definition/declaration search */
+		definition = current_tag->type & forward_types;
 
-		last_tag = tmtag;
+	filtered_tags = filter_tags(tags, current_tag, definition);
+	if (current_tag && filtered_tags->len == 0)
+	{
+		/* if we previously swapped definition/declaration search and didn't
+		 * find anything, try again with the opposite type */
+		g_ptr_array_free(filtered_tags, TRUE);
+		filtered_tags = filter_tags(tags, current_tag, !definition);
 	}
-	g_ptr_array_free(workspace_tags, TRUE);
-	workspace_tags = filtered_tags;
+	g_ptr_array_free(tags, TRUE);
+	tags = filtered_tags;
 
-	if (workspace_tags->len == 1)
+	if (tags->len == 1)
 	{
 		GeanyDocument *new_doc;
 
-		tmtag = workspace_tags->pdata[0];
-		new_doc = document_find_by_real_path(
-			tmtag->file->file_name);
+		tmtag = tags->pdata[0];
+		new_doc = document_find_by_real_path(tmtag->file->file_name);
 
-		if (new_doc)
-		{
-			/* If we are already on the tag line, swap definition/declaration */
-			if (new_doc == old_doc && tmtag->line == current_line)
-			{
-				if (goto_tag(name, !definition))
-					found = TRUE;
-			}
-		}
-		else
-		{
+		if (!new_doc)
 			/* not found in opened document, should open */
 			new_doc = document_open_file(tmtag->file->file_name, FALSE, NULL, NULL);
-		}
 
-		if (!found && navqueue_goto_line(old_doc, new_doc, tmtag->line))
-			found = TRUE;
+		navqueue_goto_line(old_doc, new_doc, tmtag->line);
 	}
-	else if (workspace_tags->len > 1)
+	else if (tags->len > 1)
 	{
-		GPtrArray *tags;
+		GPtrArray *tag_list;
 		TMTag *tag, *best_tag;
 
-		g_ptr_array_sort(workspace_tags, compare_tags_by_name_line);
-		best_tag = find_best_goto_tag(old_doc, workspace_tags);
+		g_ptr_array_sort(tags, compare_tags_by_name_line);
+		best_tag = find_best_goto_tag(old_doc, tags);
 
-		tags = g_ptr_array_new();
+		tag_list = g_ptr_array_new();
 		if (best_tag)
-			g_ptr_array_add(tags, best_tag);
-		foreach_ptr_array(tag, i, workspace_tags)
+			g_ptr_array_add(tag_list, best_tag);
+		foreach_ptr_array(tag, i, tags)
 		{
 			if (tag != best_tag)
-				g_ptr_array_add(tags, tag);
+				g_ptr_array_add(tag_list, tag);
 		}
-		show_goto_popup(old_doc, tags, best_tag != NULL);
+		show_goto_popup(old_doc, tag_list, best_tag != NULL);
 
-		g_ptr_array_free(tags, TRUE);
-		found = TRUE;
+		g_ptr_array_free(tag_list, TRUE);
 	}
 
-	g_ptr_array_free(workspace_tags, TRUE);
+	found = tags->len > 0;
+	g_ptr_array_free(tags, TRUE);
 
 	return found;
 }



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list