From 4d3ad4bdb43042f2b9e68ace8b2489287b36ab83 Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Sat, 13 Nov 2021 09:19:17 -0300 Subject: [PATCH 1/9] Rewrite word completion to play nice with other completion providers. --- .../word-completion/completion-provider.vala | 55 +++------ plugins/word-completion/engine.vala | 54 +++----- plugins/word-completion/meson.build | 1 + plugins/word-completion/plugin.vala | 54 +++----- plugins/word-completion/prefix-tree.vala | 116 ++++++++++++++++++ 5 files changed, 175 insertions(+), 105 deletions(-) create mode 100644 plugins/word-completion/prefix-tree.vala diff --git a/plugins/word-completion/completion-provider.vala b/plugins/word-completion/completion-provider.vala index 7a9071a793..8fcf79815e 100644 --- a/plugins/word-completion/completion-provider.vala +++ b/plugins/word-completion/completion-provider.vala @@ -28,7 +28,6 @@ public class Scratch.Plugins.CompletionProvider : Gtk.SourceCompletionProvider, private Gtk.TextView? view; private Gtk.TextBuffer? buffer; private Euclide.Completion.Parser parser; - private bool proposals_found = false; private Gtk.TextMark completion_end_mark; private Gtk.TextMark completion_start_mark; @@ -53,40 +52,36 @@ public class Scratch.Plugins.CompletionProvider : Gtk.SourceCompletionProvider, } public bool match (Gtk.SourceCompletionContext context) { - return true; + Gtk.TextIter start, end; + buffer.get_iter_at_offset (out end, buffer.cursor_position); + start = end.copy(); + start.backward_word_start (); + string text = buffer.get_text (start, end, true); + + return parser.match (text); } public void populate (Gtk.SourceCompletionContext context) { /*Store current insertion point for use in activate_proposal */ GLib.List? file_props; bool no_minimum = (context.get_activation () == Gtk.SourceCompletionActivation.USER_REQUESTED); - proposals_found = get_proposals (out file_props, no_minimum); - - if (proposals_found) - context.add_proposals (this, file_props, true); - - /* Signal to plugin whether proposals are available - * If none, the completion will be active but not visible */ - can_propose (proposals_found); + get_proposals (out file_props, no_minimum); + context.add_proposals (this, file_props, true); } public bool activate_proposal (Gtk.SourceCompletionProposal proposal, Gtk.TextIter iter) { - if (proposals_found) { - /* Count backward from completion_mark instead of iter - * (avoids wrong insertion if the user is typing fast) */ - Gtk.TextIter start; - Gtk.TextIter end; - Gtk.TextMark mark; + Gtk.TextIter start; + Gtk.TextIter end; + Gtk.TextMark mark; - mark = buffer.get_mark (COMPLETION_END_MARK_NAME); - buffer.get_iter_at_mark (out end, mark); + mark = buffer.get_mark (COMPLETION_END_MARK_NAME); + buffer.get_iter_at_mark (out end, mark); - mark = buffer.get_mark (COMPLETION_START_MARK_NAME); - buffer.get_iter_at_mark (out start, mark); + mark = buffer.get_mark (COMPLETION_START_MARK_NAME); + buffer.get_iter_at_mark (out start, mark); - buffer.@delete (ref start, ref end); - buffer.insert (ref start, proposal.get_text (), proposal.get_text ().length); - } + buffer.@delete (ref start, ref end); + buffer.insert (ref start, proposal.get_text (), proposal.get_text ().length); return true; } @@ -95,11 +90,6 @@ public class Scratch.Plugins.CompletionProvider : Gtk.SourceCompletionProvider, Gtk.SourceCompletionActivation.USER_REQUESTED; } - public unowned Gtk.Widget? get_info_widget (Gtk.SourceCompletionProposal proposal) { - /* As no additional info is provided no widget is needed */ - return null; - } - public int get_interactive_delay () { return 0; } @@ -116,11 +106,6 @@ public class Scratch.Plugins.CompletionProvider : Gtk.SourceCompletionProvider, return true; } - public void update_info (Gtk.SourceCompletionProposal proposal, Gtk.SourceCompletionInfo info) { - /* No additional info provided on proposals */ - return; - } - private bool get_proposals (out GLib.List? props, bool no_minimum) { string to_find = ""; Gtk.TextIter iter; @@ -158,13 +143,13 @@ public class Scratch.Plugins.CompletionProvider : Gtk.SourceCompletionProvider, /* There is no minimum length of word to find if the user requested a completion */ if (no_minimum || to_find.length >= Euclide.Completion.Parser.MINIMUM_WORD_LENGTH) { /* Get proposals, if any */ - Gee.TreeSet prop_word_list; + List prop_word_list; if (parser.get_for_word (to_find, out prop_word_list)) { foreach (var word in prop_word_list) { var item = new Gtk.SourceCompletionItem (); item.label = word; item.text = word; - props.prepend (item); + props.append (item); } return true; diff --git a/plugins/word-completion/engine.vala b/plugins/word-completion/engine.vala index 55273ffa29..6fa58a1fc2 100644 --- a/plugins/word-completion/engine.vala +++ b/plugins/word-completion/engine.vala @@ -22,74 +22,58 @@ 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; + public const string DELIMITERS = " .,;:?{}[]()0123456789+-=&|-<>*\\/\n\t\'\""; public bool is_delimiter (unichar c) { return DELIMITERS.index_of_char (c) >= 0; } - public Gee.HashMap> text_view_words; + public Gee.HashMap text_view_words; public bool parsing_cancelled = false; - private Gee.ArrayList words; - private string last_word = ""; - public Parser () { - text_view_words = new Gee.HashMap> (); + text_view_words = new Gee.HashMap (); + prefix_tree = new Scratch.Plugins.PrefixTree (); } - public void add_last_word () { - add_word (last_word); + public bool match (string to_find) { + return prefix_tree.find_prefix (to_find); } - public bool get_for_word (string to_find, out Gee.TreeSet list) { - uint length = to_find.length; - list = new Gee.TreeSet (); - last_word = to_find; - if (words != null) { - lock (words) { - foreach (var word in words) { - if (word.length > length && word.slice (0, length) == to_find) { - list.add (word); - } - } - } - } - - return !list.is_empty; + public bool get_for_word (string to_find, out List list) { + list = prefix_tree.get_all_matches (to_find); + return list.length () > 0; } public void rebuild_word_list (Gtk.TextView view) { - lock (words) { - words.clear (); - } + prefix_tree.clear (); parse_text_view (view); } public void parse_text_view (Gtk.TextView view) { /* If this view has already been parsed, restore the word list */ - lock (words) { + lock (prefix_tree) { if (text_view_words.has_key (view)) { - words = text_view_words.@get (view); + prefix_tree = text_view_words.@get (view); } else { - /* Else create a new word list and parse the buffer text */ - words = new Gee.ArrayList (); + /* Else create a new word list and parse the buffer text */ + prefix_tree = new Scratch.Plugins.PrefixTree (); } } if (view.buffer.text.length > 0) { parse_string (view.buffer.text); - text_view_words.@set (view, words); + text_view_words.@set (view, prefix_tree); } } - private void add_word (string word) { + public void add_word (string word) { if (word.length < MINIMUM_WORD_LENGTH) return; - if (!(word in words)) { - lock (words) { - words.add (word); - } + lock (prefix_tree) { + prefix_tree.insert (word); } } diff --git a/plugins/word-completion/meson.build b/plugins/word-completion/meson.build index 6aa1ed0225..2887aef312 100644 --- a/plugins/word-completion/meson.build +++ b/plugins/word-completion/meson.build @@ -1,6 +1,7 @@ module_name = 'word-completion' module_files = [ + 'prefix-tree.vala', 'completion-provider.vala', 'engine.vala', 'plugin.vala' diff --git a/plugins/word-completion/plugin.vala b/plugins/word-completion/plugin.vala index 0debc5c6b1..c6f34b66bd 100644 --- a/plugins/word-completion/plugin.vala +++ b/plugins/word-completion/plugin.vala @@ -41,7 +41,6 @@ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { private const uint USER_REQUESTED_KEY = Gdk.Key.backslash; private uint timeout_id = 0; - private bool completion_visible = false; public void activate () { plugins = (Scratch.Services.Interface) object; @@ -77,8 +76,6 @@ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { current_document = doc; current_view = doc.source_view; current_view.key_press_event.connect (on_key_press); - current_view.completion.show.connect (on_completion_shown); - current_view.completion.hide.connect (on_completion_hidden); if (text_view_list.find (current_view) == null) text_view_list.append (current_view); @@ -86,11 +83,10 @@ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { var comp_provider = new Scratch.Plugins.CompletionProvider (this); comp_provider.priority = 1; comp_provider.name = provider_name_from_document (doc); - comp_provider.can_propose.connect (on_propose); try { current_view.completion.add_provider (comp_provider); - current_view.completion.show_headers = false; + 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); @@ -119,64 +115,54 @@ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { private bool on_key_press (Gtk.Widget view, Gdk.EventKey event) { uint kv = event.keyval; unichar uc = (unichar)(Gdk.keyval_to_unicode (kv)); + print ("key key %s\n", uc.to_string ()); + + print ("is print %s is delimiter %s\n", + uc.isprint ()?"Y":"N", + parser.is_delimiter (uc)?"Y":"N"); /* Pass through any modified keypress except Shift or Capslock */ Gdk.ModifierType mods = event.state & Gdk.ModifierType.MODIFIER_MASK & ~Gdk.ModifierType.SHIFT_MASK & ~Gdk.ModifierType.LOCK_MASK; if (mods > 0 ) { + print ("enter mod\n"); /* Default key for USER_REQUESTED completion is ControlSpace * but this is trapped elsewhere. Control + USER_REQUESTED_KEY acts as an * alternative and also purges spelling mistakes and unused words from the list. * If used when a word or part of a word is selected, the selection will be * used as the word to find. */ if ((mods & Gdk.ModifierType.CONTROL_MASK) > 0 && (kv == USER_REQUESTED_KEY)) { + print ("REBUILD\n"); parser.rebuild_word_list (current_view); current_view.show_completion (); return true; - } else - return false; + } } - bool activating = kv in ACTIVATE_KEYS; + if (kv in ACTIVATE_KEYS || + (parser.is_delimiter (uc) && uc.isprint ()) ) { + var buffer = current_view.buffer; + var mark = buffer.get_insert (); + Gtk.TextIter cursor_iter; + buffer.get_iter_at_mark (out cursor_iter, mark); - if (completion_visible && activating) { - current_view.completion.activate_proposal (); - parser.add_last_word (); - return true; - } + var word_start = cursor_iter; + word_start.backward_word_start (); - if (activating || (uc.isprint () && parser.is_delimiter (uc) )) { - parser.add_last_word (); - current_view.completion.hide (); + string word = buffer.get_text (word_start, cursor_iter, false); + parser.add_word (word); } return false; } - private void on_completion_shown () { - completion_visible = true; - } - - private void on_completion_hidden () { - completion_visible = false; - } - - private void on_propose (bool can_propose) { - if (!can_propose) - current_view.completion.hide (); - - completion_visible = can_propose; - } - private string provider_name_from_document (Scratch.Services.Document doc) { return _("%s - Word Completion").printf (doc.get_basename ()); } private void cleanup (Gtk.SourceView view) { current_view.key_press_event.disconnect (on_key_press); - current_view.completion.show.disconnect (on_completion_shown); - current_view.completion.hide.disconnect (on_completion_hidden); current_view.completion.get_providers ().foreach ((p) => { try { @@ -189,8 +175,6 @@ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { warning (e.message); } }); - - completion_visible = false; } } diff --git a/plugins/word-completion/prefix-tree.vala b/plugins/word-completion/prefix-tree.vala new file mode 100644 index 0000000000..84e972d7e5 --- /dev/null +++ b/plugins/word-completion/prefix-tree.vala @@ -0,0 +1,116 @@ + +namespace Scratch.Plugins { + private class PrefixNode : Object { + public GLib.List children; + public unichar value { get; set; } + + construct { + children = new List (); + } + } + + public class PrefixTree : Object { + private PrefixNode root; + + construct { + clear (); + } + + public void clear () { + root = new PrefixNode () { + value = '\0' + }; + } + + public void insert (string word) { + if (word.length == 0) { + return; + } + + this.insert_at (word, this.root); + } + + private void insert_at (string word, PrefixNode node, int i = 0) { + unichar curr; + + word.get_next_char (ref i, out curr); + + foreach (var child in node.children) { + if (child.value == curr) { + if (curr != '\0') { + insert_at (word, child, i); + } + return; + } + } + + if (!curr.isprint () && curr != '\0') { + return; + } + + var new_child = new PrefixNode () { + value = curr + }; + node.children.insert_sorted (new_child, (c1, c2) => { + if (c1.value > c2.value) { + return 1; + } else if (c1.value == c2.value) { + return 0; + } + return -1; + }); + if (curr != '\0') { + insert_at (word, new_child, i); + } + } + + public bool find_prefix (string prefix) { + return find_prefix_at (prefix, root) != null? true : false; + } + + private PrefixNode? find_prefix_at (string prefix, PrefixNode node, int i = 0) { + unichar curr; + + prefix.get_next_char (ref i, out curr); + if (curr == '\0') { + return node; + } + + foreach (var child in node.children) { + if (child.value == curr) { + return find_prefix_at (prefix, child, i); + } + } + + return null; + } + + public List get_all_matches (string prefix) { + var list = new List (); + var node = find_prefix_at (prefix, root, 0); + if (node != null) { + var sb = new StringBuilder (prefix); + get_all_matches_rec (node, ref sb, ref list); + } + + return list; + } + + private void get_all_matches_rec ( + PrefixNode node, + ref StringBuilder sbuilder, + ref List matches) { + + foreach (var child in node.children) { + if (child.value == '\0') { + matches.append (sbuilder.str); + } else { + sbuilder.append_unichar (child.value); + get_all_matches_rec (child, ref sbuilder, ref matches); + var length = child.value.to_string ().length; + sbuilder.erase (sbuilder.len - length, -1); + } + } + } + } +} \ No newline at end of file From 04758c84bbc2f9611c6adf795793b1c22013c81a Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Sat, 13 Nov 2021 09:34:41 -0300 Subject: [PATCH 2/9] lint --- plugins/word-completion/completion-provider.vala | 2 +- plugins/word-completion/plugin.vala | 9 +-------- plugins/word-completion/prefix-tree.vala | 16 ++++++++-------- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/plugins/word-completion/completion-provider.vala b/plugins/word-completion/completion-provider.vala index 8fcf79815e..af3e4cba70 100644 --- a/plugins/word-completion/completion-provider.vala +++ b/plugins/word-completion/completion-provider.vala @@ -54,7 +54,7 @@ public class Scratch.Plugins.CompletionProvider : Gtk.SourceCompletionProvider, public bool match (Gtk.SourceCompletionContext context) { Gtk.TextIter start, end; buffer.get_iter_at_offset (out end, buffer.cursor_position); - start = end.copy(); + start = end.copy (); start.backward_word_start (); string text = buffer.get_text (start, end, true); diff --git a/plugins/word-completion/plugin.vala b/plugins/word-completion/plugin.vala index c6f34b66bd..29fe371915 100644 --- a/plugins/word-completion/plugin.vala +++ b/plugins/word-completion/plugin.vala @@ -115,32 +115,25 @@ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { private bool on_key_press (Gtk.Widget view, Gdk.EventKey event) { uint kv = event.keyval; unichar uc = (unichar)(Gdk.keyval_to_unicode (kv)); - print ("key key %s\n", uc.to_string ()); - - print ("is print %s is delimiter %s\n", - uc.isprint ()?"Y":"N", - parser.is_delimiter (uc)?"Y":"N"); /* Pass through any modified keypress except Shift or Capslock */ Gdk.ModifierType mods = event.state & Gdk.ModifierType.MODIFIER_MASK & ~Gdk.ModifierType.SHIFT_MASK & ~Gdk.ModifierType.LOCK_MASK; if (mods > 0 ) { - print ("enter mod\n"); /* Default key for USER_REQUESTED completion is ControlSpace * but this is trapped elsewhere. Control + USER_REQUESTED_KEY acts as an * alternative and also purges spelling mistakes and unused words from the list. * If used when a word or part of a word is selected, the selection will be * used as the word to find. */ if ((mods & Gdk.ModifierType.CONTROL_MASK) > 0 && (kv == USER_REQUESTED_KEY)) { - print ("REBUILD\n"); parser.rebuild_word_list (current_view); current_view.show_completion (); return true; } } - if (kv in ACTIVATE_KEYS || + if (kv in ACTIVATE_KEYS || (parser.is_delimiter (uc) && uc.isprint ()) ) { var buffer = current_view.buffer; var mark = buffer.get_insert (); diff --git a/plugins/word-completion/prefix-tree.vala b/plugins/word-completion/prefix-tree.vala index 84e972d7e5..341ea24602 100644 --- a/plugins/word-completion/prefix-tree.vala +++ b/plugins/word-completion/prefix-tree.vala @@ -3,7 +3,7 @@ namespace Scratch.Plugins { private class PrefixNode : Object { public GLib.List children; public unichar value { get; set; } - + construct { children = new List (); } @@ -26,15 +26,15 @@ namespace Scratch.Plugins { if (word.length == 0) { return; } - - this.insert_at (word, this.root); + + this.insert_at (word, this.root); } private void insert_at (string word, PrefixNode node, int i = 0) { unichar curr; word.get_next_char (ref i, out curr); - + foreach (var child in node.children) { if (child.value == curr) { if (curr != '\0') { @@ -92,15 +92,15 @@ namespace Scratch.Plugins { var sb = new StringBuilder (prefix); get_all_matches_rec (node, ref sb, ref list); } - + return list; } - private void get_all_matches_rec ( - PrefixNode node, + private void get_all_matches_rec ( + PrefixNode node, ref StringBuilder sbuilder, ref List matches) { - + foreach (var child in node.children) { if (child.value == '\0') { matches.append (sbuilder.str); From 52d37a0d9a9c8d6e5467c42a5e6afd6a127f3de0 Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Sat, 13 Nov 2021 09:38:19 -0300 Subject: [PATCH 3/9] lint 2 --- plugins/word-completion/prefix-tree.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/word-completion/prefix-tree.vala b/plugins/word-completion/prefix-tree.vala index 341ea24602..1b437efc4f 100644 --- a/plugins/word-completion/prefix-tree.vala +++ b/plugins/word-completion/prefix-tree.vala @@ -113,4 +113,4 @@ namespace Scratch.Plugins { } } } -} \ No newline at end of file +} From 900d2d3026ea26f3b77650fcaef78914fe225277 Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Wed, 17 Nov 2021 22:22:42 -0300 Subject: [PATCH 4/9] Fix problem with extra space in words. --- .../word-completion/completion-provider.vala | 31 ++++++------------- plugins/word-completion/engine.vala | 2 +- plugins/word-completion/plugin.vala | 16 ++++++++-- plugins/word-completion/prefix-tree.vala | 2 +- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/plugins/word-completion/completion-provider.vala b/plugins/word-completion/completion-provider.vala index af3e4cba70..65bcb4649c 100644 --- a/plugins/word-completion/completion-provider.vala +++ b/plugins/word-completion/completion-provider.vala @@ -108,7 +108,6 @@ public class Scratch.Plugins.CompletionProvider : Gtk.SourceCompletionProvider, private bool get_proposals (out GLib.List? props, bool no_minimum) { string to_find = ""; - Gtk.TextIter iter; Gtk.TextBuffer temp_buffer = buffer; props = null; @@ -118,28 +117,18 @@ public class Scratch.Plugins.CompletionProvider : Gtk.SourceCompletionProvider, to_find = temp_buffer.get_text (start, end, true); if (to_find.length == 0) { - /* Find start of current word */ - temp_buffer.get_iter_at_offset (out iter, buffer.cursor_position); - /* Mark current insertion point as end point for use in activate proposal */ - buffer.move_mark_by_name (COMPLETION_END_MARK_NAME, iter); - /* TODO - Use iter.backward_word_start? */ - iter.backward_find_char ((c) => { - bool valid = parser.is_delimiter (c); - if (!valid) - to_find += c.to_string (); - - return valid; - }, null); - iter.forward_cursor_position (); - /* Mark start of delimited text as start point for use in activate proposal */ - buffer.move_mark_by_name (COMPLETION_START_MARK_NAME, iter); - to_find = to_find.reverse (); - } else { - /* mark start and end of the selection */ - buffer.move_mark_by_name (COMPLETION_END_MARK_NAME, end); - buffer.move_mark_by_name (COMPLETION_START_MARK_NAME, start); + temp_buffer.get_iter_at_offset (out end, buffer.cursor_position); + + start = end; + start.backward_word_start (); + + to_find = buffer.get_text (start, end, false); } + buffer.move_mark_by_name (COMPLETION_END_MARK_NAME, end); + buffer.move_mark_by_name (COMPLETION_START_MARK_NAME, start); + + /* There is no minimum length of word to find if the user requested a completion */ if (no_minimum || to_find.length >= Euclide.Completion.Parser.MINIMUM_WORD_LENGTH) { /* Get proposals, if any */ diff --git a/plugins/word-completion/engine.vala b/plugins/word-completion/engine.vala index 6fa58a1fc2..5632b85991 100644 --- a/plugins/word-completion/engine.vala +++ b/plugins/word-completion/engine.vala @@ -24,7 +24,7 @@ public class Euclide.Completion.Parser : GLib.Object { private Scratch.Plugins.PrefixTree prefix_tree; - public const string DELIMITERS = " .,;:?{}[]()0123456789+-=&|-<>*\\/\n\t\'\""; + public const string DELIMITERS = " .,;:?{}[]()0123456789+-=&|-<>*\\/\r\n\t\'\""; public bool is_delimiter (unichar c) { return DELIMITERS.index_of_char (c) >= 0; } diff --git a/plugins/word-completion/plugin.vala b/plugins/word-completion/plugin.vala index 29fe371915..51a8dd3952 100644 --- a/plugins/word-completion/plugin.vala +++ b/plugins/word-completion/plugin.vala @@ -28,6 +28,7 @@ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { private MainWindow main_window; private Scratch.Services.Interface plugins; + private bool completion_in_progress = false; private const uint [] ACTIVATE_KEYS = { Gdk.Key.Return, @@ -76,6 +77,13 @@ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { current_document = doc; current_view = doc.source_view; current_view.key_press_event.connect (on_key_press); + current_view.completion.show.connect (() => { + completion_in_progress = true; + }); + current_view.completion.hide.connect (() => { + completion_in_progress = false; + }); + if (text_view_list.find (current_view) == null) text_view_list.append (current_view); @@ -133,8 +141,12 @@ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { } } - if (kv in ACTIVATE_KEYS || - (parser.is_delimiter (uc) && uc.isprint ()) ) { + print ("DELIM %s PRINT %s\n", + parser.is_delimiter (uc)?"Y":"N", + uc.isprint ()?"Y":"N"); + if (!completion_in_progress && parser.is_delimiter (uc) && + (uc.isprint () || uc.isspace ())) { + var buffer = current_view.buffer; var mark = buffer.get_insert (); Gtk.TextIter cursor_iter; diff --git a/plugins/word-completion/prefix-tree.vala b/plugins/word-completion/prefix-tree.vala index 1b437efc4f..292e3924ec 100644 --- a/plugins/word-completion/prefix-tree.vala +++ b/plugins/word-completion/prefix-tree.vala @@ -44,7 +44,7 @@ namespace Scratch.Plugins { } } - if (!curr.isprint () && curr != '\0') { + if (!curr.isgraph () && curr != '\0') { return; } From d15acae46ee5c0e28742325704ba9d6f2549a3c5 Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Wed, 17 Nov 2021 22:38:10 -0300 Subject: [PATCH 5/9] remove print --- plugins/word-completion/plugin.vala | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/word-completion/plugin.vala b/plugins/word-completion/plugin.vala index 51a8dd3952..4a32dd093c 100644 --- a/plugins/word-completion/plugin.vala +++ b/plugins/word-completion/plugin.vala @@ -141,9 +141,6 @@ public class Scratch.Plugins.Completion : Peas.ExtensionBase, Peas.Activatable { } } - print ("DELIM %s PRINT %s\n", - parser.is_delimiter (uc)?"Y":"N", - uc.isprint ()?"Y":"N"); if (!completion_in_progress && parser.is_delimiter (uc) && (uc.isprint () || uc.isspace ())) { From 023adb00a0780709e800ff8f759b109840d7c74b Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Sat, 20 Nov 2021 10:54:32 -0300 Subject: [PATCH 6/9] Avoid incluing delimiters in the prefix tree. --- plugins/word-completion/engine.vala | 4 ++-- plugins/word-completion/prefix-tree.vala | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/plugins/word-completion/engine.vala b/plugins/word-completion/engine.vala index 5632b85991..5159d7fc7a 100644 --- a/plugins/word-completion/engine.vala +++ b/plugins/word-completion/engine.vala @@ -24,8 +24,8 @@ public class Euclide.Completion.Parser : GLib.Object { private Scratch.Plugins.PrefixTree prefix_tree; - public const string DELIMITERS = " .,;:?{}[]()0123456789+-=&|-<>*\\/\r\n\t\'\""; - public bool is_delimiter (unichar c) { + public const string DELIMITERS = " .,;:?{}[]()0123456789+-=&|-<>*\\/\r\n\t\'\"`"; + public static bool is_delimiter (unichar c) { return DELIMITERS.index_of_char (c) >= 0; } diff --git a/plugins/word-completion/prefix-tree.vala b/plugins/word-completion/prefix-tree.vala index 292e3924ec..ea5ca2d414 100644 --- a/plugins/word-completion/prefix-tree.vala +++ b/plugins/word-completion/prefix-tree.vala @@ -31,9 +31,12 @@ namespace Scratch.Plugins { } private void insert_at (string word, PrefixNode node, int i = 0) { - unichar curr; + unichar curr = '\0'; - word.get_next_char (ref i, out curr); + bool has_next_character = false; + do { + has_next_character = word.get_next_char (ref i, out curr); + } while (has_next_character && Euclide.Completion.Parser.is_delimiter (curr)); foreach (var child in node.children) { if (child.value == curr) { @@ -44,10 +47,6 @@ namespace Scratch.Plugins { } } - if (!curr.isgraph () && curr != '\0') { - return; - } - var new_child = new PrefixNode () { value = curr }; From af281043ff7667901916ee3e0a03f6987754266c Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Sat, 20 Nov 2021 11:08:27 -0300 Subject: [PATCH 7/9] Use is_empty --- plugins/word-completion/engine.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/word-completion/engine.vala b/plugins/word-completion/engine.vala index 5159d7fc7a..99d4120044 100644 --- a/plugins/word-completion/engine.vala +++ b/plugins/word-completion/engine.vala @@ -43,7 +43,7 @@ public class Euclide.Completion.Parser : GLib.Object { public bool get_for_word (string to_find, out List list) { list = prefix_tree.get_all_matches (to_find); - return list.length () > 0; + return list.is_empty (); } public void rebuild_word_list (Gtk.TextView view) { From 669a543bfd5473b6f47f2b37941f1ae136423a39 Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Sat, 20 Nov 2021 21:06:51 -0300 Subject: [PATCH 8/9] Fix is_empty --- plugins/word-completion/engine.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/word-completion/engine.vala b/plugins/word-completion/engine.vala index 99d4120044..e63960b46d 100644 --- a/plugins/word-completion/engine.vala +++ b/plugins/word-completion/engine.vala @@ -43,7 +43,7 @@ public class Euclide.Completion.Parser : GLib.Object { public bool get_for_word (string to_find, out List list) { list = prefix_tree.get_all_matches (to_find); - return list.is_empty (); + return list.first () != null; } public void rebuild_word_list (Gtk.TextView view) { From fe72183606cb21e8d87b6000f6495eb77529db4f Mon Sep 17 00:00:00 2001 From: Igor Montagner Date: Mon, 13 Dec 2021 18:50:36 -0300 Subject: [PATCH 9/9] Remove hyphen and underscore from delimiters --- plugins/word-completion/engine.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/word-completion/engine.vala b/plugins/word-completion/engine.vala index e63960b46d..9d73598dc3 100644 --- a/plugins/word-completion/engine.vala +++ b/plugins/word-completion/engine.vala @@ -24,7 +24,7 @@ public class Euclide.Completion.Parser : GLib.Object { private Scratch.Plugins.PrefixTree prefix_tree; - public const string DELIMITERS = " .,;:?{}[]()0123456789+-=&|-<>*\\/\r\n\t\'\"`"; + public const string DELIMITERS = " .,;:?{}[]()0123456789+=&|<>*\\/\r\n\t\'\"`"; public static bool is_delimiter (unichar c) { return DELIMITERS.index_of_char (c) >= 0; }