generated from itdominator/Python-With-Gtk-Template
More work on search and replace
This commit is contained in:
parent
3ad7c3b65d
commit
f10f4fcc72
@ -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
|
||||
|
@ -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):
|
||||
...
|
||||
...
|
@ -72,6 +72,7 @@
|
||||
<object class="GtkToggleButton">
|
||||
<property name="label" translatable="yes">.*</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="focus-on-click">False</property>
|
||||
<property name="receives-default">True</property>
|
||||
@ -187,8 +188,8 @@
|
||||
<property name="margin-top">5</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="placeholder-text" translatable="yes">Find in current buffer</property>
|
||||
<signal name="activate" handler="find_next" swapped="no"/>
|
||||
<signal name="changed" handler="search_for_string" swapped="no"/>
|
||||
<signal name="key-release-event" handler="find_next_entry" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
@ -255,6 +256,7 @@
|
||||
<property name="label" translatable="yes">Find All</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="focus-on-click">False</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-end">5</property>
|
||||
@ -272,6 +274,7 @@
|
||||
<property name="label" translatable="yes">Find</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="focus-on-click">False</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-end">5</property>
|
||||
|
Loading…
Reference in New Issue
Block a user