Skip to content

Commit

Permalink
WIP: Partial implementation of regex indicate_line
Browse files Browse the repository at this point in the history
  • Loading branch information
MHendricks committed Mar 10, 2024
1 parent ac07360 commit 6902fca
Showing 1 changed file with 67 additions and 11 deletions.
78 changes: 67 additions & 11 deletions preditor/gui/find_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def __init__(self, find_text, case_sensitive):
self.case_sensitive = case_sensitive
self.find_text = find_text
self.margin_format = " {line_num: 4d}{match_indicator} {line}"
self.match_count = 0
self.match_file_count = 0

@abc.abstractmethod
def indicate_line(self, line):
Expand Down Expand Up @@ -56,21 +58,56 @@ def margin(self, line_num, match_found):
def matches(self, line):
"""Returns bool for if find_text is contained in this line."""

def title(self):
return '\nFind in workboxs: "{}"{}\n\n'.format(self.find_text, self.title_flags)

@property
@abc.abstractmethod
def title_flags(self):
"""Returns the text to show in the title for flags."""


class RegexFinder(Finder):
"""Finder that processes the text using regex."""

def __init__(self, find_text, case_sensitive):
super(RegexFinder, self).__init__(find_text, case_sensitive)
self.pattern = re.compile(find_text, flags=re.I if case_sensitive else 0)
self.pattern = re.compile(find_text, flags=0 if case_sensitive else re.I)
self._matches = None

def indicate_line(self, line):
# TODO: Properly implement this
yield line, False
# Write the margin indicating if this line has any matches
yield None, bool(self._matches)

start = 0
if self._matches:
# print([line, self._matches])
for m in self._matches:
pre = line[start : m.start()]
if pre:
yield pre, False
yield line[m.start() : m.end()], True
start = m.end()
# Record the match
self.match_count += 1
post = line[start:]
if post:
yield post, False
else:
yield line, False

# Reset regex cache for the next call to `matches`
self._matches = None

def matches(self, txt):
match = self.pattern.search(txt)
return match is not None
self._matches = list(self.pattern.finditer(txt))
return bool(self._matches)

@property
def title_flags(self):
if self.case_sensitive:
return " (regex, case sensitive)"
return " (regex)"


class SimpleFinder(Finder):
Expand Down Expand Up @@ -113,6 +150,8 @@ def indicate_line(self, line):
yield original_line[start:end], False
# insert indicated text preserving case
yield original_line[end : end + find_len], True
# Record the match
self.match_count += 1

# Check for any more matches in this line
start = end + find_len
Expand All @@ -125,6 +164,12 @@ def indicate_line(self, line):
def matches(self, txt):
return self._matches(txt)

@property
def title_flags(self):
if self.case_sensitive:
return " (case sensitive)"
return ""


class FindFiles(QWidget):
def __init__(self, parent=None, managers=None, console=None):
Expand All @@ -134,6 +179,7 @@ def __init__(self, parent=None, managers=None, console=None):
self.managers = managers
self.console = console
self.finder = None
self.match_files_count = 0

loadUi(__file__, self)

Expand Down Expand Up @@ -167,16 +213,16 @@ def activate(self):

def find(self):
find_text = self.uiFindTXT.text()
cs = " (case sensitive)" if self.uiCaseSensitiveBTN.isChecked() else ""
self.insert_text('\nFind in workboxs: "{}"{}\n\n'.format(find_text, cs))

# Create an instance of the Finder to use for this search
if self.uiRegexBTN.isChecked():
Finder = RegexFinder
else:
Finder = SimpleFinder
self.finder = Finder(find_text, cs)
self.finder = Finder(find_text, self.uiCaseSensitiveBTN.isChecked())

self.insert_text(self.finder.title())

self.match_files_count = 0
for manager in self.managers:
for (
editor,
Expand All @@ -189,7 +235,11 @@ def find(self):
workbox_id = '{},{}'.format(group_index, tab_index)
self.search_file_simple(editor, find_text, path, workbox_id)

self.insert_text('\n{} matches in {} workboxes\n'.format(0, 0))
self.insert_text(
'\n{} matches in {} workboxes\n'.format(
self.finder.match_count, self.match_files_count
)
)

def indicate_results(
self,
Expand Down Expand Up @@ -285,8 +335,14 @@ def search_file_simple(self, editor, find_text, path, workbox_id):
len_pre_history = len(pre_history)
if first:
# Print the filename on the first find
self.insert_text("# File: {}\n".format(path))
self.insert_text("# File: ")
href = ', {}, 0'.format(workbox_id)
tool_tip = "Open {}".format(path)
self.insert_found_text(path, href, tool_tip)
self.insert_text("\n")
first = False
# Record that we found a match in this file
self.match_files_count += 1
elif i > context and len_pre_history:
self.insert_text(
" {dot: >{padding}} \n".format(
Expand Down

0 comments on commit 6902fca

Please sign in to comment.