Merge with 3.3
This commit is contained in:
commit
86d26238d3
|
@ -1,19 +1,28 @@
|
|||
'''Define SearchEngine for search dialogs.'''
|
||||
import re
|
||||
from tkinter import *
|
||||
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)
|
||||
# XXX This will never garbage-collect -- who cares
|
||||
# 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
|
||||
# State shared by search, replace, and grep;
|
||||
# the search dialogs bind these to UI elements.
|
||||
self.patvar = StringVar(root) # search pattern
|
||||
self.revar = BooleanVar(root) # regular expression?
|
||||
self.casevar = BooleanVar(root) # match case?
|
||||
|
@ -56,6 +65,7 @@ class SearchEngine:
|
|||
return pat
|
||||
|
||||
def getprog(self):
|
||||
"Return compiled cooked search pattern."
|
||||
pat = self.getpat()
|
||||
if not pat:
|
||||
self.report_error(pat, "Empty regular expression")
|
||||
|
@ -77,7 +87,7 @@ class SearchEngine:
|
|||
return prog
|
||||
|
||||
def report_error(self, pat, msg, col=-1):
|
||||
# Derived class could overrid this with something fancier
|
||||
# Derived class could override this with something fancier
|
||||
msg = "Error: " + str(msg)
|
||||
if pat:
|
||||
msg = msg + "\np\Pattern: " + str(pat)
|
||||
|
@ -92,25 +102,23 @@ class SearchEngine:
|
|||
self.setpat(pat)
|
||||
|
||||
def search_text(self, text, prog=None, ok=0):
|
||||
"""Search a text widget for the pattern.
|
||||
'''Return (lineno, matchobj) for prog in text widget, or None.
|
||||
|
||||
If prog is given, it should be the precompiled pattern.
|
||||
Return a tuple (lineno, matchobj); None if not found.
|
||||
If prog is given, it should be a precompiled pattern.
|
||||
Wrap (yes/no) and direction (forward/back) settings are used.
|
||||
|
||||
This obeys the wrap and direction (back) settings.
|
||||
|
||||
The search starts at the selection (if there is one) or
|
||||
at the insert mark (otherwise). If the search is forward,
|
||||
it starts at the right of the selection; for a backward
|
||||
search, it starts at the left end. An empty match exactly
|
||||
at either end of the selection (or at the insert mark if
|
||||
there is no selection) is ignored unless the ok flag is true
|
||||
-- this is done to guarantee progress.
|
||||
The search starts at the selection (if there is one) or at the
|
||||
insert mark (otherwise). If the search is forward, it starts
|
||||
at the right of the selection; for a backward search, it
|
||||
starts at the left end. An empty match exactly at either end
|
||||
of the selection (or at the insert mark if there is no
|
||||
selection) is ignored unless the ok flag is true -- this is
|
||||
done to guarantee progress.
|
||||
|
||||
If the search is allowed to wrap around, it will return the
|
||||
original selection if (and only if) it is the only match.
|
||||
'''
|
||||
|
||||
"""
|
||||
if not prog:
|
||||
prog = self.getprog()
|
||||
if not prog:
|
||||
|
@ -179,10 +187,11 @@ class SearchEngine:
|
|||
col = len(chars) - 1
|
||||
return None
|
||||
|
||||
# Helper to search backwards in a string.
|
||||
# (Optimized for the case where the pattern isn't found.)
|
||||
|
||||
def search_reverse(prog, chars, col):
|
||||
'''Search backwards in a string (line of text).
|
||||
|
||||
This is done by searching forwards until there is no match.
|
||||
'''
|
||||
m = prog.search(chars)
|
||||
if not m:
|
||||
return None
|
||||
|
@ -198,10 +207,9 @@ def search_reverse(prog, chars, col):
|
|||
i, j = m.span()
|
||||
return found
|
||||
|
||||
# Helper to get selection end points, defaulting to insert mark.
|
||||
# Return a tuple of indices ("line.col" strings).
|
||||
|
||||
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")
|
||||
|
@ -213,8 +221,12 @@ def get_selection(text):
|
|||
last = first
|
||||
return first, last
|
||||
|
||||
# Helper to parse a text index into a (line, col) tuple.
|
||||
|
||||
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__":
|
||||
## from test import support; support.use_resources = ['gui']
|
||||
## import unittest
|
||||
## unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False)
|
||||
|
|
Loading…
Reference in New Issue