diff --git a/plugins/word-completion/engine.vala b/plugins/word-completion/engine.vala index eff236042f..2b1febb48b 100644 --- a/plugins/word-completion/engine.vala +++ b/plugins/word-completion/engine.vala @@ -22,7 +22,7 @@ public class Euclide.Completion.Parser : GLib.Object { public const int MINIMUM_WORD_LENGTH = 1; public const int MAX_TOKENS = 1000000; - private Scratch.Plugins.PrefixTree prefix_tree; + private Scratch.Plugins.PrefixTree? prefix_tree = null; public const string DELIMITERS = " .,;:?{}[]()0123456789+=&|<>*\\/\r\n\t\'\"`"; public static bool is_delimiter (unichar c) { @@ -53,26 +53,38 @@ public class Euclide.Completion.Parser : GLib.Object { public void rebuild_word_list (Gtk.TextView view) { prefix_tree.clear (); - parse_text_view (view); + if (view.buffer.text.length > 0) { + parse_string (view.buffer.text); + text_view_words.@set (view, prefix_tree); + } } - public void parse_text_view (Gtk.TextView view) { - /* If this view has already been parsed, restore the word list */ + public bool select_current_tree (Gtk.TextView view) { + bool pre_existing = true; + if (!text_view_words.has_key (view)) { + var new_treemap = new Scratch.Plugins.PrefixTree (); + text_view_words.@set (view, new_treemap); + pre_existing = false; + } + lock (prefix_tree) { - if (text_view_words.has_key (view)) { - prefix_tree = text_view_words.@get (view); - } else { - /* Else create a new word list and parse the buffer text */ - prefix_tree = new Scratch.Plugins.PrefixTree (); - } + prefix_tree = text_view_words.@get (view); + parsing_cancelled = false; } - if (view.buffer.text.length > 0) { - parse_string (view.buffer.text); - text_view_words.@set (view, prefix_tree); + return pre_existing && get_initial_parsing_completed (); + } + + public void set_initial_parsing_completed (bool completed) requires (prefix_tree != null) { + lock (prefix_tree) { + prefix_tree.completed = completed; } } + public bool get_initial_parsing_completed () requires (prefix_tree != null) { + return prefix_tree.completed; + } + public void add_word (string word) { if (word.length < MINIMUM_WORD_LENGTH) return; diff --git a/plugins/word-completion/plugin.vala b/plugins/word-completion/plugin.vala index d227d12a6a..e1c54574c0 100644 --- a/plugins/word-completion/plugin.vala +++ b/plugins/word-completion/plugin.vala @@ -19,6 +19,8 @@ */ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { + public const int INITIAL_PARSE_DELAY_MSEC = 1000; + public Object object { owned get; construct; } private List text_view_list = new List (); @@ -96,28 +98,33 @@ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { current_view.completion.add_provider (comp_provider); current_view.completion.show_headers = true; current_view.completion.show_icons = true; - /* Wait a bit to allow text to load then run parser*/ - timeout_id = Timeout.add (1000, on_timeout_update); } catch (Error e) { warning (e.message); } - } - private bool on_timeout_update () { - try { - new Thread.try ("word-completion-thread", () => { - if (current_view != null) - parser.parse_text_view (current_view as Gtk.TextView); + // Check whether there is already a parsed tree + if (!parser.select_current_tree (current_view)) { + // If not, start initial parsing after timeout to ensure text loaded + var view_to_parse = current_view; + timeout_id = Timeout.add (INITIAL_PARSE_DELAY_MSEC, () => { + timeout_id = 0; + // Check view has not been switched + if (view_to_parse == current_view) { + try { + new Thread.try ("word-completion-thread", () => { + // The initial parse gets cancelled if view switched before complete + parser.rebuild_word_list (view_to_parse); + return null; + }); + } catch (Error e) { + warning (e.message); + } + } - return null; + return Source.REMOVE; }); - } catch (Error e) { - warning (e.message); } - - timeout_id = 0; - return false; } private bool on_key_press (Gtk.Widget view, Gdk.EventKey event) { diff --git a/plugins/word-completion/prefix-tree.vala b/plugins/word-completion/prefix-tree.vala index 916ed9612d..0eb2ee73a9 100644 --- a/plugins/word-completion/prefix-tree.vala +++ b/plugins/word-completion/prefix-tree.vala @@ -2,6 +2,7 @@ namespace Scratch.Plugins { public class PrefixTree : Object { private PrefixNode root; + public bool completed { get; set; default = false; } construct { clear ();