diff --git a/plugins/searcher/mixins/file_search_mixin.py b/plugins/searcher/mixins/file_search_mixin.py index 4095d65..51cddce 100644 --- a/plugins/searcher/mixins/file_search_mixin.py +++ b/plugins/searcher/mixins/file_search_mixin.py @@ -29,6 +29,7 @@ class FileSearchMixin: def _handle_find_file_query(self, widget=None, eve=None, query=None): # NOTE: Freeze IPC consumption self.pause_fifo_update = True + self.search_query = "" # NOTE: Kill the former process if self._list_proc: @@ -41,15 +42,13 @@ class FileSearchMixin: else: self._list_proc = None + # NOTE: Clear children from ui and make sure ui thread redraws GLib.idle_add(self.clear_children, self._file_list) while len(self._file_list.get_children()) > 0: - ... - - # NOTE: Make sure ui thread redraws - time.sleep(0.5) - self.pause_fifo_update = False + time.sleep(0.2) # NOTE: If query create new process and do all new loop. + self.pause_fifo_update = False if query: GLib.idle_add(self._exec_find_file_query, query) @@ -57,12 +56,16 @@ class FileSearchMixin: query = widget.get_text() if not query in ("", None): + self.search_query = query target_dir = shlex.quote( self._fm_state.tab.get_current_directory() ) command = ["python", f"{self.path}/utils/search.py", "-t", "file_search", "-d", f"{target_dir}", "-q", f"{query}"] self._list_proc = subprocess.Popen(command, cwd=self.path, stdin=None, stdout=None, stderr=None) def _load_file_ui(self, data): - if not data in ("", None) and not self.pause_fifo_update: + if self.pause_fifo_update: + return + + if not data in ("", None): jdata = json.loads( data ) target = jdata[0] file = jdata[1] diff --git a/plugins/searcher/mixins/grep_search_mixin.py b/plugins/searcher/mixins/grep_search_mixin.py index cdf1c58..a83a24c 100644 --- a/plugins/searcher/mixins/grep_search_mixin.py +++ b/plugins/searcher/mixins/grep_search_mixin.py @@ -29,6 +29,7 @@ class GrepSearchMixin: def _handle_grep_query(self, widget=None, eve=None, query=None): # NOTE: Freeze IPC consumption self.pause_fifo_update = True + self.grep_query = "" # NOTE: Kill the former process if self._grep_proc: @@ -41,34 +42,35 @@ class GrepSearchMixin: else: self._grep_proc = None - # NOTE: Clear children from ui + # NOTE: Clear children from ui and make sure ui thread redraws GLib.idle_add(self.clear_children, self._grep_list) while len(self._grep_list.get_children()) > 0: - ... - - # NOTE: Make sure ui thread redraws - time.sleep(0.5) - self.pause_fifo_update = False + time.sleep(0.2) # NOTE: If query create new process and do all new loop. + self.pause_fifo_update = False if query: GLib.idle_add(self._exec_grep_query, query) def _exec_grep_query(self, widget=None, eve=None): query = widget.get_text() if not query in ("", None): + self.grep_query = query + target_dir = shlex.quote( self._fm_state.tab.get_current_directory() ) command = ["python", f"{self.path}/utils/search.py", "-t", "grep_search", "-d", f"{target_dir}", "-q", f"{query}"] self._grep_proc = subprocess.Popen(command, cwd=self.path, stdin=None, stdout=None, stderr=None) def _load_grep_ui(self, data): - if not data in ("", None) and not self.pause_fifo_update: + if self.pause_fifo_update: + return + + if not data in ("", None): jdata = json.loads( data ) jkeys = jdata.keys() for key in jkeys: sub_keys = jdata[key].keys() grep_result = jdata[key] - widget = GrepPreviewWidget(key, sub_keys, grep_result) - GLib.idle_add(self._grep_list.add, widget) - # self._grep_list.add(widget) + widget = GrepPreviewWidget(key, sub_keys, grep_result, self.grep_query) + self._grep_list.add(widget) diff --git a/plugins/searcher/plugin.py b/plugins/searcher/plugin.py index 61eaeda..d506e21 100644 --- a/plugins/searcher/plugin.py +++ b/plugins/searcher/plugin.py @@ -1,5 +1,5 @@ # Python imports -import os, threading, inspect +import os, threading, inspect, time # Lib imports import gi @@ -46,6 +46,8 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase): self._list_proc = None self.pause_fifo_update = False self.update_list_ui_buffer = () + self.grep_query = "" + self.search_query = "" def get_ui_element(self): @@ -95,3 +97,4 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase): ''' Clear children of a gtk widget. ''' for child in widget.get_children(): widget.remove(child) + time.sleep(0.01) diff --git a/plugins/searcher/utils/ipc_server.py b/plugins/searcher/utils/ipc_server.py index 937a474..96969cf 100644 --- a/plugins/searcher/utils/ipc_server.py +++ b/plugins/searcher/utils/ipc_server.py @@ -48,47 +48,32 @@ class IPCServer: self.is_ipc_alive = True while True: - conn = listener.accept() - start_time = time.perf_counter() - self.handle_message(conn, start_time) + conn = listener.accept() + + if not self.pause_fifo_update: + self.handle_message(conn) + else: + conn.close() listener.close() - def handle_message(self, conn, start_time) -> None: + def handle_message(self, conn) -> None: while True: msg = conn.recv() - if not self.pause_fifo_update: - if "SEARCH|" in msg: - file = msg.split("SEARCH|")[1].strip() - if file: - GLib.idle_add(self._load_file_ui, file) + if "SEARCH|" in msg: + file = msg.split("SEARCH|")[1].strip() + if file: + GLib.idle_add(self._load_file_ui, file) - conn.close() - break - - if "GREP|" in msg: - data = msg.split("GREP|")[1].strip() - if data: - GLib.idle_add(self._load_grep_ui, data) - - conn.close() - break + if "GREP|" in msg: + data = msg.split("GREP|")[1].strip() + if data: + GLib.idle_add(self._load_grep_ui, data) - if msg in ['close connection', 'close server']: - conn.close() - break - - # NOTE: Not perfect but insures we don't lock up the connection for too long. - end_time = time.perf_counter() - if (end_time - start_time) > self._ipc_timeout: - conn.close() - break - else: - conn.close() - break - + conn.close() + break def send_ipc_message(self, message: str = "Empty Data...") -> None: try: diff --git a/plugins/searcher/utils/search.py b/plugins/searcher/utils/search.py index 1355f1d..31bdcc6 100755 --- a/plugins/searcher/utils/search.py +++ b/plugins/searcher/utils/search.py @@ -33,15 +33,11 @@ def daemon_threaded(fn): def send_ipc_message(message) -> None: - try: - conn = Client(address=_ipc_address, family="AF_UNIX", authkey=_ipc_authkey) - + with Client(address=_ipc_address, family="AF_UNIX", authkey=_ipc_authkey) as conn: conn.send(message) conn.close() - except ConnectionRefusedError as e: - print("Connection refused...") - except Exception as e: - print(repr(e)) + + time.sleep(0.05) def file_search(path, query): diff --git a/plugins/searcher/widgets/grep_preview_widget.py b/plugins/searcher/widgets/grep_preview_widget.py index 899d309..4e6b799 100644 --- a/plugins/searcher/widgets/grep_preview_widget.py +++ b/plugins/searcher/widgets/grep_preview_widget.py @@ -1,5 +1,5 @@ # Python imports -import base64 +import base64, re # Lib imports import gi @@ -10,28 +10,31 @@ from gi.repository import Gtk class GrepPreviewWidget(Gtk.Box): - def __init__(self, _path, sub_keys, _data): + def __init__(self, _path, sub_keys, _data, _grep_query): super(GrepPreviewWidget, self).__init__() - self.set_orientation(Gtk.Orientation.VERTICAL) - self.line_color = "#e0cc64" - path = self.decode_str(_path) - _label = '/'.join( path.split("/")[-3:] ) - title = Gtk.LinkButton.new_with_label(uri=f"file://{path}", label=_label) + self.set_orientation(Gtk.Orientation.VERTICAL) + line_color = "#e0cc64" + highlight_color = "#FBF719" + grep_query = _grep_query + + path = self.decode_str(_path) + lbl = '/'.join( path.split("/")[-3:] ) + title = Gtk.LinkButton.new_with_label(uri=f"file://{path}", label=lbl) text_view = Gtk.TextView() - text_view.set_editable(False) - text_view.set_wrap_mode(Gtk.WrapMode.NONE) buffer = text_view.get_buffer() + text_view.set_editable(False) + text_view.set_monospace(True) + text_view.set_wrap_mode(Gtk.WrapMode.NONE) for i, key in enumerate(sub_keys): - line_num = self.make_utf8_line_num(self.line_color, key) - text = f"\t\t{ self.decode_str(_data[key]) }" - + line_num = self.make_utf8_line_num(line_color, key) itr = buffer.get_end_iter() buffer.insert_markup(itr, line_num, len(line_num)) - itr = buffer.get_end_iter() - buffer.insert(itr, text, length=len(text)) + + decoded = f"\t{self.decode_str(_data[key])}" + self.make_utf8_line_highlight(buffer, itr, i, highlight_color, decoded, grep_query) self.add(title) self.add(text_view) @@ -42,3 +45,15 @@ class GrepPreviewWidget(Gtk.Box): def make_utf8_line_num(self, color, target): return bytes(f"\n{target}", "utf-8").decode("utf-8") + + def make_utf8_line_highlight(self, buffer, itr, i, color, target, query): + parts = re.split(r"(" + query + ")(?i)", target.replace("\n", "")) + for part in parts: + itr = buffer.get_end_iter() + + if not query.lower() == part.lower() and not query.lower() in part.lower(): + buffer.insert(itr, part, length=len(part)) + else: + new_s = f"{part}" + _part = bytes(new_s, "utf-8").decode("utf-8") + buffer.insert_markup(itr, _part, len(_part)) diff --git a/user_config/usr/share/solarfm/settings.json b/user_config/usr/share/solarfm/settings.json index 9b6850b..d9d1789 100644 --- a/user_config/usr/share/solarfm/settings.json +++ b/user_config/usr/share/solarfm/settings.json @@ -23,7 +23,7 @@ "remux_folder_max_disk_usage": "8589934592" }, "filters": { - "code": [".cpp", ".css", ".c", ".go", ".html", ".htm", ".java", ".js", ".json", ".lua", ".md", ".py", ".rs"], + "code": [".cpp", ".css", ".c", ".go", ".html", ".htm", ".java", ".js", ".json", ".lua", ".md", ".py", ".rs", ".toml", ".xml", ".pom"], "videos": [".mkv", ".mp4", ".webm", ".avi", ".mov", ".m4v", ".mpg", ".mpeg", ".wmv", ".flv"], "office": [".doc", ".docx", ".xls", ".xlsx", ".xlt", ".xltx", ".xlm", ".ppt", ".pptx", ".pps", ".ppsx", ".odt", ".rtf"], "images": [".png", ".jpg", ".jpeg", ".gif", ".ico", ".tga", ".webp"],