diff --git a/plugins/highlight-word-selection/highlight-word-selection.vala b/plugins/highlight-word-selection/highlight-word-selection.vala index c7ad0af48..58154d2cf 100644 --- a/plugins/highlight-word-selection/highlight-word-selection.vala +++ b/plugins/highlight-word-selection/highlight-word-selection.vala @@ -34,11 +34,11 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Scratc plugins = (Scratch.Services.Interface) object; plugins.hook_document.connect ((doc) => { if (current_source != null) { - current_source.selection_changed.disconnect (on_selection_changed); + current_source.selection_event.disconnect (on_selection_changed); } current_source = doc.source_view; - current_source.selection_changed.connect (on_selection_changed); + current_source.selection_event.connect (on_selection_changed); }); plugins.hook_window.connect ((w) => { @@ -46,18 +46,15 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Scratc }); } - // A deselection is now treated as a selection change - private void on_selection_changed () requires (main_window != null) { + private void on_selection_changed (ref Gtk.TextIter start, ref Gtk.TextIter end) requires (main_window != null) { if (current_search_context != null) { // Cancel existing search current_search_context.set_highlight (false); current_search_context = null; } - // Only highlight (extended) selection if non-zero length and search highlighting not happening - Gtk.TextIter start, end; - if (current_source.buffer.get_selection_bounds (out start, out end) && - !main_window.has_successful_search ()) { + if (!main_window.has_successful_search ()) { + // Perform plugin selection when there is no ongoing and successful search var original_start = start.copy (); // Ignore leading space @@ -113,22 +110,25 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Scratc // Ensure no leading or trailing space var selected_text = start.get_text (end).strip (); - - // We know the selected text is non-zero length, check not too long - if (selected_text.char_count () <= SELECTION_HIGHLIGHT_MAX_CHARS) { - current_search_context = new Gtk.SourceSearchContext ( - (Gtk.SourceBuffer)current_source.buffer, - null - ); - current_search_context.settings.search_text = selected_text; - current_search_context.set_highlight (true); + if (selected_text.char_count () > SELECTION_HIGHLIGHT_MAX_CHARS) { + //Nevertheless select as much as permitted + selected_text = selected_text.substring (0, SELECTION_HIGHLIGHT_MAX_CHARS); } + + current_search_context = new Gtk.SourceSearchContext ( + (Gtk.SourceBuffer)current_source.buffer, + null + ); + current_search_context.settings.search_text = ""; + current_search_context.set_highlight (false); + current_search_context.settings.search_text = selected_text; + current_search_context.set_highlight (true); } } public void deactivate () { if (current_source != null) { - current_source.selection_changed.disconnect (on_selection_changed); + current_source.selection_event.disconnect (on_selection_changed); } } } diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index d85e048e2..747bb9a19 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -35,7 +35,6 @@ namespace Scratch.Widgets { private uint size_allocate_timer = 0; private Gtk.TextIter last_select_start_iter; private Gtk.TextIter last_select_end_iter; - private string selected_text = ""; private GitGutterRenderer git_diff_gutter_renderer; private NavMarkGutterRenderer navmark_gutter_renderer; @@ -44,9 +43,9 @@ namespace Scratch.Widgets { private const double SCROLL_THRESHOLD = 1.0; public signal void style_changed (Gtk.SourceStyleScheme style); - // "selection_changed" signal now only emitted when the selected text changes (position ignored). - // Listened to by searchbar and highlight word selection plugin - public signal void selection_changed (Gtk.TextIter start_iter, Gtk.TextIter end_iter); + // "selection_event" signal emitted when selection changes. May be selection or deselection. + // Listened to by highlight word selection plugin + public signal void selection_event (Gtk.TextIter start_iter, Gtk.TextIter end_iter); //lang can be null, in the case of *No highlight style* aka Normal text public Gtk.SourceLanguage? language { @@ -559,20 +558,17 @@ namespace Scratch.Widgets { Gtk.TextIter start, end; var selection = buffer.get_selection_bounds (out start, out end); - var draw_spaces_state = (ScratchDrawSpacesState) Scratch.settings.get_enum ("draw-spaces"); + var draw_spaces_state = Scratch.settings.get_enum ("draw-spaces"); /* Draw spaces in selection the same way if drawn at all */ - if (selection && - draw_spaces_state in (ScratchDrawSpacesState.FOR_SELECTION | ScratchDrawSpacesState.CURRENT | ScratchDrawSpacesState.ALWAYS)) { - + if (selection && draw_spaces_state != ScratchDrawSpacesState.NEVER) { + buffer.apply_tag_by_name ("draw_spaces", start, end); + } else if (draw_spaces_state == ScratchDrawSpacesState.CURRENT) { + get_current_line (out start, out end); buffer.apply_tag_by_name ("draw_spaces", start, end); - return; } - if (draw_spaces_state == ScratchDrawSpacesState.CURRENT && - get_current_line (out start, out end)) { - - buffer.apply_tag_by_name ("draw_spaces", start, end); - } + //This is required for reliable results when this function is called from another thread (e.g. SourceFunc) + queue_draw (); } private void on_context_menu (Gtk.Menu menu) { @@ -642,23 +638,34 @@ namespace Scratch.Widgets { private void on_mark_set (Gtk.TextIter loc, Gtk.TextMark mar) { // Weed out user movement for text selection changes + // may not be new selection - also caused by highlighting for example Gtk.TextIter start, end; buffer.get_selection_bounds (out start, out end); - - if (start.equal (last_select_start_iter) && end.equal (last_select_end_iter)) { + if (last_select_start_iter.equal (start) && last_select_end_iter.equal (end)) { + // Selection unchanged - update draw spaces when required return; + } else { + last_select_start_iter.assign (start); + last_select_end_iter.assign (end); } - last_select_start_iter.assign (start); - last_select_end_iter.assign (end); - update_draw_spaces (); - if (selection_changed_timer != 0) { Source.remove (selection_changed_timer); selection_changed_timer = 0; } - selection_changed_timer = Timeout.add (THROTTLE_MS, selection_changed_event); + selection_changed_timer = Timeout.add ( + THROTTLE_MS, + () => { + selection_changed_timer = 0; + update_draw_spaces (); + + Gtk.TextIter s, e; + bool selected = buffer.get_selection_bounds (out s, out e); + selection_event (s, e); + return Source.REMOVE; + } + ); } private void on_mark_deleted (Gtk.TextMark mark) { @@ -669,20 +676,6 @@ namespace Scratch.Widgets { } } - private bool selection_changed_event () { - Gtk.TextIter start, end; - buffer.get_selection_bounds (out start, out end); - // No selection now treated as a potential selection change - var prev_selected_text = selected_text; - selected_text = buffer.get_text (start, end, true); - if (selected_text != prev_selected_text) { - selection_changed (start, end); - } - - selection_changed_timer = 0; - return false; - } - uint refresh_timeout_id = 0; public void schedule_refresh () { if (refresh_timeout_id > 0) {