Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Lib/idlelib/SearchEngine.py

    r2 r391  
     1'''Define SearchEngine for search dialogs.'''
    12import re
    2 from Tkinter import *
     3from Tkinter import StringVar, BooleanVar, TclError
    34import tkMessageBox
    45
    56def get(root):
     7    '''Return the singleton SearchEngine instance for the process.
     8
     9    The single SearchEngine saves settings between dialog instances.
     10    If there is not a SearchEngine already, make one.
     11    '''
    612    if not hasattr(root, "_searchengine"):
    713        root._searchengine = SearchEngine(root)
    8         # XXX This will never garbage-collect -- who cares
     14        # This creates a cycle that persists until root is deleted.
    915    return root._searchengine
    1016
    1117class SearchEngine:
     18    """Handles searching a text widget for Find, Replace, and Grep."""
    1219
    1320    def __init__(self, root):
    14         self.root = root
    15         # State shared by search, replace, and grep;
    16         # the search dialogs bind these to UI elements.
    17         self.patvar = StringVar(root)           # search pattern
    18         self.revar = BooleanVar(root)           # regular expression?
    19         self.casevar = BooleanVar(root)         # match case?
    20         self.wordvar = BooleanVar(root)         # match whole word?
    21         self.wrapvar = BooleanVar(root)         # wrap around buffer?
    22         self.wrapvar.set(1)                     # (on by default)
    23         self.backvar = BooleanVar(root)         # search backwards?
     21        '''Initialize Variables that save search state.
     22
     23        The dialogs bind these to the UI elements present in the dialogs.
     24        '''
     25        self.root = root  # need for report_error()
     26        self.patvar = StringVar(root, '')   # search pattern
     27        self.revar = BooleanVar(root, False)   # regular expression?
     28        self.casevar = BooleanVar(root, False)   # match case?
     29        self.wordvar = BooleanVar(root, False)   # match whole word?
     30        self.wrapvar = BooleanVar(root, True)   # wrap around buffer?
     31        self.backvar = BooleanVar(root, False)   # search backwards?
    2432
    2533    # Access methods
     
    4856    # Higher level access methods
    4957
     58    def setcookedpat(self, pat):
     59        "Set pattern after escaping if re."
     60        # called only in SearchDialog.py: 66
     61        if self.isre():
     62            pat = re.escape(pat)
     63        self.setpat(pat)
     64
    5065    def getcookedpat(self):
    5166        pat = self.getpat()
    52         if not self.isre():
     67        if not self.isre():  # if True, see setcookedpat
    5368            pat = re.escape(pat)
    5469        if self.isword():
     
    5772
    5873    def getprog(self):
     74        "Return compiled cooked search pattern."
    5975        pat = self.getpat()
    6076        if not pat:
     
    6783        try:
    6884            prog = re.compile(pat, flags)
    69         except re.error, what:
     85        except re.error as what:
    7086            try:
    7187                msg, col = what
     
    7894
    7995    def report_error(self, pat, msg, col=-1):
    80         # Derived class could overrid this with something fancier
     96        # Derived class could override this with something fancier
    8197        msg = "Error: " + str(msg)
    8298        if pat:
    83             msg = msg + "\np\Pattern: " + str(pat)
     99            msg = msg + "\nPattern: " + str(pat)
    84100        if col >= 0:
    85101            msg = msg + "\nOffset: " + str(col)
     
    87103                               msg, master=self.root)
    88104
    89     def setcookedpat(self, pat):
    90         if self.isre():
    91             pat = re.escape(pat)
    92         self.setpat(pat)
    93 
    94105    def search_text(self, text, prog=None, ok=0):
    95         """Search a text widget for the pattern.
    96 
    97         If prog is given, it should be the precompiled pattern.
    98         Return a tuple (lineno, matchobj); None if not found.
    99 
    100         This obeys the wrap and direction (back) settings.
    101 
    102         The search starts at the selection (if there is one) or
    103         at the insert mark (otherwise).  If the search is forward,
    104         it starts at the right of the selection; for a backward
    105         search, it starts at the left end.  An empty match exactly
    106         at either end of the selection (or at the insert mark if
    107         there is no selection) is ignored  unless the ok flag is true
    108         -- this is done to guarantee progress.
    109 
    110         If the search is allowed to wrap around, it will return the
    111         original selection if (and only if) it is the only match.
    112 
    113         """
     106        '''Return (lineno, matchobj) or None for forward/backward search.
     107
     108        This function calls the right function with the right arguments.
     109        It directly return the result of that call.
     110
     111        Text is a text widget. Prog is a precompiled pattern.
     112        The ok parameteris a bit complicated as it has two effects.
     113
     114        If there is a selection, the search begin at either end,
     115        depending on the direction setting and ok, with ok meaning that
     116        the search starts with the selection. Otherwise, search begins
     117        at the insert mark.
     118
     119        To aid progress, the search functions do not return an empty
     120        match at the starting position unless ok is True.
     121        '''
     122
    114123        if not prog:
    115124            prog = self.getprog()
     
    180189        return None
    181190
    182 # Helper to search backwards in a string.
    183 # (Optimized for the case where the pattern isn't found.)
    184 
    185191def search_reverse(prog, chars, col):
     192    '''Search backwards and return an re match object or None.
     193
     194    This is done by searching forwards until there is no match.
     195    Prog: compiled re object with a search method returning a match.
     196    Chars: line of text, without \n.
     197    Col: stop index for the search; the limit for match.end().
     198    '''
    186199    m = prog.search(chars)
    187200    if not m:
    188201        return None
    189202    found = None
    190     i, j = m.span()
     203    i, j = m.span()  # m.start(), m.end() == match slice indexes
    191204    while i < col and j <= col:
    192205        found = m
     
    199212    return found
    200213
    201 # Helper to get selection end points, defaulting to insert mark.
    202 # Return a tuple of indices ("line.col" strings).
    203 
    204214def get_selection(text):
     215    '''Return tuple of 'line.col' indexes from selection or insert mark.
     216    '''
    205217    try:
    206218        first = text.index("sel.first")
     
    214226    return first, last
    215227
    216 # Helper to parse a text index into a (line, col) tuple.
    217 
    218228def get_line_col(index):
     229    '''Return (line, col) tuple of ints from 'line.col' string.'''
    219230    line, col = map(int, index.split(".")) # Fails on invalid index
    220231    return line, col
     232
     233if __name__ == "__main__":
     234    from test import support; support.use_resources = ['gui']
     235    import unittest
     236    unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False)
Note: See TracChangeset for help on using the changeset viewer.