diff options
author | Terry Jan Reedy <tjreedy@udel.edu> | 2016-05-22 23:10:31 (GMT) |
---|---|---|
committer | Terry Jan Reedy <tjreedy@udel.edu> | 2016-05-22 23:10:31 (GMT) |
commit | 0d9220e162f1e5f8caa3d7ebaa54665776d361a1 (patch) | |
tree | a4fa9f7cafdfc93fde86b8ffd6088d739bb93e01 /Lib/idlelib/SearchEngine.py | |
parent | dc4f7c09cc934524a763498250e30123a0d9d2c5 (diff) | |
download | cpython-0d9220e162f1e5f8caa3d7ebaa54665776d361a1.zip cpython-0d9220e162f1e5f8caa3d7ebaa54665776d361a1.tar.gz cpython-0d9220e162f1e5f8caa3d7ebaa54665776d361a1.tar.bz2 |
Issue #24225: Rename many idlelib/*.py and idlelib/idle_test/test_*.py files.
Diffstat (limited to 'Lib/idlelib/SearchEngine.py')
-rw-r--r-- | Lib/idlelib/SearchEngine.py | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/Lib/idlelib/SearchEngine.py b/Lib/idlelib/SearchEngine.py deleted file mode 100644 index 37883bf..0000000 --- a/Lib/idlelib/SearchEngine.py +++ /dev/null @@ -1,233 +0,0 @@ -'''Define SearchEngine for search dialogs.''' -import re -from tkinter import StringVar, BooleanVar, TclError -import tkinter.messagebox as tkMessageBox - -def get(root): - '''Return the singleton SearchEngine instance for the process. - - The single SearchEngine saves settings between dialog instances. - If there is not a SearchEngine already, make one. - ''' - if not hasattr(root, "_searchengine"): - root._searchengine = SearchEngine(root) - # This creates a cycle that persists until root is deleted. - return root._searchengine - -class SearchEngine: - """Handles searching a text widget for Find, Replace, and Grep.""" - - def __init__(self, root): - '''Initialize Variables that save search state. - - The dialogs bind these to the UI elements present in the dialogs. - ''' - self.root = root # need for report_error() - self.patvar = StringVar(root, '') # search pattern - self.revar = BooleanVar(root, False) # regular expression? - self.casevar = BooleanVar(root, False) # match case? - self.wordvar = BooleanVar(root, False) # match whole word? - self.wrapvar = BooleanVar(root, True) # wrap around buffer? - self.backvar = BooleanVar(root, False) # search backwards? - - # Access methods - - def getpat(self): - return self.patvar.get() - - def setpat(self, pat): - self.patvar.set(pat) - - def isre(self): - return self.revar.get() - - def iscase(self): - return self.casevar.get() - - def isword(self): - return self.wordvar.get() - - def iswrap(self): - return self.wrapvar.get() - - def isback(self): - return self.backvar.get() - - # Higher level access methods - - def setcookedpat(self, pat): - "Set pattern after escaping if re." - # called only in SearchDialog.py: 66 - if self.isre(): - pat = re.escape(pat) - self.setpat(pat) - - def getcookedpat(self): - pat = self.getpat() - if not self.isre(): # if True, see setcookedpat - pat = re.escape(pat) - if self.isword(): - pat = r"\b%s\b" % pat - return pat - - def getprog(self): - "Return compiled cooked search pattern." - pat = self.getpat() - if not pat: - self.report_error(pat, "Empty regular expression") - return None - pat = self.getcookedpat() - flags = 0 - if not self.iscase(): - flags = flags | re.IGNORECASE - try: - prog = re.compile(pat, flags) - except re.error as what: - args = what.args - msg = args[0] - col = args[1] if len(args) >= 2 else -1 - self.report_error(pat, msg, col) - return None - return prog - - def report_error(self, pat, msg, col=-1): - # Derived class could override this with something fancier - msg = "Error: " + str(msg) - if pat: - msg = msg + "\nPattern: " + str(pat) - if col >= 0: - msg = msg + "\nOffset: " + str(col) - tkMessageBox.showerror("Regular expression error", - msg, master=self.root) - - def search_text(self, text, prog=None, ok=0): - '''Return (lineno, matchobj) or None for forward/backward search. - - This function calls the right function with the right arguments. - It directly return the result of that call. - - Text is a text widget. Prog is a precompiled pattern. - The ok parameter is a bit complicated as it has two effects. - - If there is a selection, the search begin at either end, - depending on the direction setting and ok, with ok meaning that - the search starts with the selection. Otherwise, search begins - at the insert mark. - - To aid progress, the search functions do not return an empty - match at the starting position unless ok is True. - ''' - - if not prog: - prog = self.getprog() - if not prog: - return None # Compilation failed -- stop - wrap = self.wrapvar.get() - first, last = get_selection(text) - if self.isback(): - if ok: - start = last - else: - start = first - line, col = get_line_col(start) - res = self.search_backward(text, prog, line, col, wrap, ok) - else: - if ok: - start = first - else: - start = last - line, col = get_line_col(start) - res = self.search_forward(text, prog, line, col, wrap, ok) - return res - - def search_forward(self, text, prog, line, col, wrap, ok=0): - wrapped = 0 - startline = line - chars = text.get("%d.0" % line, "%d.0" % (line+1)) - while chars: - m = prog.search(chars[:-1], col) - if m: - if ok or m.end() > col: - return line, m - line = line + 1 - if wrapped and line > startline: - break - col = 0 - ok = 1 - chars = text.get("%d.0" % line, "%d.0" % (line+1)) - if not chars and wrap: - wrapped = 1 - wrap = 0 - line = 1 - chars = text.get("1.0", "2.0") - return None - - def search_backward(self, text, prog, line, col, wrap, ok=0): - wrapped = 0 - startline = line - chars = text.get("%d.0" % line, "%d.0" % (line+1)) - while 1: - m = search_reverse(prog, chars[:-1], col) - if m: - if ok or m.start() < col: - return line, m - line = line - 1 - if wrapped and line < startline: - break - ok = 1 - if line <= 0: - if not wrap: - break - wrapped = 1 - wrap = 0 - pos = text.index("end-1c") - line, col = map(int, pos.split(".")) - chars = text.get("%d.0" % line, "%d.0" % (line+1)) - col = len(chars) - 1 - return None - -def search_reverse(prog, chars, col): - '''Search backwards and return an re match object or None. - - This is done by searching forwards until there is no match. - Prog: compiled re object with a search method returning a match. - Chars: line of text, without \\n. - Col: stop index for the search; the limit for match.end(). - ''' - m = prog.search(chars) - if not m: - return None - found = None - i, j = m.span() # m.start(), m.end() == match slice indexes - while i < col and j <= col: - found = m - if i == j: - j = j+1 - m = prog.search(chars, j) - if not m: - break - i, j = m.span() - return found - -def get_selection(text): - '''Return tuple of 'line.col' indexes from selection or insert mark. - ''' - try: - first = text.index("sel.first") - last = text.index("sel.last") - except TclError: - first = last = None - if not first: - first = text.index("insert") - if not last: - last = first - return first, last - -def get_line_col(index): - '''Return (line, col) tuple of ints from 'line.col' string.''' - line, col = map(int, index.split(".")) # Fails on invalid index - return line, col - -if __name__ == "__main__": - import unittest - unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False) |