Merge pull request #862 from techee/tm_workspace_find_cleanup3
Rewrite scope completion v3. Closes #488 and #505.
This commit is contained in:
commit
a775da0714
174
src/editor.c
174
src/editor.c
@ -75,6 +75,7 @@ static GHashTable *snippet_hash = NULL;
|
||||
static GQueue *snippet_offsets = NULL;
|
||||
static gint snippet_cursor_insert_pos;
|
||||
static GtkAccelGroup *snippet_accel_group = NULL;
|
||||
static gboolean autocomplete_scope_shown = FALSE;
|
||||
|
||||
static const gchar geany_cursor_marker[] = "__GEANY_CURSOR_MARKER__";
|
||||
|
||||
@ -657,7 +658,9 @@ static gboolean match_last_chars(ScintillaObject *sci, gint pos, const gchar *st
|
||||
gchar *buf;
|
||||
|
||||
g_return_val_if_fail(len < 100, FALSE);
|
||||
g_return_val_if_fail((gint)len <= pos, FALSE);
|
||||
|
||||
if ((gint)len > pos)
|
||||
return FALSE;
|
||||
|
||||
buf = g_alloca(len + 1);
|
||||
sci_get_text_range(sci, pos - len, pos, buf);
|
||||
@ -697,51 +700,108 @@ static void request_reshowing_calltip(SCNotification *nt)
|
||||
}
|
||||
|
||||
|
||||
static void autocomplete_scope(GeanyEditor *editor)
|
||||
static gboolean autocomplete_scope(GeanyEditor *editor, const gchar *root, gsize rootlen)
|
||||
{
|
||||
ScintillaObject *sci = editor->sci;
|
||||
gint pos = sci_get_current_position(editor->sci);
|
||||
gchar typed = sci_get_char_at(sci, pos - 1);
|
||||
gchar brace_char;
|
||||
gchar *name;
|
||||
const GPtrArray *tags = NULL;
|
||||
const TMTag *tag;
|
||||
GeanyFiletype *ft = editor->document->file_type;
|
||||
GPtrArray *tags;
|
||||
gboolean function = FALSE;
|
||||
gboolean member;
|
||||
gboolean ret = FALSE;
|
||||
const gchar *current_scope;
|
||||
const gchar *context_sep = tm_tag_context_separator(ft->lang);
|
||||
|
||||
if (ft->id == GEANY_FILETYPES_C || ft->id == GEANY_FILETYPES_CPP)
|
||||
if (autocomplete_scope_shown)
|
||||
{
|
||||
if (pos >= 2 && (match_last_chars(sci, pos, "->") || match_last_chars(sci, pos, "::")))
|
||||
/* move at the operator position */
|
||||
pos -= rootlen;
|
||||
|
||||
/* allow for a space between word and operator */
|
||||
while (pos > 0 && isspace(sci_get_char_at(sci, pos - 1)))
|
||||
pos--;
|
||||
else if (ft->id == GEANY_FILETYPES_CPP && pos >= 3 && match_last_chars(sci, pos, "->*"))
|
||||
pos-=2;
|
||||
else if (typed != '.')
|
||||
return;
|
||||
|
||||
if (pos > 0)
|
||||
typed = sci_get_char_at(sci, pos - 1);
|
||||
}
|
||||
else if (typed != '.')
|
||||
return;
|
||||
|
||||
/* make sure to keep in sync with similar checks below */
|
||||
if (typed == '.')
|
||||
pos -= 1;
|
||||
else if (match_last_chars(sci, pos, context_sep))
|
||||
pos -= strlen(context_sep);
|
||||
else if ((ft->id == GEANY_FILETYPES_C || ft->id == GEANY_FILETYPES_CPP) &&
|
||||
match_last_chars(sci, pos, "->"))
|
||||
pos -= 2;
|
||||
else if (ft->id == GEANY_FILETYPES_CPP && match_last_chars(sci, pos, "->*"))
|
||||
pos -= 3;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
/* allow for a space between word and operator */
|
||||
if (isspace(sci_get_char_at(sci, pos - 2)))
|
||||
while (pos > 0 && isspace(sci_get_char_at(sci, pos - 1)))
|
||||
pos--;
|
||||
name = editor_get_word_at_pos(editor, pos - 1, NULL);
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
tags = tm_workspace_find(name, tm_tag_max_t, NULL, FALSE, ft->lang);
|
||||
g_free(name);
|
||||
if (!tags || tags->len == 0)
|
||||
return;
|
||||
|
||||
tag = g_ptr_array_index(tags, 0);
|
||||
name = tag->var_type;
|
||||
if (name)
|
||||
/* if function or array index, skip to matching brace */
|
||||
brace_char = sci_get_char_at(sci, pos - 1);
|
||||
if (pos > 0 && (brace_char == ')' || brace_char == ']'))
|
||||
{
|
||||
TMSourceFile *obj = editor->document->tm_file;
|
||||
gint brace_pos = sci_find_matching_brace(sci, pos - 1);
|
||||
|
||||
tags = tm_workspace_find_scope_members(obj ? obj->tags_array : NULL,
|
||||
name, TRUE, FALSE);
|
||||
if (tags)
|
||||
show_tags_list(editor, tags, 0);
|
||||
if (brace_pos != -1)
|
||||
{
|
||||
pos = brace_pos;
|
||||
function = brace_char == ')';
|
||||
}
|
||||
|
||||
/* allow for a space between opening brace and name */
|
||||
while (pos > 0 && isspace(sci_get_char_at(sci, pos - 1)))
|
||||
pos--;
|
||||
}
|
||||
|
||||
name = editor_get_word_at_pos(editor, pos, NULL);
|
||||
if (!name)
|
||||
return FALSE;
|
||||
|
||||
/* check if invoked on member */
|
||||
pos -= strlen(name);
|
||||
while (pos > 0 && isspace(sci_get_char_at(sci, pos - 1)))
|
||||
pos--;
|
||||
/* make sure to keep in sync with similar checks above */
|
||||
member = match_last_chars(sci, pos, ".") || match_last_chars(sci, pos, context_sep) ||
|
||||
match_last_chars(sci, pos, "->") || match_last_chars(sci, pos, "->*");
|
||||
|
||||
if (symbols_get_current_scope(editor->document, ¤t_scope) == -1)
|
||||
current_scope = "";
|
||||
tags = tm_workspace_find_scope_members(editor->document->tm_file, name, function,
|
||||
member, current_scope);
|
||||
if (tags)
|
||||
{
|
||||
GPtrArray *filtered = g_ptr_array_new();
|
||||
TMTag *tag;
|
||||
guint i;
|
||||
|
||||
foreach_ptr_array(tag, i, tags)
|
||||
{
|
||||
if (g_str_has_prefix(tag->name, root))
|
||||
g_ptr_array_add(filtered, tag);
|
||||
}
|
||||
|
||||
if (filtered->len > 0)
|
||||
{
|
||||
show_tags_list(editor, filtered, rootlen);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
g_ptr_array_free(tags, TRUE);
|
||||
g_ptr_array_free(filtered, TRUE);
|
||||
}
|
||||
|
||||
g_free(name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -1100,6 +1160,7 @@ static gboolean on_editor_notify(G_GNUC_UNUSED GObject *object, GeanyEditor *edi
|
||||
case SCN_AUTOCCANCELLED:
|
||||
/* now that autocomplete is finishing or was cancelled, reshow calltips
|
||||
* if they were showing */
|
||||
autocomplete_scope_shown = FALSE;
|
||||
request_reshowing_calltip(nt);
|
||||
break;
|
||||
case SCN_NEEDSHOWN:
|
||||
@ -1832,10 +1893,9 @@ static gboolean append_calltip(GString *str, const TMTag *tag, GeanyFiletypeID f
|
||||
|
||||
static gchar *find_calltip(const gchar *word, GeanyFiletype *ft)
|
||||
{
|
||||
const GPtrArray *tags;
|
||||
GPtrArray *tags;
|
||||
const TMTagType arg_types = tm_tag_function_t | tm_tag_prototype_t |
|
||||
tm_tag_method_t | tm_tag_macro_with_arg_t;
|
||||
TMTagAttrType *attrs = NULL;
|
||||
TMTag *tag;
|
||||
GString *str = NULL;
|
||||
guint i;
|
||||
@ -1843,20 +1903,26 @@ static gchar *find_calltip(const gchar *word, GeanyFiletype *ft)
|
||||
g_return_val_if_fail(ft && word && *word, NULL);
|
||||
|
||||
/* use all types in case language uses wrong tag type e.g. python "members" instead of "methods" */
|
||||
tags = tm_workspace_find(word, tm_tag_max_t, attrs, FALSE, ft->lang);
|
||||
tags = tm_workspace_find(word, NULL, tm_tag_max_t, NULL, ft->lang);
|
||||
if (tags->len == 0)
|
||||
{
|
||||
g_ptr_array_free(tags, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tag = TM_TAG(tags->pdata[0]);
|
||||
|
||||
if (ft->id == GEANY_FILETYPES_D &&
|
||||
(tag->type == tm_tag_class_t || tag->type == tm_tag_struct_t))
|
||||
{
|
||||
g_ptr_array_free(tags, TRUE);
|
||||
/* user typed e.g. 'new Classname(' so lookup D constructor Classname::this() */
|
||||
tags = tm_workspace_find_scoped("this", tag->name,
|
||||
arg_types, attrs, FALSE, ft->lang, TRUE);
|
||||
tags = tm_workspace_find("this", tag->name, arg_types, NULL, ft->lang);
|
||||
if (tags->len == 0)
|
||||
{
|
||||
g_ptr_array_free(tags, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* remove tags with no argument list */
|
||||
@ -1869,7 +1935,10 @@ static gchar *find_calltip(const gchar *word, GeanyFiletype *ft)
|
||||
}
|
||||
tm_tags_prune((GPtrArray *) tags);
|
||||
if (tags->len == 0)
|
||||
{
|
||||
g_ptr_array_free(tags, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{ /* remove duplicate calltips */
|
||||
TMTagAttrType sort_attr[] = {tm_tag_attr_name_t, tm_tag_attr_scope_t,
|
||||
@ -1906,6 +1975,9 @@ static gchar *find_calltip(const gchar *word, GeanyFiletype *ft)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_ptr_array_free(tags, TRUE);
|
||||
|
||||
if (str)
|
||||
{
|
||||
gchar *result = str->str;
|
||||
@ -2027,21 +2099,21 @@ autocomplete_html(ScintillaObject *sci, const gchar *root, gsize rootlen)
|
||||
static gboolean
|
||||
autocomplete_tags(GeanyEditor *editor, const gchar *root, gsize rootlen)
|
||||
{
|
||||
TMTagAttrType attrs[] = { tm_tag_attr_name_t, 0 };
|
||||
const GPtrArray *tags;
|
||||
GPtrArray *tags;
|
||||
GeanyDocument *doc;
|
||||
gboolean found;
|
||||
|
||||
g_return_val_if_fail(editor, FALSE);
|
||||
|
||||
doc = editor->document;
|
||||
|
||||
tags = tm_workspace_find(root, tm_tag_max_t, attrs, TRUE, doc->file_type->lang);
|
||||
if (tags)
|
||||
{
|
||||
tags = tm_workspace_find_prefix(root, doc->file_type->lang, editor_prefs.autocompletion_max_entries);
|
||||
found = tags->len > 0;
|
||||
if (found)
|
||||
show_tags_list(editor, tags, rootlen);
|
||||
return tags->len > 0;
|
||||
}
|
||||
return FALSE;
|
||||
g_ptr_array_free(tags, TRUE);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
@ -2201,7 +2273,6 @@ gboolean editor_start_auto_complete(GeanyEditor *editor, gint pos, gboolean forc
|
||||
if (!force && !highlighting_is_code_style(lexer, style))
|
||||
return FALSE;
|
||||
|
||||
autocomplete_scope(editor);
|
||||
ret = autocomplete_check_html(editor, style, pos);
|
||||
|
||||
if (ft->id == GEANY_FILETYPES_LATEX)
|
||||
@ -2215,6 +2286,23 @@ gboolean editor_start_auto_complete(GeanyEditor *editor, gint pos, gboolean forc
|
||||
root = cword;
|
||||
rootlen = strlen(root);
|
||||
|
||||
if (ret || force)
|
||||
{
|
||||
if (autocomplete_scope_shown)
|
||||
{
|
||||
autocomplete_scope_shown = FALSE;
|
||||
if (!ret)
|
||||
sci_send_command(sci, SCI_AUTOCCANCEL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = autocomplete_scope(editor, root, rootlen);
|
||||
if (!ret && autocomplete_scope_shown)
|
||||
sci_send_command(sci, SCI_AUTOCCANCEL);
|
||||
autocomplete_scope_shown = ret;
|
||||
}
|
||||
|
||||
if (!ret && rootlen > 0)
|
||||
{
|
||||
if (ft->id == GEANY_FILETYPES_PHP && style == SCE_HPHP_DEFAULT &&
|
||||
|
@ -281,7 +281,7 @@ GString *symbols_find_typenames_as_string(gint lang, gboolean global)
|
||||
gint tag_lang;
|
||||
|
||||
if (global)
|
||||
typedefs = tm_tags_extract(app->tm_workspace->global_tags, TM_GLOBAL_TYPE_MASK);
|
||||
typedefs = app->tm_workspace->global_typename_array;
|
||||
else
|
||||
typedefs = app->tm_workspace->typename_array;
|
||||
|
||||
@ -305,8 +305,6 @@ GString *symbols_find_typenames_as_string(gint lang, gboolean global)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typedefs && global)
|
||||
g_ptr_array_free(typedefs, TRUE);
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -324,31 +322,7 @@ GString *symbols_find_typenames_as_string(gint lang, gboolean global)
|
||||
GEANY_API_SYMBOL
|
||||
const gchar *symbols_get_context_separator(gint ft_id)
|
||||
{
|
||||
switch (ft_id)
|
||||
{
|
||||
case GEANY_FILETYPES_C: /* for C++ .h headers or C structs */
|
||||
case GEANY_FILETYPES_CPP:
|
||||
case GEANY_FILETYPES_GLSL: /* for structs */
|
||||
/*case GEANY_FILETYPES_RUBY:*/ /* not sure what to use atm*/
|
||||
case GEANY_FILETYPES_PHP:
|
||||
case GEANY_FILETYPES_POWERSHELL:
|
||||
case GEANY_FILETYPES_RUST:
|
||||
case GEANY_FILETYPES_ZEPHIR:
|
||||
return "::";
|
||||
|
||||
/* avoid confusion with other possible separators in group/section name */
|
||||
case GEANY_FILETYPES_CONF:
|
||||
case GEANY_FILETYPES_REST:
|
||||
return ":::";
|
||||
|
||||
/* no context separator */
|
||||
case GEANY_FILETYPES_ASCIIDOC:
|
||||
case GEANY_FILETYPES_TXT2TAGS:
|
||||
return "\x03";
|
||||
|
||||
default:
|
||||
return ".";
|
||||
}
|
||||
return tm_tag_context_separator(filetypes[ft_id]->lang);
|
||||
}
|
||||
|
||||
|
||||
|
@ -126,8 +126,7 @@ static int tm_source_file_tags(const tagEntryInfo *tag)
|
||||
/* Set the argument list of tag identified by its name */
|
||||
static void tm_source_file_set_tag_arglist(const char *tag_name, const char *arglist)
|
||||
{
|
||||
guint count;
|
||||
TMTag **tags, *tag;
|
||||
guint i;
|
||||
|
||||
if (NULL == arglist ||
|
||||
NULL == tag_name ||
|
||||
@ -136,13 +135,16 @@ static void tm_source_file_set_tag_arglist(const char *tag_name, const char *arg
|
||||
return;
|
||||
}
|
||||
|
||||
tags = tm_tags_find(current_source_file->tags_array, tag_name, FALSE, FALSE,
|
||||
&count);
|
||||
if (tags != NULL && count == 1)
|
||||
/* going in reverse order because the tag was added recently */
|
||||
for (i = current_source_file->tags_array->len; i > 0; i--)
|
||||
{
|
||||
tag = tags[0];
|
||||
g_free(tag->arglist);
|
||||
tag->arglist = g_strdup(arglist);
|
||||
TMTag *tag = (TMTag *) current_source_file->tags_array->pdata[i - 1];
|
||||
if (g_strcmp0(tag->name, tag_name) == 0)
|
||||
{
|
||||
g_free(tag->arglist);
|
||||
tag->arglist = g_strdup(arglist);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "read.h"
|
||||
#define LIBCTAGS_DEFINED
|
||||
#include "tm_tag.h"
|
||||
#include "tm_parser.h"
|
||||
|
||||
|
||||
#define TAG_NEW(T) ((T) = g_slice_new0(TMTag))
|
||||
@ -108,6 +109,8 @@ typedef struct
|
||||
{
|
||||
guint *sort_attrs;
|
||||
gboolean partial;
|
||||
const GPtrArray *tags_array;
|
||||
gboolean first;
|
||||
} TMSortOptions;
|
||||
|
||||
static const char *s_tag_type_names[] = {
|
||||
@ -860,7 +863,7 @@ void tm_tags_remove_file_tags(TMSourceFile *source_file, GPtrArray *tags_array)
|
||||
TMTag **found;
|
||||
TMTag *tag = source_file->tags_array->pdata[i];
|
||||
|
||||
found = tm_tags_find(tags_array, tag->name, FALSE, TRUE, &tag_count);
|
||||
found = tm_tags_find(tags_array, tag->name, FALSE, &tag_count);
|
||||
|
||||
for (j = 0; j < tag_count; j++)
|
||||
{
|
||||
@ -1081,85 +1084,74 @@ static gpointer binary_search(gpointer key, gpointer base, size_t nmemb,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static TMTag **tags_search(const GPtrArray *tags_array, TMTag *tag,
|
||||
gboolean tags_array_sorted, TMSortOptions *sort_options)
|
||||
static gint tag_search_cmp(gconstpointer ptr1, gconstpointer ptr2, gpointer user_data)
|
||||
{
|
||||
if (tags_array_sorted)
|
||||
{ /* fast binary search on sorted tags array */
|
||||
return (TMTag **) binary_search(&tag, tags_array->pdata, tags_array->len,
|
||||
tm_tag_compare, sort_options);
|
||||
}
|
||||
else
|
||||
{ /* the slow way: linear search (to make it a bit faster, search reverse assuming
|
||||
* that the tag to search was added recently) */
|
||||
guint i;
|
||||
TMTag **t;
|
||||
for (i = tags_array->len; i > 0; i--)
|
||||
gint res = tm_tag_compare(ptr1, ptr2, user_data);
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
TMSortOptions *sort_options = user_data;
|
||||
const GPtrArray *tags_array = sort_options->tags_array;
|
||||
TMTag **tag = (TMTag **) ptr2;
|
||||
|
||||
/* if previous/next (depending on sort options) tag equal, we haven't
|
||||
* found the first/last tag in a sequence of equal tags yet */
|
||||
if (sort_options->first && ptr2 != &tags_array->pdata[0]) {
|
||||
if (tm_tag_compare(ptr1, tag - 1, user_data) == 0)
|
||||
return -1;
|
||||
}
|
||||
else if (!sort_options->first && ptr2 != &tags_array->pdata[tags_array->len-1])
|
||||
{
|
||||
t = (TMTag **) &tags_array->pdata[i - 1];
|
||||
if (0 == tm_tag_compare(&tag, t, sort_options))
|
||||
return t;
|
||||
if (tm_tag_compare(ptr1, tag + 1, user_data) == 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns a pointer to the position of the first matching tag in a (sorted) tags array.
|
||||
The passed array of tags should be already sorted by name for optimal performance. If
|
||||
\c tags_array_sorted is set to FALSE, it may be unsorted but the lookup will be slower.
|
||||
@param tags_array Tag array (may be sorted on name)
|
||||
The passed array of tags must be already sorted by name (searched with binary search).
|
||||
@param tags_array Tag array (sorted on name)
|
||||
@param name Name of the tag to locate.
|
||||
@param partial If TRUE, matches the first part of the name instead of doing exact match.
|
||||
@param tags_array_sorted If TRUE, the passed \c tags_array is sorted by name so it can be
|
||||
searched with binary search. Otherwise it is searched linear which is obviously slower.
|
||||
@param tagCount Return location of the matched tags.
|
||||
*/
|
||||
TMTag **tm_tags_find(const GPtrArray *tags_array, const char *name,
|
||||
gboolean partial, gboolean tags_array_sorted, guint * tagCount)
|
||||
gboolean partial, guint *tagCount)
|
||||
{
|
||||
static TMTag *tag = NULL;
|
||||
TMTag **result;
|
||||
guint tagMatches=0;
|
||||
TMTag *tag, **first;
|
||||
TMSortOptions sort_options;
|
||||
|
||||
*tagCount = 0;
|
||||
if ((!tags_array) || (!tags_array->len))
|
||||
if (!tags_array || !tags_array->len)
|
||||
return NULL;
|
||||
|
||||
if (NULL == tag)
|
||||
tag = g_new0(TMTag, 1);
|
||||
tag = g_new0(TMTag, 1);
|
||||
tag->name = (char *) name;
|
||||
|
||||
sort_options.sort_attrs = NULL;
|
||||
sort_options.partial = partial;
|
||||
sort_options.tags_array = tags_array;
|
||||
sort_options.first = TRUE;
|
||||
first = (TMTag **)binary_search(&tag, tags_array->pdata, tags_array->len,
|
||||
tag_search_cmp, &sort_options);
|
||||
|
||||
result = tags_search(tags_array, tag, tags_array_sorted, &sort_options);
|
||||
/* There can be matches on both sides of result */
|
||||
if (result)
|
||||
if (first)
|
||||
{
|
||||
TMTag **last = (TMTag **) &tags_array->pdata[tags_array->len - 1];
|
||||
TMTag **adv;
|
||||
TMTag **last;
|
||||
unsigned first_pos;
|
||||
|
||||
/* First look for any matches after result */
|
||||
adv = result;
|
||||
adv++;
|
||||
for (; adv <= last && *adv; ++ adv)
|
||||
{
|
||||
if (0 != tm_tag_compare(&tag, adv, &sort_options))
|
||||
break;
|
||||
++tagMatches;
|
||||
}
|
||||
/* Now look for matches from result and below */
|
||||
for (; result >= (TMTag **) tags_array->pdata; -- result)
|
||||
{
|
||||
if (0 != tm_tag_compare(&tag, (TMTag **) result, &sort_options))
|
||||
break;
|
||||
++tagMatches;
|
||||
}
|
||||
*tagCount=tagMatches;
|
||||
++ result; /* Correct address for the last successful match */
|
||||
sort_options.first = FALSE;
|
||||
first_pos = first - (TMTag **)tags_array->pdata;
|
||||
/* search between the first element and end */
|
||||
last = (TMTag **)binary_search(&tag, first, tags_array->len - first_pos,
|
||||
tag_search_cmp, &sort_options);
|
||||
*tagCount = last - first + 1;
|
||||
}
|
||||
return (TMTag **) result;
|
||||
|
||||
g_free(tag);
|
||||
return (TMTag **) first;
|
||||
}
|
||||
|
||||
/* Returns TMTag which "own" given line
|
||||
@ -1190,17 +1182,48 @@ tm_get_current_tag (GPtrArray * file_tags, const gulong line, const TMTagType ta
|
||||
return matching_tag;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Returns TMTag to function or method which "own" given line
|
||||
@param line Current line in edited file.
|
||||
@param file_tags A GPtrArray of edited file TMTag pointers.
|
||||
@return TMTag pointers to owner function. */
|
||||
static const TMTag *
|
||||
tm_get_current_function (GPtrArray * file_tags, const gulong line)
|
||||
const gchar *tm_tag_context_separator(langType lang)
|
||||
{
|
||||
return tm_get_current_tag (file_tags, line, tm_tag_function_t | tm_tag_method_t);
|
||||
switch (lang)
|
||||
{
|
||||
case TM_PARSER_C: /* for C++ .h headers or C structs */
|
||||
case TM_PARSER_CPP:
|
||||
case TM_PARSER_GLSL: /* for structs */
|
||||
/*case GEANY_FILETYPES_RUBY:*/ /* not sure what to use atm*/
|
||||
case TM_PARSER_PHP:
|
||||
case TM_PARSER_POWERSHELL:
|
||||
case TM_PARSER_RUST:
|
||||
case TM_PARSER_ZEPHIR:
|
||||
return "::";
|
||||
|
||||
/* avoid confusion with other possible separators in group/section name */
|
||||
case TM_PARSER_CONF:
|
||||
case TM_PARSER_REST:
|
||||
return ":::";
|
||||
|
||||
/* no context separator */
|
||||
case TM_PARSER_ASCIIDOC:
|
||||
case TM_PARSER_TXT2TAGS:
|
||||
return "\x03";
|
||||
|
||||
default:
|
||||
return ".";
|
||||
}
|
||||
}
|
||||
|
||||
gboolean tm_tag_is_anon(const TMTag *tag)
|
||||
{
|
||||
guint i;
|
||||
char dummy;
|
||||
|
||||
if (tag->lang == TM_PARSER_C || tag->lang == TM_PARSER_CPP)
|
||||
return sscanf(tag->name, "anon_%*[a-z]_%u%c", &i, &dummy) == 1;
|
||||
else if (tag->lang == TM_PARSER_FORTRAN || tag->lang == TM_PARSER_F77)
|
||||
return sscanf(tag->name, "Structure#%u%c", &i, &dummy) == 1 ||
|
||||
sscanf(tag->name, "Interface#%u%c", &i, &dummy) == 1 ||
|
||||
sscanf(tag->name, "Enum#%u%c", &i, &dummy) == 1;
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TM_DEBUG /* various debugging functions */
|
||||
@ -1343,11 +1366,12 @@ void tm_tags_array_print(GPtrArray *tags, FILE *fp)
|
||||
*/
|
||||
gint tm_tag_scope_depth(const TMTag *t)
|
||||
{
|
||||
const gchar *context_sep = tm_tag_context_separator(t->lang);
|
||||
gint depth;
|
||||
char *s;
|
||||
if(!(t && t->scope))
|
||||
return 0;
|
||||
for (s = t->scope, depth = 0; s; s = strstr(s, "::"))
|
||||
for (s = t->scope, depth = 0; s; s = strstr(s, context_sep))
|
||||
{
|
||||
++ depth;
|
||||
++ s;
|
||||
|
@ -179,7 +179,7 @@ gboolean tm_tags_prune(GPtrArray *tags_array);
|
||||
gboolean tm_tags_dedup(GPtrArray *tags_array, TMTagAttrType *sort_attributes, gboolean unref_duplicates);
|
||||
|
||||
TMTag **tm_tags_find(const GPtrArray *tags_array, const char *name,
|
||||
gboolean partial, gboolean tags_array_sorted, guint * tagCount);
|
||||
gboolean partial, guint * tagCount);
|
||||
|
||||
void tm_tags_array_free(GPtrArray *tags_array, gboolean free_all);
|
||||
|
||||
@ -191,6 +191,10 @@ TMTag *tm_tag_ref(TMTag *tag);
|
||||
|
||||
gboolean tm_tags_equal(const TMTag *a, const TMTag *b);
|
||||
|
||||
const gchar *tm_tag_context_separator(langType lang);
|
||||
|
||||
gboolean tm_tag_is_anon(const TMTag *tag);
|
||||
|
||||
#ifdef TM_DEBUG /* various debugging functions */
|
||||
|
||||
const char *tm_tag_type_name(const TMTag *tag);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -33,6 +33,7 @@ typedef struct
|
||||
GPtrArray *tags_array; /**< Sorted tags from all source files
|
||||
(just pointers to source file tags, the tag objects are owned by the source files) */
|
||||
GPtrArray *typename_array; /* Typename tags for syntax highlighting (pointers owned by source files) */
|
||||
GPtrArray *global_typename_array; /* Like above for global tags */
|
||||
} TMWorkspace;
|
||||
|
||||
|
||||
@ -54,17 +55,14 @@ gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode);
|
||||
gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes,
|
||||
int includes_count, const char *tags_file, int lang);
|
||||
|
||||
const GPtrArray *tm_workspace_find(const char *name, TMTagType type, TMTagAttrType *attrs,
|
||||
gboolean partial, langType lang);
|
||||
GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type,
|
||||
TMTagAttrType *attrs, langType lang);
|
||||
|
||||
const GPtrArray *
|
||||
tm_workspace_find_scoped (const char *name, const char *scope, TMTagType type,
|
||||
TMTagAttrType *attrs, gboolean partial, langType lang, gboolean global_search);
|
||||
GPtrArray *tm_workspace_find_prefix(const char *prefix, langType lang, guint max_num);
|
||||
|
||||
GPtrArray *tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name,
|
||||
gboolean function, gboolean member, const gchar *current_scope);
|
||||
|
||||
const GPtrArray *tm_workspace_find_scope_members(const GPtrArray *file_tags,
|
||||
const char *scope_name,
|
||||
gboolean find_global,
|
||||
gboolean no_definitions);
|
||||
|
||||
void tm_workspace_add_source_file_noupdate(TMSourceFile *source_file);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user