From 00271842a395d195c405ce300b773ede5b8060cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Tr=C3=B6ger?= Date: Wed, 16 Sep 2015 21:58:29 +0200 Subject: [PATCH 1/2] Move bookmark list refresh into an idle callback This should delay updates on Scintilla events until the GLib main loop is idling, assuming the typing or other text modifications are finished. --- addons/src/ao_bookmarklist.c | 38 +++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/addons/src/ao_bookmarklist.c b/addons/src/ao_bookmarklist.c index 3e78195e6..07c052d8b 100644 --- a/addons/src/ao_bookmarklist.c +++ b/addons/src/ao_bookmarklist.c @@ -62,8 +62,16 @@ struct _AoBookmarkListPrivate gint search_line; GtkTreeIter *search_iter; + + guint refresh_idle_source_id; }; +typedef struct +{ + AoBookmarkList *bm; + GeanyDocument *document; +} AoBookmarkListRefreshContainer; + enum { PROP_0, @@ -401,14 +409,17 @@ void ao_bookmark_list_activate(AoBookmarkList *bm) } -void ao_bookmark_list_update(AoBookmarkList *bm, GeanyDocument *doc) +static gboolean update_bookmark_list_delayed(gpointer data) { gint line_nr = 0; gint mask = 1 << 1; - ScintillaObject *sci = doc->editor->sci; + AoBookmarkListRefreshContainer *container = data; + AoBookmarkList *bm = container->bm; AoBookmarkListPrivate *priv = AO_BOOKMARK_LIST_GET_PRIVATE(bm); + GeanyDocument *doc = container->document; + ScintillaObject *sci = doc->editor->sci; - if (priv->enable_bookmarklist) + if (priv->enable_bookmarklist && DOC_VALID(doc)) { gtk_list_store_clear(priv->store); while ((line_nr = scintilla_send_message(sci, SCI_MARKERNEXT, line_nr, mask)) != -1) @@ -417,6 +428,26 @@ void ao_bookmark_list_update(AoBookmarkList *bm, GeanyDocument *doc) line_nr++; } } + + g_free(container); + priv->refresh_idle_source_id = 0; + return FALSE; +} + + +void ao_bookmark_list_update(AoBookmarkList *bm, GeanyDocument *doc) +{ + AoBookmarkListPrivate *priv = AO_BOOKMARK_LIST_GET_PRIVATE(bm); + if (priv->refresh_idle_source_id == 0) + { + AoBookmarkListRefreshContainer *container = g_new0(AoBookmarkListRefreshContainer, 1); + container->bm = bm; + container->document = doc; + priv->refresh_idle_source_id = plugin_idle_add( + geany_plugin, + update_bookmark_list_delayed, + container); + } } @@ -444,6 +475,7 @@ static void ao_bookmark_list_init(AoBookmarkList *self) AoBookmarkListPrivate *priv = AO_BOOKMARK_LIST_GET_PRIVATE(self); priv->page = NULL; + priv->refresh_idle_source_id = 0; } From 0ecdc4253a5c2d3032a9d8c5e2b26a645d7b0b3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Tr=C3=B6ger?= Date: Wed, 16 Sep 2015 23:10:26 +0200 Subject: [PATCH 2/2] Update bookmark list also on any line changes in the document In addition to updating the bookmark list on document notebook tab change and adding/removing line markers, also rebuild the bookmark list when the text in the document changes with lines added or deleted. Should fix SF bugs #129 and #39. --- addons/src/ao_bookmarklist.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/addons/src/ao_bookmarklist.c b/addons/src/ao_bookmarklist.c index 07c052d8b..0d0ad4432 100644 --- a/addons/src/ao_bookmarklist.c +++ b/addons/src/ao_bookmarklist.c @@ -69,7 +69,7 @@ struct _AoBookmarkListPrivate typedef struct { AoBookmarkList *bm; - GeanyDocument *document; + guint document_id; } AoBookmarkListRefreshContainer; enum @@ -416,11 +416,12 @@ static gboolean update_bookmark_list_delayed(gpointer data) AoBookmarkListRefreshContainer *container = data; AoBookmarkList *bm = container->bm; AoBookmarkListPrivate *priv = AO_BOOKMARK_LIST_GET_PRIVATE(bm); - GeanyDocument *doc = container->document; - ScintillaObject *sci = doc->editor->sci; + GeanyDocument *doc = document_find_by_id(container->document_id); - if (priv->enable_bookmarklist && DOC_VALID(doc)) + if (priv->enable_bookmarklist && doc != NULL) { + ScintillaObject *sci = doc->editor->sci; + gtk_list_store_clear(priv->store); while ((line_nr = scintilla_send_message(sci, SCI_MARKERNEXT, line_nr, mask)) != -1) { @@ -438,11 +439,13 @@ static gboolean update_bookmark_list_delayed(gpointer data) void ao_bookmark_list_update(AoBookmarkList *bm, GeanyDocument *doc) { AoBookmarkListPrivate *priv = AO_BOOKMARK_LIST_GET_PRIVATE(bm); + if (priv->refresh_idle_source_id == 0) { AoBookmarkListRefreshContainer *container = g_new0(AoBookmarkListRefreshContainer, 1); + container->bm = bm; - container->document = doc; + container->document_id = doc->id; priv->refresh_idle_source_id = plugin_idle_add( geany_plugin, update_bookmark_list_delayed, @@ -455,16 +458,23 @@ void ao_bookmark_list_update_marker(AoBookmarkList *bm, GeanyEditor *editor, SCN { AoBookmarkListPrivate *priv = AO_BOOKMARK_LIST_GET_PRIVATE(bm); - if (priv->enable_bookmarklist && - nt->nmhdr.code == SCN_MODIFIED && nt->modificationType == SC_MOD_CHANGEMARKER) + if (priv->enable_bookmarklist && nt->nmhdr.code == SCN_MODIFIED) { - if (sci_is_marker_set_at_line(editor->sci, nt->line, 1)) + if (nt->modificationType == SC_MOD_CHANGEMARKER) { - add_line(bm, editor->sci, nt->line); + if (sci_is_marker_set_at_line(editor->sci, nt->line, 1)) + { + add_line(bm, editor->sci, nt->line); + } + else + { + delete_line(bm, nt->line); + } } - else + else if (nt->linesAdded != 0) { - delete_line(bm, nt->line); + /* if any lines changed, refresh the whole list as we refer line numbers */ + ao_bookmark_list_update(bm, editor->document); } } }