From f10f4fcc7262599175a037c1a7398fbf796f20bd Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Sun, 15 Oct 2023 01:35:43 -0500 Subject: [PATCH] More work on search and replace --- plugins/colorize/plugin.py | 2 +- plugins/search_replace/plugin.py | 107 ++++++++++++++------ plugins/search_replace/search_replace.glade | 5 +- 3 files changed, 80 insertions(+), 34 deletions(-) diff --git a/plugins/colorize/plugin.py b/plugins/colorize/plugin.py index d1f77a6..652100b 100644 --- a/plugins/colorize/plugin.py +++ b/plugins/colorize/plugin.py @@ -115,7 +115,7 @@ class Plugin(PluginBase): if not start_itr or not query: return None, None results = [] - flags = Gtk.TextSearchFlags.VISIBLE_ONLY & Gtk.TextSearchFlags.TEXT_ONLY + flags = Gtk.TextSearchFlags.VISIBLE_ONLY | Gtk.TextSearchFlags.TEXT_ONLY while True: result = start_itr.forward_search(query, flags, end_itr) if not result: break diff --git a/plugins/search_replace/plugin.py b/plugins/search_replace/plugin.py index 84c5562..2ab6971 100644 --- a/plugins/search_replace/plugin.py +++ b/plugins/search_replace/plugin.py @@ -1,5 +1,6 @@ # Python imports import os +import re # Lib imports import gi @@ -21,17 +22,22 @@ class Plugin(PluginBase): self.path = os.path.dirname(os.path.realpath(__file__)) self._GLADE_FILE = f"{self.path}/search_replace.glade" - self._search_replace_dialog = None - self._find_entry = None - self._replace_entry = None - self._active_src_view = None + self._search_replace_dialog = None + self._find_entry = None + self._replace_entry = None + self._active_src_view = None + self._buffer = None + self._tag_table = None - self.use_regex = False - self.use_case_sensitive = False - self.use_only_in_selection = False - self.use_whole_word_search = False - self.highlight_color = "#FBF719" - self.text_color = "#000000" + self.use_regex = False + self.use_case_sensitive = False + self.search_only_in_selection = False + self.use_whole_word_search = False + + self.search_tag = "search_tag" + self.highlight_color = "#FBF719" + self.text_color = "#000000" + self.alpha_num_under = re.compile(r"[a-zA-Z0-9_]") def run(self): @@ -59,6 +65,8 @@ class Plugin(PluginBase): def _set_active_src_view(self, source_view): self._active_src_view = source_view + self._buffer = self._active_src_view.get_buffer() + self._tag_table = self._buffer.get_tag_table() self.search_for_string(self._find_entry) def _show_search_replace(self, widget = None, eve = None): @@ -86,18 +94,22 @@ class Plugin(PluginBase): def tggle_regex(self, widget): self.use_regex = not widget.get_active() self._set_find_options_lbl() + self.search_for_string(self._find_entry) def tggle_case_sensitive(self, widget): - self.use_case_sensitive = not widget.get_active() + self.use_case_sensitive = widget.get_active() self._set_find_options_lbl() + self.search_for_string(self._find_entry) def tggle_selection_only_scan(self, widget): - self.use_only_in_selection = not widget.get_active() + self.search_only_in_selection = widget.get_active() self._set_find_options_lbl() + self.search_for_string(self._find_entry) def tggle_whole_word_search(self, widget): - self.use_whole_word_search = not widget.get_active() + self.use_whole_word_search = widget.get_active() self._set_find_options_lbl() + self.search_for_string(self._find_entry) def _set_find_options_lbl(self): # Finding with Options: Case Insensitive @@ -106,8 +118,8 @@ class Plugin(PluginBase): # f"Finding with Options: {regex}, {case}, {selection}, {word}" ... - def _update_status_lbl(self, total_count: int = None, query: str = None): - if not total_count or not query: return + def _update_status_lbl(self, total_count: int = 0, query: str = None): + if not query: return count = total_count if total_count > 0 else "No" plural = "s" if total_count > 1 else "" @@ -115,16 +127,13 @@ class Plugin(PluginBase): def get_search_tag(self, buffer): tag_table = buffer.get_tag_table() - search_tag = tag_table.lookup("search_tag") + search_tag = tag_table.lookup(self.search_tag) if not search_tag: - search_tag = buffer.create_tag("search_tag", background = self.highlight_color, foreground = self.text_color) + search_tag = buffer.create_tag(self.search_tag, background = self.highlight_color, foreground = self.text_color) - buffer.remove_tag_by_name("search_tag", buffer.get_start_iter(), buffer.get_end_iter()) + buffer.remove_tag_by_name(self.search_tag, buffer.get_start_iter(), buffer.get_end_iter()) return search_tag - def find_next_entry(self, widget, eve, use_data = None): - ... - def search_for_string(self, widget): query = widget.get_text() buffer = self._active_src_view.get_buffer() @@ -139,36 +148,70 @@ class Plugin(PluginBase): end_itr = buffer.get_end_iter() results, total_count = self.search(start_itr, query) + self._update_status_lbl(total_count, query) for start, end in results: buffer.apply_tag(search_tag, start, end) - self._update_status_lbl(total_count, query) - def search(self, start_itr = None, query = None): + def search(self, start_itr = None, query = None, limit = None): if not start_itr or not query: return None, None + flags = Gtk.TextSearchFlags.VISIBLE_ONLY | Gtk.TextSearchFlags.TEXT_ONLY if not self.use_case_sensitive: - _flags = Gtk.TextSearchFlags.VISIBLE_ONLY & Gtk.TextSearchFlags.TEXT_ONLY & Gtk.TextSearchFlags.CASE_INSENSITIVE - else: - _flags = Gtk.TextSearchFlags.VISIBLE_ONLY & Gtk.TextSearchFlags.TEXT_ONLY + flags = flags | Gtk.TextSearchFlags.CASE_INSENSITIVE - results = [] + if self.search_only_in_selection and self._buffer.get_has_selection(): + start_itr, limit = self._buffer.get_selection_bounds() + + _results = [] while True: - result = start_itr.forward_search(query, flags = _flags, limit = None) + result = start_itr.forward_search(query, flags, limit) if not result: break - results.append(result) + _results.append(result) start_itr = result[1] + results = self.apply_filters(_results, query) return results, len(results) + def apply_filters(self, _results, query): + results = [] + for start, end in _results: + text = self._buffer.get_slice(start, end, include_hidden_chars = False) + if self.use_whole_word_search: + end.forward_char() + start.backward_char() + match = self.alpha_num_under.match( start.get_char() ) + if not match is None: + continue + match = self.alpha_num_under.match( end.get_char() ) + if not match is None: + continue + end.backward_char() + start.forward_char() + results.append([start, end]) + return results + + def find_next(self, widget, eve = None, use_data = None): + mark = self._buffer.get_insert() + iter = self._buffer.get_iter_at_mark(mark) + iter.forward_line() + + search_tag = self._tag_table.lookup(self.search_tag) + next_tag_found = iter.forward_to_tag_toggle(search_tag) + if not next_tag_found: + self._buffer.place_cursor( self._buffer.get_start_iter() ) + mark = self._buffer.get_insert() + iter = self._buffer.get_iter_at_mark(mark) + iter.forward_to_tag_toggle(search_tag) + + self._buffer.place_cursor(iter) + self._active_src_view.scroll_to_mark( self._buffer.get_insert(), 0.0, True, 0.0, 0.0 ) - def find_next(self, widget): - ... def find_all(self, widget): ... @@ -177,4 +220,4 @@ class Plugin(PluginBase): ... def replace_all(self, widget): - ... + ... \ No newline at end of file diff --git a/plugins/search_replace/search_replace.glade b/plugins/search_replace/search_replace.glade index 3a9f9e5..2904d59 100644 --- a/plugins/search_replace/search_replace.glade +++ b/plugins/search_replace/search_replace.glade @@ -72,6 +72,7 @@ .* True + False True False True @@ -187,8 +188,8 @@ 5 5 Find in current buffer + - 0 @@ -255,6 +256,7 @@ Find All True True + False True 5 5 @@ -272,6 +274,7 @@ Find True True + False True 5 5