Keep a separate list of typenames for Scintilla syntax highlighting

Manage the list the same way as workspace tags_array by the fast tag removal
and merge. Thanks to this, typename tags don't have to be extracted from
tags_array periodically, which speeds up editing.
This commit is contained in:
Jiří Techet 2014-10-30 18:46:46 +01:00
parent 32a3dfab7f
commit bdee1336aa
8 changed files with 44 additions and 40 deletions

View File

@ -2558,8 +2558,7 @@ void document_highlight_tags(GeanyDocument *doc)
/* get any type keywords and tell scintilla about them
* this will cause the type keywords to be colourized in scintilla */
keywords_str = symbols_find_tags_as_string(app->tm_workspace->tags_array,
TM_GLOBAL_TYPE_MASK, doc->file_type->lang);
keywords_str = symbols_find_typenames_as_string(doc->file_type->lang, FALSE);
if (keywords_str)
{
keywords = g_string_free(keywords_str, FALSE);

View File

@ -433,23 +433,6 @@ void highlighting_free_styles(void)
}
static GString *get_global_typenames(gint lang)
{
GString *s = NULL;
if (app->tm_workspace)
{
GPtrArray *tags_array = app->tm_workspace->global_tags;
if (tags_array)
{
s = symbols_find_tags_as_string(tags_array, TM_GLOBAL_TYPE_MASK, lang);
}
}
return s;
}
static gchar*
get_keyfile_whitespace_chars(GKeyFile *config, GKeyFile *configh)
{
@ -823,7 +806,7 @@ static void merge_type_keywords(ScintillaObject *sci, guint ft_id, guint keyword
const gchar *user_words = style_sets[ft_id].keywords[keyword_idx];
GString *s;
s = get_global_typenames(filetypes[ft_id]->lang);
s = symbols_find_typenames_as_string(filetypes[ft_id]->lang, TRUE);
if (G_UNLIKELY(s == NULL))
s = g_string_sized_new(200);
else

View File

@ -64,11 +64,6 @@
#include <stdlib.h>
const guint TM_GLOBAL_TYPE_MASK =
tm_tag_class_t | tm_tag_enum_t | tm_tag_interface_t |
tm_tag_struct_t | tm_tag_typedef_t | tm_tag_union_t | tm_tag_namespace_t;
static gchar **html_entities = NULL;
typedef struct
@ -248,7 +243,7 @@ static void html_tags_loaded(void)
}
GString *symbols_find_tags_as_string(GPtrArray *tags_array, guint tag_types, gint lang)
GString *symbols_find_typenames_as_string(gint lang, gboolean global)
{
guint j;
TMTag *tag;
@ -256,9 +251,10 @@ GString *symbols_find_tags_as_string(GPtrArray *tags_array, guint tag_types, gin
GPtrArray *typedefs;
gint tag_lang;
g_return_val_if_fail(tags_array != NULL, NULL);
typedefs = tm_tags_extract(tags_array, tag_types);
if (global)
typedefs = tm_tags_extract(app->tm_workspace->global_tags, TM_GLOBAL_TYPE_MASK);
else
typedefs = app->tm_workspace->typename_array;
if ((typedefs) && (typedefs->len > 0))
{
@ -280,7 +276,7 @@ GString *symbols_find_tags_as_string(GPtrArray *tags_array, guint tag_types, gin
}
}
}
if (typedefs)
if (typedefs && global)
g_ptr_array_free(typedefs, TRUE);
return s;
}

View File

@ -34,8 +34,6 @@ const gchar *symbols_get_context_separator(gint ft_id);
#ifdef GEANY_PRIVATE
extern const guint TM_GLOBAL_TYPE_MASK;
enum
{
SYMBOLS_SORT_BY_NAME,
@ -52,7 +50,7 @@ void symbols_reload_config_files(void);
void symbols_global_tags_loaded(guint file_type_idx);
GString *symbols_find_tags_as_string(GPtrArray *tags_array, guint tag_types, gint lang);
GString *symbols_find_typenames_as_string(gint lang, gboolean global);
const GList *symbols_get_tag_list(GeanyDocument *doc, guint tag_types);

View File

@ -78,6 +78,11 @@ static void log_tag_free(TMTag *tag)
#endif /* DEBUG_TAG_REFS */
const guint TM_GLOBAL_TYPE_MASK =
tm_tag_class_t | tm_tag_enum_t | tm_tag_interface_t |
tm_tag_struct_t | tm_tag_typedef_t | tm_tag_union_t | tm_tag_namespace_t;
/* Note: To preserve binary compatibility, it is very important
that you only *append* to this list ! */
enum

View File

@ -143,6 +143,9 @@ typedef struct _TMTag
#ifdef GEANY_PRIVATE
extern const guint TM_GLOBAL_TYPE_MASK;
typedef enum {
TM_FILE_FORMAT_TAGMANAGER,
TM_FILE_FORMAT_PIPE,

View File

@ -44,6 +44,7 @@ static gboolean tm_create_workspace(void)
theWorkspace->global_tags = g_ptr_array_new();
theWorkspace->source_files = g_ptr_array_new();
theWorkspace->typename_array = g_ptr_array_new();
return TRUE;
}
@ -63,6 +64,7 @@ void tm_workspace_free(void)
g_ptr_array_free(theWorkspace->source_files, TRUE);
tm_tags_array_free(theWorkspace->global_tags, TRUE);
g_ptr_array_free(theWorkspace->tags_array, TRUE);
g_ptr_array_free(theWorkspace->typename_array, TRUE);
g_free(theWorkspace);
theWorkspace = NULL;
}
@ -108,7 +110,10 @@ void tm_workspace_remove_source_file(TMSourceFile *source_file, gboolean update_
if (theWorkspace->source_files->pdata[i] == source_file)
{
if (update_workspace)
{
tm_tags_remove_file_tags(source_file, theWorkspace->tags_array);
tm_tags_remove_file_tags(source_file, theWorkspace->typename_array);
}
g_ptr_array_remove_index_fast(theWorkspace->source_files, i);
return;
}
@ -506,18 +511,19 @@ void tm_workspace_update(void)
g_message("Total: %d tags", theWorkspace->tags_array->len);
#endif
tm_tags_sort(theWorkspace->tags_array, sort_attrs, TRUE, FALSE);
theWorkspace->typename_array = tm_tags_extract(theWorkspace->tags_array, TM_GLOBAL_TYPE_MASK);
}
static void tm_workspace_merge_file_tags(TMSourceFile *source_file)
static void tm_workspace_merge_tags(GPtrArray **big_array, GPtrArray *small_array)
{
TMTagAttrType sort_attrs[] = { tm_tag_attr_name_t, tm_tag_attr_file_t,
tm_tag_attr_scope_t, tm_tag_attr_type_t, tm_tag_attr_arglist_t, 0};
GPtrArray *new_tags = tm_tags_merge(theWorkspace->tags_array,
source_file->tags_array, sort_attrs, FALSE);
GPtrArray *new_tags = tm_tags_merge(*big_array, small_array, sort_attrs, FALSE);
/* tags owned by TMSourceFile - free just the pointer array */
g_ptr_array_free(theWorkspace->tags_array, TRUE);
theWorkspace->tags_array = new_tags;
g_ptr_array_free(*big_array, TRUE);
*big_array = new_tags;
}
/** Updates the source file by reparsing. The tags array and
@ -540,15 +546,22 @@ void tm_workspace_update_source_file(TMSourceFile *source_file, gboolean update_
/* tm_source_file_parse() deletes the tag objects - remove the tags from
* workspace while they exist and can be scanned */
tm_tags_remove_file_tags(source_file, theWorkspace->tags_array);
tm_tags_remove_file_tags(source_file, theWorkspace->typename_array);
}
tm_source_file_parse(source_file);
tm_tags_sort(source_file->tags_array, NULL, FALSE, TRUE);
if (update_workspace)
{
GPtrArray *sf_typedefs;
#ifdef TM_DEBUG
g_message("Updating workspace from source file");
#endif
tm_workspace_merge_file_tags(source_file);
tm_workspace_merge_tags(&theWorkspace->tags_array, source_file->tags_array);
sf_typedefs = tm_tags_extract(source_file->tags_array, TM_GLOBAL_TYPE_MASK);
tm_workspace_merge_tags(&theWorkspace->typename_array, sf_typedefs);
g_ptr_array_free(sf_typedefs, TRUE);
}
#ifdef TM_DEBUG
else
@ -592,10 +605,16 @@ void tm_workspace_update_source_file_buffer(TMSourceFile *source_file, guchar* t
tm_tags_sort(source_file->tags_array, NULL, FALSE, TRUE);
if (update_workspace)
{
GPtrArray *sf_typedefs;
#ifdef TM_DEBUG
g_message("Updating workspace from buffer..");
#endif
tm_workspace_merge_file_tags(source_file);
tm_workspace_merge_tags(&theWorkspace->tags_array, source_file->tags_array);
sf_typedefs = tm_tags_extract(source_file->tags_array, TM_GLOBAL_TYPE_MASK);
tm_workspace_merge_tags(&theWorkspace->typename_array, sf_typedefs);
g_ptr_array_free(sf_typedefs, TRUE);
}
#ifdef TM_DEBUG
else

View File

@ -32,6 +32,7 @@ typedef struct
GPtrArray *source_files; /**< An array of TMSourceFile pointers */
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) */
} TMWorkspace;
void tm_workspace_add_source_file(TMSourceFile *source_file);