Skip to content

Fix highlighting after reselecting same word #1520

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 7 additions & 16 deletions plugins/highlight-word-selection/highlight-word-selection.vala
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,10 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A
plugins = (Scratch.Services.Interface) object;
plugins.hook_document.connect ((doc) => {
if (current_source != null) {
current_source.deselected.disconnect (on_deselection);
current_source.selection_changed.disconnect (on_selection_changed);
}

current_source = doc.source_view;
current_source.deselected.connect (on_deselection);
current_source.selection_changed.connect (on_selection_changed);
});

Expand All @@ -48,9 +46,10 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A
});
}

public void on_selection_changed (ref Gtk.TextIter start, ref Gtk.TextIter end) requires (main_window != null) {
if (!main_window.has_successful_search ()) {
// Perform plugin selection when there is no ongoing and successful search
public void on_selection_changed (string selected_text, ref Gtk.TextIter start, ref Gtk.TextIter end) {
if (selected_text != "" &&
!main_window.has_successful_search ()) {
// Perform plugin selection when there is no ongoing and successful search
current_search_context = new Gtk.SourceSearchContext (
(Gtk.SourceBuffer)current_source.buffer,
null
Expand Down Expand Up @@ -112,13 +111,13 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A
);

// Ensure no leading or trailing space
var selected_text = start.get_text (end).strip ();
var stripped_selected_words = start.get_text (end).strip ();

if (selected_text.char_count () > SELECTION_HIGHLIGHT_MAX_CHARS) {
if (stripped_selected_words.char_count () > SELECTION_HIGHLIGHT_MAX_CHARS) {
return;
}

current_search_context.settings.search_text = selected_text;
current_search_context.settings.search_text = stripped_selected_words;
current_search_context.set_highlight (true);
} else if (current_search_context != null) {
// Cancel existing search
Expand All @@ -127,16 +126,8 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A
}
}

public void on_deselection () {
if (current_search_context != null) {
current_search_context.set_highlight (false);
current_search_context = null;
}
}

public void deactivate () {
if (current_source != null) {
current_source.deselected.disconnect (on_deselection);
current_source.selection_changed.disconnect (on_selection_changed);
}
}
Expand Down
71 changes: 29 additions & 42 deletions src/Widgets/SourceView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,20 @@ namespace Scratch.Widgets {
public FolderManager.ProjectFolderItem project { get; set; default = null; }

private string font;
private uint selection_changed_timer = 0;
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 string prev_selected_text = "";
private SourceGutterRenderer git_diff_gutter_renderer;

private const uint THROTTLE_MS = 400;
private const uint SIZE_ALLOCATION_THROTTLE_MS = 400;
private const uint SELECTION_CHANGE_THROTTLE_MS = 100;
private double total_delta = 0;
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);
public signal void deselected ();
public signal void selection_changed (string selected_text, 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 {
Expand Down Expand Up @@ -99,7 +98,9 @@ namespace Scratch.Widgets {
var source_buffer = new Gtk.SourceBuffer (null);
set_buffer (source_buffer);
source_buffer.highlight_syntax = true;
source_buffer.mark_set.connect (on_mark_set);
source_buffer.mark_set.connect (schedule_selection_changed_event);
// Need to handle this signal else not all deselections are detected
source_buffer.mark_deleted.connect (schedule_selection_changed_event);
highlight_current_line = true;

var draw_spaces_tag = new Gtk.SourceTag ("draw_spaces");
Expand Down Expand Up @@ -189,7 +190,7 @@ namespace Scratch.Widgets {
size_allocate.connect ((allocation) => {
// Throttle for performance
if (size_allocate_timer == 0) {
size_allocate_timer = Timeout.add (THROTTLE_MS, () => {
size_allocate_timer = Timeout.add (SIZE_ALLOCATION_THROTTLE_MS, () => {
size_allocate_timer = 0;
bottom_margin = calculate_bottom_margin (allocation.height);
return GLib.Source.REMOVE;
Expand Down Expand Up @@ -539,14 +540,12 @@ namespace Scratch.Widgets {
/* Draw spaces in selection the same way if drawn at all */
if (selection &&
draw_spaces_state in (ScratchDrawSpacesState.FOR_SELECTION | ScratchDrawSpacesState.CURRENT | ScratchDrawSpacesState.ALWAYS)) {

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);
}
}
Expand Down Expand Up @@ -597,49 +596,37 @@ namespace Scratch.Widgets {
return (int) (height_in_px - (LINES_TO_KEEP * px_per_line));
}

void on_mark_set (Gtk.TextIter loc, Gtk.TextMark mar) {
// Weed out user movement for text selection changes
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)) {
return;
}

last_select_start_iter.assign (start);
last_select_end_iter.assign (end);
private bool continue_selection_timer = false;
private uint selection_changed_timer = 0;
private void schedule_selection_changed_event () {
// Update spaces immediately to maintain previous behaviour
update_draw_spaces ();

if (selection_changed_timer != 0) {
Source.remove (selection_changed_timer);
selection_changed_timer = 0;
continue_selection_timer = true;
return;
}

// Fire deselected immediately
if (start.equal (end)) {
deselected ();
// Don't fire signal till we think select movement is done
} else {
selection_changed_timer = Timeout.add (THROTTLE_MS, selection_changed_event);
}
selection_changed_timer = Timeout.add (SELECTION_CHANGE_THROTTLE_MS, () => {
if (continue_selection_timer) {
continue_selection_timer = false;
return Source.CONTINUE;
}

}
selection_changed_timer = 0;
Gtk.TextIter start, end;
var selected_text = "";
if (buffer.get_selection_bounds (out start, out end)) {
selected_text = buffer.get_text (start, end, true);
}

bool selection_changed_event () {
Gtk.TextIter start, end;
bool selected = buffer.get_selection_bounds (out start, out end);
if (selected) {
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 (selected_text, start, end);
}
} else {
deselected ();
}

selection_changed_timer = 0;
return false;
prev_selected_text = selected_text;
return Source.REMOVE;
});
}

uint refresh_diff_timeout_id = 0;
Expand Down