diff --git a/ChangeLog b/ChangeLog index a25f8cc67..d42c04c15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-04-13 Nick Treleaven + + * src/sci_cb.c, tagmanager/tm_tag.c, tagmanager/tm_workspace.c: + Show up and down arrows when there are multiple calltip matches. + + 2007-04-10 Enrico Tröger * geany.glade, src/document.c, src/geany.h, src/interface.c, diff --git a/src/sci_cb.c b/src/sci_cb.c index f1aba77fa..059805612 100644 --- a/src/sci_cb.c +++ b/src/sci_cb.c @@ -50,7 +50,9 @@ static struct { gchar *text; gboolean set; -} calltip = {NULL, FALSE}; + gchar *last_word; + guint tag_index; +} calltip = {NULL, FALSE, NULL, 0}; static gchar indent[100]; @@ -336,6 +338,23 @@ void on_editor_notification(GtkWidget *editor, gint scn, gpointer lscn, gpointer } break; } + case SCN_CALLTIPCLICK: + { + if (nt->position > 0) + { + switch (nt->position) + { + case 1: // up arrow + if (calltip.tag_index > 0) + calltip.tag_index--; + break; + + case 2: calltip.tag_index++; break; // down arrow + } + sci_cb_show_calltip(idx, -1); + } + break; + } } } @@ -645,14 +664,9 @@ static gint find_start_bracket(ScintillaObject *sci, gint pos) } -static gchar *tag_to_calltip(const TMTag *tag, filetype_id ft_id) +static gboolean append_calltip(GString *str, const TMTag *tag, filetype_id ft_id) { - GString *str; - gchar *result; - - if (! tag->atts.entry.arglist) return NULL; - - str = g_string_new(NULL); + if (! tag->atts.entry.arglist) return FALSE; if (tag->atts.entry.var_type) { @@ -676,47 +690,87 @@ static gchar *tag_to_calltip(const TMTag *tag, filetype_id ft_id) g_string_append_c(str, ' '); g_string_append(str, tag->atts.entry.arglist); - result = str->str; - g_string_free(str, FALSE); - return result; + return TRUE; } static gchar *find_calltip(const gchar *word, filetype *ft) { - TMTag *tag; const GPtrArray *tags; + TMTagAttrType *attrs = NULL; + TMTag *tag; + GString *str = NULL; + guint i; g_return_val_if_fail(ft && word && *word, NULL); - tags = tm_workspace_find(word, tm_tag_max_t, NULL, FALSE, ft->lang); - + tags = tm_workspace_find(word, tm_tag_max_t, attrs, FALSE, ft->lang); if (tags->len == 0) return NULL; tag = TM_TAG(tags->pdata[0]); - if (tag->atts.entry.arglist) - { - return tag_to_calltip(tag, FILETYPE_ID(ft)); - } - else if (tag->type == tm_tag_class_t && FILETYPE_ID(ft) == GEANY_FILETYPES_D) - { - TMTagAttrType attrs[] = { tm_tag_attr_name_t, 0 }; + if (tag->type == tm_tag_class_t && FILETYPE_ID(ft) == GEANY_FILETYPES_D) + { // user typed e.g. 'new Classname(' so lookup D constructor Classname::this() - tags = tm_workspace_find_scoped("this", tag->name, tm_tag_function_t | tm_tag_prototype_t, - attrs, FALSE, ft->lang, TRUE); - if (tags->len != 0) + tags = tm_workspace_find_scoped("this", tag->name, + tm_tag_function_t | tm_tag_prototype_t, attrs, FALSE, ft->lang, TRUE); + if (tags->len == 0) + return NULL; + } + + // remove tags with no argument list + for (i = 0; i < tags->len; i++) + { + tag = TM_TAG(tags->pdata[i]); + + if (! tag->atts.entry.arglist) + tags->pdata[i] = NULL; + } + tm_tags_prune((GPtrArray *) tags); + if (tags->len == 0) + return NULL; + + // if the current word has changed since last time, start with the first tag match + if (! utils_str_equal(word, calltip.last_word)) + calltip.tag_index = 0; + // cache the current word for next time + g_free(calltip.last_word); + calltip.last_word = g_strdup(word); + calltip.tag_index = MIN(calltip.tag_index, tags->len - 1); // ensure tag_index is in range + + for (i = calltip.tag_index; i < tags->len; i++) + { + tag = TM_TAG(tags->pdata[i]); + + if (str == NULL) { - tag = TM_TAG(tags->pdata[0]); - if (tag->atts.entry.arglist) - return tag_to_calltip(tag, FILETYPE_ID(ft)); + str = g_string_new(NULL); + if (calltip.tag_index > 0) + g_string_prepend(str, "\001 "); // up arrow + append_calltip(str, tag, FILETYPE_ID(ft)); } + else // add a down arrow + { + if (calltip.tag_index > 0) // already have an up arrow + g_string_insert_c(str, 1, '\002'); + else + g_string_prepend(str, "\002 "); + break; + } + } + if (str) + { + gchar *result = str->str; + + g_string_free(str, FALSE); + return result; } return NULL; } +// use pos = -1 to search for the previous unmatched open bracket. gboolean sci_cb_show_calltip(gint idx, gint pos) { gint orig_pos = pos; // the position for the calltip diff --git a/tagmanager/tm_tag.c b/tagmanager/tm_tag.c index 8fdc38a82..0c5f09f40 100644 --- a/tagmanager/tm_tag.c +++ b/tagmanager/tm_tag.c @@ -474,6 +474,14 @@ int tm_tag_compare(const void *ptr1, const void *ptr2) if (0 != (returnval = strcmp(NVL(t1->atts.entry.scope, ""), NVL(t2->atts.entry.scope, "")))) return returnval; break; + case tm_tag_attr_arglist_t: + if (0 != (returnval = strcmp(NVL(t1->atts.entry.arglist, ""), NVL(t2->atts.entry.arglist, "")))) + { + int line_diff = (t1->atts.entry.line - t2->atts.entry.line); + + return line_diff ? line_diff : returnval; + } + break; case tm_tag_attr_vartype_t: if (0 != (returnval = strcmp(NVL(t1->atts.entry.var_type, ""), NVL(t2->atts.entry.var_type, "")))) return returnval; diff --git a/tagmanager/tm_workspace.c b/tagmanager/tm_workspace.c index 29a34f90a..fb29d4e2b 100644 --- a/tagmanager/tm_workspace.c +++ b/tagmanager/tm_workspace.c @@ -382,7 +382,7 @@ void tm_workspace_recreate_tags_array(void) guint i, j; TMWorkObject *w; TMTagAttrType sort_attrs[] = { tm_tag_attr_name_t, tm_tag_attr_file_t - , tm_tag_attr_scope_t, tm_tag_attr_type_t, 0}; + , tm_tag_attr_scope_t, tm_tag_attr_type_t, tm_tag_attr_arglist_t, 0}; #ifdef TM_DEBUG g_message("Recreating workspace tags array"); @@ -551,7 +551,8 @@ const GPtrArray *tm_workspace_find(const char *name, int type, TMTagAttrType *at } } - tm_tags_sort(tags, attrs, TRUE); + if (attrs) + tm_tags_sort(tags, attrs, TRUE); return tags; } @@ -559,7 +560,7 @@ const GPtrArray *tm_workspace_find(const char *name, int type, TMTagAttrType *at /* scope can be NULL. * lang can be -1 */ static int -fill_find_tags_array (GPtrArray * dst, const GPtrArray * src, +fill_find_tags_array (GPtrArray *dst, const GPtrArray *src, const char *name, const char *scope, int type, gboolean partial, gint lang, gboolean first) { @@ -607,12 +608,12 @@ tm_workspace_find_scoped (const char *name, const char *scope, gint type, tags = g_ptr_array_new (); fill_find_tags_array (tags, theWorkspace->work_object.tags_array, - name, scope, type, partial, lang, TRUE); + name, scope, type, partial, lang, FALSE); if (global_search) { // for a scoped tag, I think we always want the same language fill_find_tags_array (tags, theWorkspace->global_tags, - name, scope, type, partial, lang, TRUE); + name, scope, type, partial, lang, FALSE); } if (attrs) tm_tags_sort (tags, attrs, TRUE);