[Python-checkins] python/dist/src/Lib/idlelib CodeContext.py, 1.4, 1.5 NEWS.txt, 1.62, 1.63

kbk@users.sourceforge.net kbk at users.sourceforge.net
Mon Oct 3 01:36:49 CEST 2005


Update of /cvsroot/python/python/dist/src/Lib/idlelib
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32569

Modified Files:
	CodeContext.py NEWS.txt 
Log Message:
Increased performance in CodeContext extension  Patch 936169 Noam Raphael


Index: CodeContext.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/CodeContext.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- CodeContext.py	6 Jun 2004 01:29:21 -0000	1.4
+++ CodeContext.py	2 Oct 2005 23:36:46 -0000	1.5
@@ -14,10 +14,10 @@
 from configHandler import idleConf
 from sets import Set
 import re
+from sys import maxint as INFINITY
 
 BLOCKOPENERS = Set(["class", "def", "elif", "else", "except", "finally", "for",
                     "if", "try", "while"])
-INFINITY = 1 << 30
 UPDATEINTERVAL = 100 # millisec
 FONTUPDATEINTERVAL = 1000 # millisec
 
@@ -37,8 +37,12 @@
         self.text = editwin.text
         self.textfont = self.text["font"]
         self.label = None
-        # Dummy line, which starts the "block" of the whole document:
-        self.info = list(self.interesting_lines(1))
+        # self.info holds information about the context lines of line number
+        # self.lastfirstline. The information is a tuple of the line's
+        # indentation, the line's text and the keyword at the beginning of the
+        # line, as returned by get_line_info. At the beginning of the list
+        # there's a dummy line, which starts the "block" of the whole document.
+        self.info = [(0, -1, "", False)]
         self.lastfirstline = 1
         visible = idleConf.GetOption("extensions", "CodeContext",
                                      "visible", type="bool", default=False)
@@ -73,14 +77,7 @@
 
         If the line does not start a block, the keyword value is False.
         The indentation of empty lines (or comment lines) is INFINITY.
-        There is a dummy block start, with indentation -1 and text "".
-
-        Return the indent level, text (including leading whitespace),
-        and the block opening keyword.
-
         """
-        if linenum == 0:
-            return -1, "", True
         text = self.text.get("%d.0" % linenum, "%d.end" % linenum)
         spaces, firstword = getspacesfirstword(text)
         opener = firstword in BLOCKOPENERS and firstword
@@ -90,40 +87,59 @@
             indent = len(spaces)
         return indent, text, opener
 
-    def interesting_lines(self, firstline):
-        """Generator which yields context lines, starting at firstline."""
+    def interesting_lines(self, firstline, stopline=1, stopindent=0):
+        """
+        Find the context lines, starting at firstline.
+        Will not return lines whose index is smaller than stopline or whose
+        indentation is smaller than stopindent.
+        stopline should always be >= 1, so the dummy block start will never
+        be returned (This function doesn't know what to do about it.)
+        Returns a list with the context lines, starting from the first (top),
+        and a number which all context lines above the inspected region should
+        have a smaller indentation than it.
+        """
+        lines = []
         # The indentation level we are currently in:
         lastindent = INFINITY
         # For a line to be interesting, it must begin with a block opening
         # keyword, and have less indentation than lastindent.
-        for line_index in xrange(firstline, -1, -1):
+        for line_index in xrange(firstline, stopline-1, -1):
             indent, text, opener = self.get_line_info(line_index)
             if indent < lastindent:
                 lastindent = indent
                 if opener in ("else", "elif"):
                     # We also show the if statement
                     lastindent += 1
-                if opener and line_index < firstline:
-                    yield line_index, text
+                if opener and line_index < firstline and indent >= stopindent:
+                    lines.append((line_index, indent, text, opener))
+                if lastindent <= stopindent:
+                    break
+        lines.reverse()
+        return lines, lastindent
 
     def update_label(self):
+        """Update the CodeContext label, if needed.
+        """
         firstline = int(self.text.index("@0,0").split('.')[0])
         if self.lastfirstline == firstline:
             return
-        self.lastfirstline = firstline
-        tmpstack = []
-        for line_index, text in self.interesting_lines(firstline):
-            # Remove irrelevant self.info items, and when we reach a relevant
-            # item (which must happen because of the dummy element), break.
-            while self.info[-1][0] > line_index:
+        if self.lastfirstline < firstline:
+            lines, lastindent = self.interesting_lines(firstline,
+                                                       self.lastfirstline)
+            while self.info[-1][1] >= lastindent:
                 del self.info[-1]
-            if self.info[-1][0] == line_index:
-                break
-            tmpstack.append((line_index, text))
-        while tmpstack:
-            self.info.append(tmpstack.pop())
+            self.info.extend(lines)
+        else:
+            stopindent = self.info[-1][1] + 1
+            while self.info[-1][0] >= firstline:
+                stopindent = self.info[-1][1]
+                del self.info[-1]
+            lines, lastindent = self.interesting_lines(
+                firstline, self.info[-1][0]+1, stopindent)
+            self.info.extend(lines)
+        self.lastfirstline = firstline
         lines = [""] * max(0, self.numlines - len(self.info)) + \
-                [x[1] for x in self.info[-self.numlines:]]
+                [x[2] for x in self.info[-self.numlines:]]
         self.label["text"] = '\n'.join(lines)
 
     def timer_event(self):

Index: NEWS.txt
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/NEWS.txt,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -d -r1.62 -r1.63
--- NEWS.txt	23 Aug 2005 02:27:23 -0000	1.62
+++ NEWS.txt	2 Oct 2005 23:36:46 -0000	1.63
@@ -3,6 +3,8 @@
 
 *Release date: XX-XXX-2005*
 
+- Increased performance in CodeContext extension  Patch 936169 Noam Raphael
+
 - Mac line endings were incorrect when pasting code from some browsers
   when using X11 and the Fink distribution.  Python Bug 1263656.
 
@@ -148,12 +150,12 @@
 - If nulls somehow got into the strings in recent-files.lst
   EditorWindow.update_recent_files_list() was failing.  Python Bug 931336.
 
-- If the normal background is changed via Configure/Highlighting, it will update
-  immediately, thanks to the previously mentioned patch by Nigel Rowe.
+- If the normal background is changed via Configure/Highlighting, it will
+  update immediately, thanks to the previously mentioned patch by Nigel Rowe.
 
 - Add a highlight theme for builtin keywords.  Python Patch 805830 Nigel Rowe
-  This also fixed IDLEfork bug [ 693418 ] Normal text background color not refreshed
-  and Python bug [897872 ] Unknown color name on HP-UX
+  This also fixed IDLEfork bug [ 693418 ] Normal text background color not
+  refreshed and Python bug [897872 ] Unknown color name on HP-UX
 
 - rpc.py:SocketIO - Large modules were generating large pickles when downloaded
   to the execution server.  The return of the OK response from the subprocess



More information about the Python-checkins mailing list