From 77f6e98de8e50d0b9e270c113c8ba3b2828bbe19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Techet?= Date: Sat, 16 Jan 2016 14:25:01 +0100 Subject: [PATCH 1/9] Add scope completion for namespaces Pop up scope completion dialog for namespaces too; e.g. for boost:: show all symbols defined in the namespace. Determine whether the namespace scope completion should be used based on whether user typed a scope separator. If so, perform completion for namespaces before normal scope completion - this seems to work better e.g. for Scintilla where Scintilla:: would otherwise pop up the varible sci instead of showing everything in the namespace (might be more questionable for languages where the scope separator is identical to the dereference operator like Java's "." but we have to make some choice anyway). The performance seems to be reasonable - for the completion all tags have to be walked but after testing with big C++ projects like boost and Mozilla, the completion takes only something like 0.2s which is acceptable as the delay happens only on typing the scope completion separator and feels kind of expected. Also tested with linux kernel sources which normally lack any scope information by hacking TM a bit and injecting 10-character scope for each tag - then the completion takes something over 0.5s. --- src/editor.c | 12 ++++--- tagmanager/src/tm_workspace.c | 65 ++++++++++++++++++++++++++--------- tagmanager/src/tm_workspace.h | 2 +- 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/src/editor.c b/src/editor.c index e8ef888a3d..1762d2175a 100644 --- a/src/editor.c +++ b/src/editor.c @@ -711,6 +711,7 @@ static gboolean autocomplete_scope(GeanyEditor *editor, const gchar *root, gsize GPtrArray *tags; gboolean function = FALSE; gboolean member; + gboolean scope_sep_typed = FALSE; gboolean ret = FALSE; const gchar *current_scope; const gchar *context_sep = tm_tag_context_separator(ft->lang); @@ -729,10 +730,13 @@ static gboolean autocomplete_scope(GeanyEditor *editor, const gchar *root, gsize } /* make sure to keep in sync with similar checks below */ - if (typed == '.') - pos -= 1; - else if (match_last_chars(sci, pos, context_sep)) + if (match_last_chars(sci, pos, context_sep)) + { pos -= strlen(context_sep); + scope_sep_typed = TRUE; + } + else if (typed == '.') + pos -= 1; else if ((ft->id == GEANY_FILETYPES_C || ft->id == GEANY_FILETYPES_CPP) && match_last_chars(sci, pos, "->")) pos -= 2; @@ -777,7 +781,7 @@ static gboolean autocomplete_scope(GeanyEditor *editor, const gchar *root, gsize 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); + member, current_scope, scope_sep_typed); if (tags) { GPtrArray *filtered = g_ptr_array_new(); diff --git a/tagmanager/src/tm_workspace.c b/tagmanager/src/tm_workspace.c index ef582a84a0..b20ed8d79d 100644 --- a/tagmanager/src/tm_workspace.c +++ b/tagmanager/src/tm_workspace.c @@ -1039,6 +1039,22 @@ find_scope_members_all(const GPtrArray *tags, const GPtrArray *searched_array, l } +static GPtrArray *find_namespace_members_all(const GPtrArray *tags, const GPtrArray *searched_array, langType lang) +{ + GPtrArray *member_tags = NULL; + guint i; + + for (i = 0; i < tags->len && !member_tags; i++) + { + TMTag *tag = TM_TAG(tags->pdata[i]); + + member_tags = find_scope_members_tags(searched_array, tag, TRUE); + } + + return member_tags; +} + + /* Returns all member tags of a struct/union/class if the provided name is a variable of such a type or the name of the type. @param source_file TMSourceFile of the edited source file or NULL if not available @@ -1046,10 +1062,11 @@ find_scope_members_all(const GPtrArray *tags, const GPtrArray *searched_array, l @param function TRUE if the name is a name of a function @param member TRUE if invoked on class/struct member (e.g. after the last dot in foo.bar.) @param current_scope The current scope in the editor + @param search_namespace Whether to search the contents of namespace (e.g. after MyNamespace::) @return A GPtrArray of TMTag pointers to struct/union/class members or NULL when not found */ GPtrArray * tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name, - gboolean function, gboolean member, const gchar *current_scope) + gboolean function, gboolean member, const gchar *current_scope, gboolean search_namespace) { langType lang = source_file ? source_file->lang : -1; GPtrArray *tags, *member_tags = NULL; @@ -1059,26 +1076,40 @@ tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name, ~(function_types | tm_tag_enumerator_t | tm_tag_namespace_t | tm_tag_package_t); TMTagAttrType sort_attr[] = {tm_tag_attr_name_t, 0}; - if (function) - tag_type = function_types; + if (search_namespace) + { + tags = tm_workspace_find(name, NULL, tm_tag_namespace_t, NULL, lang); - /* tags corresponding to the variable/type name */ - tags = tm_workspace_find(name, NULL, tag_type, NULL, lang); + member_tags = find_namespace_members_all(tags, theWorkspace->tags_array, lang); + if (!member_tags) + member_tags = find_namespace_members_all(tags, theWorkspace->global_tags, lang); + + g_ptr_array_free(tags, TRUE); + } - /* Start searching inside the source file, continue with workspace tags and - * end with global tags. This way we find the "closest" tag to the current - * file in case there are more of them. */ - if (source_file) - member_tags = find_scope_members_all(tags, source_file->tags_array, - lang, member, current_scope); - if (!member_tags) - member_tags = find_scope_members_all(tags, theWorkspace->tags_array, lang, - member, current_scope); if (!member_tags) - member_tags = find_scope_members_all(tags, theWorkspace->global_tags, lang, - member, current_scope); + { + if (function) + tag_type = function_types; + + /* tags corresponding to the variable/type name */ + tags = tm_workspace_find(name, NULL, tag_type, NULL, lang); + + /* Start searching inside the source file, continue with workspace tags and + * end with global tags. This way we find the "closest" tag to the current + * file in case there are more of them. */ + if (source_file) + member_tags = find_scope_members_all(tags, source_file->tags_array, + lang, member, current_scope); + if (!member_tags) + member_tags = find_scope_members_all(tags, theWorkspace->tags_array, lang, + member, current_scope); + if (!member_tags) + member_tags = find_scope_members_all(tags, theWorkspace->global_tags, lang, + member, current_scope); - g_ptr_array_free(tags, TRUE); + g_ptr_array_free(tags, TRUE); + } tm_tags_dedup(member_tags, sort_attr, FALSE); diff --git a/tagmanager/src/tm_workspace.h b/tagmanager/src/tm_workspace.h index 50821224b9..f134eec545 100644 --- a/tagmanager/src/tm_workspace.h +++ b/tagmanager/src/tm_workspace.h @@ -61,7 +61,7 @@ GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type 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); + gboolean function, gboolean member, const gchar *current_scope, gboolean search_namespace); void tm_workspace_add_source_file_noupdate(TMSourceFile *source_file); From 5030f7f3da945c0caeb42e090991ad362d30a743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Techet?= Date: Sat, 13 Feb 2016 01:43:35 +0100 Subject: [PATCH 2/9] Cleanup NONE/AUTO filetype definitions At the moment the Geany code uses arbitrary combination of the following synonyms TM_PARSER_NONE / LANG_IGNORE / -2 TM_PARSER_AUTO / LANG_AUTO / -1 Especially using just the numbers makes things very confusing. In the Geany code this patch replaces all occurrences of -2 and LANG_IGNORE with TM_PARSER_NONE. It also removes LANG_IGNORE from the header which isn't needed any more. In addition, TM_PARSER_AUTO/LANG_AUTO shouldn't be used at all. We want filetype detection based on Geany's definitions and not based on the hard-coded ctags definitions. Remove it completely. Finally, as it's clearer now what the constants mean, the patch fixes the implementation of langs_compatible() (tag or file can never be of type AUTO but we should rather check for NONE filetypes which we should consider incompatible between each other). --- src/filetypes.c | 2 +- src/symbols.c | 4 ++-- tagmanager/src/tm_parser.h | 9 +-------- tagmanager/src/tm_source_file.c | 19 ++++++------------- tagmanager/src/tm_workspace.c | 7 ++++--- 5 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/filetypes.c b/src/filetypes.c index 218d24383b..8a8601a424 100644 --- a/src/filetypes.c +++ b/src/filetypes.c @@ -202,7 +202,7 @@ static GeanyFiletype *filetype_new(void) GeanyFiletype *ft = g_new0(GeanyFiletype, 1); ft->group = GEANY_FILETYPE_GROUP_NONE; - ft->lang = -2; /* assume no tagmanager parser */ + ft->lang = TM_PARSER_NONE; /* assume no tagmanager parser */ /* pattern must not be null */ ft->pattern = g_new0(gchar*, 1); ft->indent_width = -1; diff --git a/src/symbols.c b/src/symbols.c index db37514515..f7217519d3 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -295,8 +295,8 @@ GString *symbols_find_typenames_as_string(gint lang, gboolean global) /* the check for tag_lang == lang is necessary to avoid wrong type colouring of * e.g. PHP classes in C++ files - * lang = -2 disables the check */ - if (tag->name && (tag_lang == lang || lang == -2 || + * lang = TM_PARSER_NONE disables the check */ + if (tag->name && (tag_lang == lang || lang == TM_PARSER_NONE || (lang == TM_PARSER_CPP && tag_lang == TM_PARSER_C))) { if (j != 0) diff --git a/tagmanager/src/tm_parser.h b/tagmanager/src/tm_parser.h index 2e0edaceb8..6d859e0ab9 100644 --- a/tagmanager/src/tm_parser.h +++ b/tagmanager/src/tm_parser.h @@ -10,18 +10,11 @@ #ifndef TM_PARSER_H #define TM_PARSER_H -#ifndef LIBCTAGS_DEFINED -/* from ctags/parse.h */ -# define LANG_AUTO (-1) -# define LANG_IGNORE (-2) -#endif - /* keep in sync with ctags/parsers.h */ typedef enum { - TM_PARSER_NONE = LANG_IGNORE, - TM_PARSER_AUTO = LANG_AUTO, + TM_PARSER_NONE = -2, /* keep in sync with ctags LANG_IGNORE */ TM_PARSER_C = 0, TM_PARSER_CPP, TM_PARSER_JAVA, diff --git a/tagmanager/src/tm_source_file.c b/tagmanager/src/tm_source_file.c index af3d6499c5..9ba2398b85 100644 --- a/tagmanager/src/tm_source_file.c +++ b/tagmanager/src/tm_source_file.c @@ -34,6 +34,7 @@ #define LIBCTAGS_DEFINED #include "tm_source_file.h" #include "tm_tag.h" +#include "tm_parser.h" typedef struct { @@ -193,7 +194,7 @@ static gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_ } if (name == NULL) - source_file->lang = LANG_AUTO; + source_file->lang = TM_PARSER_NONE; else source_file->lang = getNamedLanguage(name); @@ -203,7 +204,7 @@ static gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_ /** Initializes a TMSourceFile structure and returns a pointer to it. The * TMSourceFile has to be added to TMWorkspace to start its parsing. * @param file_name The file name. - * @param name Name of the used programming language, NULL for autodetection. + * @param name Name of the used programming language, NULL to disable parsing. * @return The created unparsed TMSourceFile object. * */ GEANY_API_SYMBOL @@ -297,7 +298,7 @@ gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize return FALSE; } - if (source_file->lang == LANG_IGNORE) + if (source_file->lang == TM_PARSER_NONE) { tm_tags_array_free(source_file->tags_array, FALSE); return FALSE; @@ -342,15 +343,7 @@ gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize TagEntrySetArglistFunction = tm_source_file_set_tag_arglist; } current_source_file = source_file; - if (LANG_AUTO == source_file->lang) - source_file->lang = getFileLanguage (file_name); - if (source_file->lang == LANG_IGNORE) - { -#ifdef TM_DEBUG - g_warning("ignoring %s (unknown language)\n", file_name); -#endif - } - else if (! LanguageTable [source_file->lang]->enabled) + if (! LanguageTable [source_file->lang]->enabled) { #ifdef TM_DEBUG g_warning("ignoring %s (language disabled)\n", file_name); @@ -422,7 +415,7 @@ const gchar *tm_source_file_get_lang_name(gint lang) /* Gets the language index for \a name. @param name The language name. - @return The language index, or -2. + @return The language index, or TM_PARSER_NONE. */ gint tm_source_file_get_named_lang(const gchar *name) { diff --git a/tagmanager/src/tm_workspace.c b/tagmanager/src/tm_workspace.c index b20ed8d79d..fc4b7453a0 100644 --- a/tagmanager/src/tm_workspace.c +++ b/tagmanager/src/tm_workspace.c @@ -193,8 +193,7 @@ void tm_workspace_add_source_file_noupdate(TMSourceFile *source_file) you're editing. It's useful for a "real-time" updating of the tags. The tags array and the tags themselves are destroyed and re-created, hence any other tag arrays pointing to these tags should be rebuilt as well. All sorting - information is also lost. The language parameter is automatically detected - the first time the file is parsed if it is set to LANG_AUTO. + information is also lost. @param source_file The source file to update with a buffer. @param text_buf A text buffer. The user should take care of allocate and free it after the use here. @@ -688,7 +687,9 @@ gboolean tm_workspace_create_global_tags(const char *pre_process, const char **i static gboolean langs_compatible(langType lang, langType other) { - if (lang == other || lang == -1 || other == -1) + if (lang == TM_PARSER_NONE || other == TM_PARSER_NONE) + return FALSE; + if (lang == other) return TRUE; /* Accept CPP tags for C lang and vice versa */ else if (lang == TM_PARSER_C && other == TM_PARSER_CPP) From cb307e5b92479ce984aff01b106b1bdad346c0e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Techet?= Date: Sat, 13 Feb 2016 01:52:53 +0100 Subject: [PATCH 3/9] Use the langs_compatible() function when passing typenames to scintilla This requires making the function public and tm_tag.c seems to be a better place for the function than tm_workspace so move there and add the prefix. --- src/symbols.c | 6 +----- tagmanager/src/tm_tag.c | 16 ++++++++++++++++ tagmanager/src/tm_tag.h | 2 ++ tagmanager/src/tm_workspace.c | 22 +++------------------- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/symbols.c b/src/symbols.c index f7217519d3..045914694d 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -293,11 +293,7 @@ GString *symbols_find_typenames_as_string(gint lang, gboolean global) tag = TM_TAG(typedefs->pdata[j]); tag_lang = tag->lang; - /* the check for tag_lang == lang is necessary to avoid wrong type colouring of - * e.g. PHP classes in C++ files - * lang = TM_PARSER_NONE disables the check */ - if (tag->name && (tag_lang == lang || lang == TM_PARSER_NONE || - (lang == TM_PARSER_CPP && tag_lang == TM_PARSER_C))) + if (tag->name && tm_tag_langs_compatible(lang, tag_lang)) { if (j != 0) g_string_append_c(s, ' '); diff --git a/tagmanager/src/tm_tag.c b/tagmanager/src/tm_tag.c index ff559ee1e5..9e4da83a61 100644 --- a/tagmanager/src/tm_tag.c +++ b/tagmanager/src/tm_tag.c @@ -1226,6 +1226,22 @@ gboolean tm_tag_is_anon(const TMTag *tag) } +gboolean tm_tag_langs_compatible(langType lang, langType other) +{ + if (lang == TM_PARSER_NONE || other == TM_PARSER_NONE) + return FALSE; + if (lang == other) + return TRUE; + /* Accept CPP tags for C lang and vice versa */ + else if (lang == TM_PARSER_C && other == TM_PARSER_CPP) + return TRUE; + else if (lang == TM_PARSER_CPP && other == TM_PARSER_C) + return TRUE; + + return FALSE; +} + + #ifdef TM_DEBUG /* various debugging functions */ /* diff --git a/tagmanager/src/tm_tag.h b/tagmanager/src/tm_tag.h index 9441392d3d..4274e31f0f 100644 --- a/tagmanager/src/tm_tag.h +++ b/tagmanager/src/tm_tag.h @@ -195,6 +195,8 @@ const gchar *tm_tag_context_separator(langType lang); gboolean tm_tag_is_anon(const TMTag *tag); +gboolean tm_tag_langs_compatible(langType lang, langType other); + #ifdef TM_DEBUG /* various debugging functions */ const char *tm_tag_type_name(const TMTag *tag); diff --git a/tagmanager/src/tm_workspace.c b/tagmanager/src/tm_workspace.c index fc4b7453a0..e8554d97b2 100644 --- a/tagmanager/src/tm_workspace.c +++ b/tagmanager/src/tm_workspace.c @@ -685,22 +685,6 @@ gboolean tm_workspace_create_global_tags(const char *pre_process, const char **i } -static gboolean langs_compatible(langType lang, langType other) -{ - if (lang == TM_PARSER_NONE || other == TM_PARSER_NONE) - return FALSE; - if (lang == other) - return TRUE; - /* Accept CPP tags for C lang and vice versa */ - else if (lang == TM_PARSER_C && other == TM_PARSER_CPP) - return TRUE; - else if (lang == TM_PARSER_CPP && other == TM_PARSER_C) - return TRUE; - - return FALSE; -} - - static void fill_find_tags_array(GPtrArray *dst, const GPtrArray *src, const char *name, const char *scope, TMTagType type, langType lang) { @@ -714,7 +698,7 @@ static void fill_find_tags_array(GPtrArray *dst, const GPtrArray *src, for (i = 0; i < num; ++i) { if ((type & (*tag)->type) && - langs_compatible(lang, (*tag)->lang) && + tm_tag_langs_compatible(lang, (*tag)->lang) && (!scope || g_strcmp0((*tag)->scope, scope) == 0)) { g_ptr_array_add(dst, *tag); @@ -761,7 +745,7 @@ static void fill_find_tags_array_prefix(GPtrArray *dst, const GPtrArray *src, tag = tm_tags_find(src, name, TRUE, &count); for (i = 0; i < count && num < max_num; ++i) { - if (langs_compatible(lang, (*tag)->lang) && + if (tm_tag_langs_compatible(lang, (*tag)->lang) && !tm_tag_is_anon(*tag) && (!last || g_strcmp0(last->name, (*tag)->name) != 0)) { @@ -827,7 +811,7 @@ find_scope_members_tags (const GPtrArray *all, TMTag *type_tag, gboolean namespa if (tag && (tag->type & member_types) && tag->scope && tag->scope[0] != '\0' && - langs_compatible(tag->lang, type_tag->lang) && + tm_tag_langs_compatible(tag->lang, type_tag->lang) && strcmp(scope, tag->scope) == 0 && (!namespace || !tm_tag_is_anon(tag))) { From d1a5ceac424158218d585f8a34e527a537c17e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Techet?= Date: Sat, 13 Feb 2016 02:00:30 +0100 Subject: [PATCH 4/9] Don't pass multiple copies of identical type name to scintilla for colorization For instance for the boost library this makes the resulting string passed to scintilla 6x shorter. Because scintilla goes through this list more or less linearly for every single word in the document, this can bring significant reductions of time spent when recolorizing. --- src/symbols.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/symbols.c b/src/symbols.c index 045914694d..5268a055ce 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -287,17 +287,21 @@ GString *symbols_find_typenames_as_string(gint lang, gboolean global) if ((typedefs) && (typedefs->len > 0)) { + const gchar *last_name = ""; + s = g_string_sized_new(typedefs->len * 10); for (j = 0; j < typedefs->len; ++j) { tag = TM_TAG(typedefs->pdata[j]); tag_lang = tag->lang; - if (tag->name && tm_tag_langs_compatible(lang, tag_lang)) + if (tag->name && tm_tag_langs_compatible(lang, tag_lang) && + strcmp(tag->name, last_name) != 0) { if (j != 0) g_string_append_c(s, ' '); g_string_append(s, tag->name); + last_name = tag->name; } } } From 00cb498ebcc6b73499b9c5d2991490f64a5c765e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Techet?= Date: Sat, 13 Feb 2016 11:51:30 +0100 Subject: [PATCH 5/9] Don't use ctags types inside Geany We should isolate ctags from Geany completely and use separate types. At the moment langType is shared by both Geany and ctags. For Geany redefine it as TMParserType (which was currently used as the name of the enum and was unused) and use everywhere in Geany. At the same time convert some ints to TMParserType where they denote the parser. This is strictly speaking an API change but no plugin uses langType at the moment so its renaming doesn't cause any problems. The only remaining visible ctags type is tagEntryInfo - it is however used only inside tagmanager (and can be later removed quite easily too by slightly reorganizing TM source files). --- src/filetypes.h | 8 ++++---- tagmanager/src/tm_parser.h | 5 +++-- tagmanager/src/tm_source_file.c | 4 ++-- tagmanager/src/tm_source_file.h | 12 +++++------- tagmanager/src/tm_tag.c | 8 ++++---- tagmanager/src/tm_tag.h | 8 ++++---- tagmanager/src/tm_workspace.c | 22 +++++++++++----------- tagmanager/src/tm_workspace.h | 6 +++--- 8 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/filetypes.h b/src/filetypes.h index 9f5998333b..4bdc495b32 100644 --- a/src/filetypes.h +++ b/src/filetypes.h @@ -24,7 +24,7 @@ #define GEANY_FILETYPES_H 1 #include "geany.h" /* for GEANY() macro */ -#include "tm_source_file.h" /* for langType */ +#include "tm_parser.h" /* for TMParserType */ #include "gtkcompat.h" /* Needed by ScintillaWidget.h */ #include "Scintilla.h" /* Needed by ScintillaWidget.h */ @@ -134,9 +134,9 @@ GeanyFiletypeGroupID; typedef struct GeanyFiletype { GeanyFiletypeID id; /**< Index in @ref filetypes. */ - /** Represents the langType of tagmanager (see the table - * in tagmanager/parsers.h), -1 represents all, -2 none. */ - langType lang; + /** Represents the TMParserType of tagmanager (see the table + * in tagmanager/src/tm_parser.h). */ + TMParserType lang; /** Untranslated short name, such as "C", "None". * Must not be translated as it's used for hash table lookups - use * filetypes_get_display_name() instead. */ diff --git a/tagmanager/src/tm_parser.h b/tagmanager/src/tm_parser.h index 6d859e0ab9..642c57765a 100644 --- a/tagmanager/src/tm_parser.h +++ b/tagmanager/src/tm_parser.h @@ -10,9 +10,10 @@ #ifndef TM_PARSER_H #define TM_PARSER_H +typedef gint TMParserType; /* keep in sync with ctags/parsers.h */ -typedef enum +enum { TM_PARSER_NONE = -2, /* keep in sync with ctags LANG_IGNORE */ TM_PARSER_C = 0, @@ -67,7 +68,7 @@ typedef enum TM_PARSER_ZEPHIR, TM_PARSER_POWERSHELL, TM_PARSER_COUNT -} TMParserType; +}; #endif /* TM_PARSER_H */ diff --git a/tagmanager/src/tm_source_file.c b/tagmanager/src/tm_source_file.c index 9ba2398b85..dcb2bee674 100644 --- a/tagmanager/src/tm_source_file.c +++ b/tagmanager/src/tm_source_file.c @@ -399,7 +399,7 @@ gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize @param lang The language index. @return The language name, or NULL. */ -const gchar *tm_source_file_get_lang_name(gint lang) +const gchar *tm_source_file_get_lang_name(TMParserType lang) { if (NULL == LanguageTable) { @@ -417,7 +417,7 @@ const gchar *tm_source_file_get_lang_name(gint lang) @param name The language name. @return The language index, or TM_PARSER_NONE. */ -gint tm_source_file_get_named_lang(const gchar *name) +TMParserType tm_source_file_get_named_lang(const gchar *name) { if (NULL == LanguageTable) { diff --git a/tagmanager/src/tm_source_file.h b/tagmanager/src/tm_source_file.h index f2bdf4b1c9..64d5614fe6 100644 --- a/tagmanager/src/tm_source_file.h +++ b/tagmanager/src/tm_source_file.h @@ -14,14 +14,12 @@ #include #include +#include "tm_parser.h" + #ifndef LIBCTAGS_DEFINED -typedef int langType; typedef void tagEntryInfo; #endif -#if !defined(tagEntryInfo) -#endif - #ifdef __cplusplus extern "C" { @@ -39,7 +37,7 @@ extern "C" */ typedef struct { - langType lang; /**< Programming language used */ + TMParserType lang; /**< Programming language used */ char *file_name; /**< Full file name (inc. path) */ char *short_name; /**< Just the name of the file (without the path) */ GPtrArray *tags_array; /**< Sorted tag array obtained by parsing the object */ @@ -56,9 +54,9 @@ gchar *tm_get_real_path(const gchar *file_name); #ifdef GEANY_PRIVATE -const gchar *tm_source_file_get_lang_name(gint lang); +const gchar *tm_source_file_get_lang_name(TMParserType lang); -gint tm_source_file_get_named_lang(const gchar *name); +TMParserType tm_source_file_get_named_lang(const gchar *name); gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize buf_size, gboolean use_buffer); diff --git a/tagmanager/src/tm_tag.c b/tagmanager/src/tm_tag.c index 9e4da83a61..dbab8d5a74 100644 --- a/tagmanager/src/tm_tag.c +++ b/tagmanager/src/tm_tag.c @@ -562,9 +562,9 @@ static gboolean tm_tag_init_from_file_ctags(TMTag *tag, TMSourceFile *file, FILE /* Same as tm_tag_new() except that the tag attributes are read from file. - @param mode langType to use for the tag. + @param mode TMParserType to use for the tag. */ -TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp, gint mode, TMFileFormat format) +TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp, TMParserType mode, TMFileFormat format) { TMTag *tag; gboolean result = FALSE; @@ -1182,7 +1182,7 @@ tm_get_current_tag (GPtrArray * file_tags, const gulong line, const TMTagType ta return matching_tag; } -const gchar *tm_tag_context_separator(langType lang) +const gchar *tm_tag_context_separator(TMParserType lang) { switch (lang) { @@ -1226,7 +1226,7 @@ gboolean tm_tag_is_anon(const TMTag *tag) } -gboolean tm_tag_langs_compatible(langType lang, langType other) +gboolean tm_tag_langs_compatible(TMParserType lang, TMParserType other) { if (lang == TM_PARSER_NONE || other == TM_PARSER_NONE) return FALSE; diff --git a/tagmanager/src/tm_tag.h b/tagmanager/src/tm_tag.h index 4274e31f0f..2116d69c3e 100644 --- a/tagmanager/src/tm_tag.h +++ b/tagmanager/src/tm_tag.h @@ -137,7 +137,7 @@ typedef struct _TMTag char *var_type; /**< Variable type (maps to struct for typedefs) */ char access; /**< Access type (public/protected/private/etc.) */ char impl; /**< Implementation (e.g. virtual) */ - langType lang; /**< Programming language of the file */ + TMParserType lang; /**< Programming language of the file */ } TMTag; @@ -160,7 +160,7 @@ GType tm_tag_get_type(void) G_GNUC_CONST; TMTag *tm_tag_new(TMSourceFile *file, const tagEntryInfo *tag_entry); -TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp, gint mode, TMFileFormat format); +TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp, TMParserType mode, TMFileFormat format); gboolean tm_tag_write(TMTag *tag, FILE *file, guint attrs); @@ -191,11 +191,11 @@ TMTag *tm_tag_ref(TMTag *tag); gboolean tm_tags_equal(const TMTag *a, const TMTag *b); -const gchar *tm_tag_context_separator(langType lang); +const gchar *tm_tag_context_separator(TMParserType lang); gboolean tm_tag_is_anon(const TMTag *tag); -gboolean tm_tag_langs_compatible(langType lang, langType other); +gboolean tm_tag_langs_compatible(TMParserType lang, TMParserType other); #ifdef TM_DEBUG /* various debugging functions */ diff --git a/tagmanager/src/tm_workspace.c b/tagmanager/src/tm_workspace.c index e8554d97b2..60c3ca046c 100644 --- a/tagmanager/src/tm_workspace.c +++ b/tagmanager/src/tm_workspace.c @@ -502,7 +502,7 @@ static gchar *create_temp_file(const gchar *tpl) @return TRUE on success, FALSE on failure. */ gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes, - int includes_count, const char *tags_file, int lang) + int includes_count, const char *tags_file, TMParserType lang) { #ifdef HAVE_GLOB_H glob_t globbuf; @@ -686,7 +686,7 @@ gboolean tm_workspace_create_global_tags(const char *pre_process, const char **i static void fill_find_tags_array(GPtrArray *dst, const GPtrArray *src, - const char *name, const char *scope, TMTagType type, langType lang) + const char *name, const char *scope, TMTagType type, TMParserType lang) { TMTag **tag; guint i, num; @@ -718,7 +718,7 @@ static void fill_find_tags_array(GPtrArray *dst, const GPtrArray *src, @return Array of matching tags. */ GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type, - TMTagAttrType *attrs, langType lang) + TMTagAttrType *attrs, TMParserType lang) { GPtrArray *tags = g_ptr_array_new(); @@ -733,7 +733,7 @@ GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type static void fill_find_tags_array_prefix(GPtrArray *dst, const GPtrArray *src, - const char *name, langType lang, guint max_num) + const char *name, TMParserType lang, guint max_num) { TMTag **tag, *last = NULL; guint i, count, num; @@ -766,7 +766,7 @@ static void fill_find_tags_array_prefix(GPtrArray *dst, const GPtrArray *src, @param max_num The maximum number of tags to return. @return Array of matching tags sorted by their name. */ -GPtrArray *tm_workspace_find_prefix(const char *prefix, langType lang, guint max_num) +GPtrArray *tm_workspace_find_prefix(const char *prefix, TMParserType lang, guint max_num) { TMTagAttrType attrs[] = { tm_tag_attr_name_t, 0 }; GPtrArray *tags = g_ptr_array_new(); @@ -831,7 +831,7 @@ find_scope_members_tags (const GPtrArray *all, TMTag *type_tag, gboolean namespa } -static gchar *strip_type(const gchar *scoped_name, langType lang) +static gchar *strip_type(const gchar *scoped_name, TMParserType lang) { if (scoped_name != NULL) { @@ -853,7 +853,7 @@ static gchar *strip_type(const gchar *scoped_name, langType lang) /* Gets all members of the type with the given name; search them inside tags_array */ static GPtrArray * find_scope_members (const GPtrArray *tags_array, const gchar *name, TMSourceFile *file, - langType lang, gboolean namespace) + TMParserType lang, gboolean namespace) { GPtrArray *res = NULL; gchar *type_name; @@ -930,7 +930,7 @@ find_scope_members (const GPtrArray *tags_array, const gchar *name, TMSourceFile /* Checks whether a member tag is directly accessible from method with method_scope */ static gboolean member_at_method_scope(const GPtrArray *tags, const gchar *method_scope, TMTag *member_tag, - langType lang) + TMParserType lang) { const gchar *sep = tm_tag_context_separator(lang); gboolean ret = FALSE; @@ -980,7 +980,7 @@ static gboolean member_at_method_scope(const GPtrArray *tags, const gchar *metho /* For an array of variable/type tags, find members inside the types */ static GPtrArray * -find_scope_members_all(const GPtrArray *tags, const GPtrArray *searched_array, langType lang, +find_scope_members_all(const GPtrArray *tags, const GPtrArray *searched_array, TMParserType lang, gboolean member, const gchar *current_scope) { GPtrArray *member_tags = NULL; @@ -1024,7 +1024,7 @@ find_scope_members_all(const GPtrArray *tags, const GPtrArray *searched_array, l } -static GPtrArray *find_namespace_members_all(const GPtrArray *tags, const GPtrArray *searched_array, langType lang) +static GPtrArray *find_namespace_members_all(const GPtrArray *tags, const GPtrArray *searched_array, TMParserType lang) { GPtrArray *member_tags = NULL; guint i; @@ -1053,7 +1053,7 @@ GPtrArray * tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name, gboolean function, gboolean member, const gchar *current_scope, gboolean search_namespace) { - langType lang = source_file ? source_file->lang : -1; + TMParserType lang = source_file ? source_file->lang : -1; GPtrArray *tags, *member_tags = NULL; TMTagType function_types = tm_tag_function_t | tm_tag_method_t | tm_tag_macro_with_arg_t | tm_tag_prototype_t; diff --git a/tagmanager/src/tm_workspace.h b/tagmanager/src/tm_workspace.h index f134eec545..b2f100c546 100644 --- a/tagmanager/src/tm_workspace.h +++ b/tagmanager/src/tm_workspace.h @@ -53,12 +53,12 @@ const TMWorkspace *tm_get_workspace(void); 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); + int includes_count, const char *tags_file, TMParserType lang); GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type, - TMTagAttrType *attrs, langType lang); + TMTagAttrType *attrs, TMParserType lang); -GPtrArray *tm_workspace_find_prefix(const char *prefix, langType lang, guint max_num); +GPtrArray *tm_workspace_find_prefix(const char *prefix, TMParserType lang, guint max_num); GPtrArray *tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name, gboolean function, gboolean member, const gchar *current_scope, gboolean search_namespace); From 292383c197b72c56f44b68b14845093adfed7133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Techet?= Date: Sat, 20 Feb 2016 23:50:23 +0100 Subject: [PATCH 6/9] Some more uses of TMParserType instead of int --- src/filetypes.c | 6 +++--- src/symbols.c | 4 ++-- src/symbols.h | 4 +--- tagmanager/src/tm_workspace.c | 6 +++--- tagmanager/src/tm_workspace.h | 2 +- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/filetypes.c b/src/filetypes.c index 8a8601a424..a9a74595b3 100644 --- a/src/filetypes.c +++ b/src/filetypes.c @@ -103,7 +103,7 @@ static gchar *filetype_make_title(const char *name, enum TitleType type) /* name argument (ie filetype name) must not be translated as it is used for * filetype lookup. Use filetypes_get_display_name() instead.*/ -static void ft_init(filetype_id ft_id, int lang, const char *name, +static void ft_init(filetype_id ft_id, TMParserType lang, const char *name, const char *title_name, enum TitleType title_type, GeanyFiletypeGroupID group_id) { @@ -950,7 +950,7 @@ static void load_settings(guint ft_id, GKeyFile *config, GKeyFile *configh) if (result != NULL) { ft->lang = tm_source_file_get_named_lang(result); - if (ft->lang < 0) + if (ft->lang == TM_PARSER_NONE) geany_debug("Cannot find tags parser '%s' for custom filetype '%s'.", result, ft->name); g_free(result); } @@ -1240,7 +1240,7 @@ gboolean filetype_has_tags(GeanyFiletype *ft) { g_return_val_if_fail(ft != NULL, FALSE); - return ft->lang >= 0; + return ft->lang != TM_PARSER_NONE; } diff --git a/src/symbols.c b/src/symbols.c index 5268a055ce..c3aeffbf8e 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -272,13 +272,13 @@ static void html_tags_loaded(void) } -GString *symbols_find_typenames_as_string(gint lang, gboolean global) +GString *symbols_find_typenames_as_string(TMParserType lang, gboolean global) { guint j; TMTag *tag; GString *s = NULL; GPtrArray *typedefs; - gint tag_lang; + TMParserType tag_lang; if (global) typedefs = app->tm_workspace->global_typename_array; diff --git a/src/symbols.h b/src/symbols.h index 1afbd29e95..8a325aaa0a 100644 --- a/src/symbols.h +++ b/src/symbols.h @@ -50,9 +50,7 @@ void symbols_reload_config_files(void); void symbols_global_tags_loaded(guint file_type_idx); -GString *symbols_find_typenames_as_string(gint lang, gboolean global); - -const GList *symbols_get_tag_list(GeanyDocument *doc, guint tag_types); +GString *symbols_find_typenames_as_string(TMParserType lang, gboolean global); const gchar **symbols_get_html_entities(void); diff --git a/tagmanager/src/tm_workspace.c b/tagmanager/src/tm_workspace.c index 60c3ca046c..8e51f84677 100644 --- a/tagmanager/src/tm_workspace.c +++ b/tagmanager/src/tm_workspace.c @@ -337,7 +337,7 @@ void tm_workspace_remove_source_files(GPtrArray *source_files) @return TRUE on success, FALSE on failure. @see tm_workspace_create_global_tags() */ -gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode) +gboolean tm_workspace_load_global_tags(const char *tags_file, TMParserType mode) { guchar buf[BUFSIZ]; FILE *fp; @@ -1042,7 +1042,7 @@ static GPtrArray *find_namespace_members_all(const GPtrArray *tags, const GPtrAr /* Returns all member tags of a struct/union/class if the provided name is a variable of such a type or the name of the type. - @param source_file TMSourceFile of the edited source file or NULL if not available + @param source_file TMSourceFile of the edited source file @param name Name of the variable/type whose members are searched @param function TRUE if the name is a name of a function @param member TRUE if invoked on class/struct member (e.g. after the last dot in foo.bar.) @@ -1053,7 +1053,7 @@ GPtrArray * tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name, gboolean function, gboolean member, const gchar *current_scope, gboolean search_namespace) { - TMParserType lang = source_file ? source_file->lang : -1; + TMParserType lang = source_file->lang; GPtrArray *tags, *member_tags = NULL; TMTagType function_types = tm_tag_function_t | tm_tag_method_t | tm_tag_macro_with_arg_t | tm_tag_prototype_t; diff --git a/tagmanager/src/tm_workspace.h b/tagmanager/src/tm_workspace.h index b2f100c546..173766b97a 100644 --- a/tagmanager/src/tm_workspace.h +++ b/tagmanager/src/tm_workspace.h @@ -50,7 +50,7 @@ void tm_workspace_remove_source_files(GPtrArray *source_files); const TMWorkspace *tm_get_workspace(void); -gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode); +gboolean tm_workspace_load_global_tags(const char *tags_file, TMParserType mode); gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes, int includes_count, const char *tags_file, TMParserType lang); From 833921e6ee793d5d27a4e1ac4a9ef212676c2328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Techet?= Date: Fri, 26 Feb 2016 01:29:50 +0100 Subject: [PATCH 7/9] Install tm_parser.h Included now in other headers and needed for successful plugin compilation. --- tagmanager/src/Makefile.am | 3 ++- wscript | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tagmanager/src/Makefile.am b/tagmanager/src/Makefile.am index 65ee42c5ab..ba05ca0097 100644 --- a/tagmanager/src/Makefile.am +++ b/tagmanager/src/Makefile.am @@ -18,7 +18,8 @@ tagmanager_include_HEADERS = \ tm_source_file.h \ tm_tag.h \ tm_tagmanager.h \ - tm_workspace.h + tm_workspace.h \ + tm_parser.h libtagmanager_la_SOURCES =\ diff --git a/wscript b/wscript index d7cabeb721..ac6e49dd23 100644 --- a/wscript +++ b/wscript @@ -671,7 +671,8 @@ def build(bld): tagmanager/src/tm_source_file.h tagmanager/src/tm_tag.h tagmanager/src/tm_tagmanager.h - tagmanager/src/tm_workspace.h ''') + tagmanager/src/tm_workspace.h + tagmanager/src/tm_parser.h ''') # Docs base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}' ext = '.txt' if is_win32 else '' From 86cb9aeac0f3d32c6a93688dbe49039fb24f15e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Techet?= Date: Fri, 26 Feb 2016 01:40:37 +0100 Subject: [PATCH 8/9] Make the use of TMParserType private Or semi-private by removing the docstring. --- src/filetypes.h | 2 +- tagmanager/src/tm_parser.h | 4 ++++ tagmanager/src/tm_source_file.h | 2 +- tagmanager/src/tm_tag.h | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/filetypes.h b/src/filetypes.h index 4bdc495b32..19c7e9adb9 100644 --- a/src/filetypes.h +++ b/src/filetypes.h @@ -134,7 +134,7 @@ GeanyFiletypeGroupID; typedef struct GeanyFiletype { GeanyFiletypeID id; /**< Index in @ref filetypes. */ - /** Represents the TMParserType of tagmanager (see the table + /* Represents the TMParserType of tagmanager (see the table * in tagmanager/src/tm_parser.h). */ TMParserType lang; /** Untranslated short name, such as "C", "None". diff --git a/tagmanager/src/tm_parser.h b/tagmanager/src/tm_parser.h index 642c57765a..9b3c237420 100644 --- a/tagmanager/src/tm_parser.h +++ b/tagmanager/src/tm_parser.h @@ -12,6 +12,9 @@ typedef gint TMParserType; + +#ifdef GEANY_PRIVATE + /* keep in sync with ctags/parsers.h */ enum { @@ -70,5 +73,6 @@ enum TM_PARSER_COUNT }; +#endif /* GEANY_PRIVATE */ #endif /* TM_PARSER_H */ diff --git a/tagmanager/src/tm_source_file.h b/tagmanager/src/tm_source_file.h index 64d5614fe6..2ecd9d7bc2 100644 --- a/tagmanager/src/tm_source_file.h +++ b/tagmanager/src/tm_source_file.h @@ -37,7 +37,7 @@ extern "C" */ typedef struct { - TMParserType lang; /**< Programming language used */ + TMParserType lang; /* Programming language used */ char *file_name; /**< Full file name (inc. path) */ char *short_name; /**< Just the name of the file (without the path) */ GPtrArray *tags_array; /**< Sorted tag array obtained by parsing the object */ diff --git a/tagmanager/src/tm_tag.h b/tagmanager/src/tm_tag.h index 2116d69c3e..ac7886ec49 100644 --- a/tagmanager/src/tm_tag.h +++ b/tagmanager/src/tm_tag.h @@ -137,7 +137,7 @@ typedef struct _TMTag char *var_type; /**< Variable type (maps to struct for typedefs) */ char access; /**< Access type (public/protected/private/etc.) */ char impl; /**< Implementation (e.g. virtual) */ - TMParserType lang; /**< Programming language of the file */ + TMParserType lang; /* Programming language of the file */ } TMTag; From 2d88bc9a63a57fccad4ae072faf74a914860a7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Techet?= Date: Sun, 28 Feb 2016 16:22:45 +0100 Subject: [PATCH 9/9] Bump GEANY_API_VERSION for langType rename --- src/plugindata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugindata.h b/src/plugindata.h index 63dd373c89..8e84d6a3cf 100644 --- a/src/plugindata.h +++ b/src/plugindata.h @@ -58,7 +58,7 @@ G_BEGIN_DECLS * @warning You should not test for values below 200 as previously * @c GEANY_API_VERSION was defined as an enum value, not a macro. */ -#define GEANY_API_VERSION 227 +#define GEANY_API_VERSION 228 /* hack to have a different ABI when built with GTK3 because loading GTK2-linked plugins * with GTK3-linked Geany leads to crash */