Added support to show the current class/method name in the combo boxes at the top of the editor.

Wed, 03 Jul 2013 19:34:42 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 03 Jul 2013 19:34:42 +0200
changeset 2768
eab35f6e709f
parent 2766
c413e9eeaf95
child 2769
8cbebde7a984

Added support to show the current class/method name in the combo boxes at the top of the editor.

APIs/Python3/eric5.api file | annotate | diff | comparison | revisions
Documentation/Help/source.qch file | annotate | diff | comparison | revisions
Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
Documentation/Source/eric5.QScintilla.Editor.html file | annotate | diff | comparison | revisions
Documentation/Source/eric5.QScintilla.EditorAssembly.html file | annotate | diff | comparison | revisions
Documentation/Source/eric5.Utilities.ClassBrowsers.ClbrBaseClasses.html file | annotate | diff | comparison | revisions
Documentation/Source/eric5.Utilities.ModuleParser.html file | annotate | diff | comparison | revisions
QScintilla/Editor.py file | annotate | diff | comparison | revisions
QScintilla/EditorAssembly.py file | annotate | diff | comparison | revisions
Utilities/ClassBrowsers/ClbrBaseClasses.py file | annotate | diff | comparison | revisions
Utilities/ClassBrowsers/pyclbr.py file | annotate | diff | comparison | revisions
Utilities/ModuleParser.py file | annotate | diff | comparison | revisions
changelog file | annotate | diff | comparison | revisions
--- a/APIs/Python3/eric5.api	Wed Jul 03 19:23:52 2013 +0200
+++ b/APIs/Python3/eric5.api	Wed Jul 03 19:34:42 2013 +0200
@@ -6569,6 +6569,7 @@
 eric5.QScintilla.Editor.Editor.coverageMarkersShown?7
 eric5.QScintilla.Editor.Editor.curLineHasBreakpoint?4()
 eric5.QScintilla.Editor.Editor.cursorChanged?7
+eric5.QScintilla.Editor.Editor.cursorLineChanged?7
 eric5.QScintilla.Editor.Editor.determineFileType?4()
 eric5.QScintilla.Editor.Editor.dragEnterEvent?4(event)
 eric5.QScintilla.Editor.Editor.dragLeaveEvent?4(event)
@@ -7887,6 +7888,7 @@
 eric5.Utilities.ClassBrowsers.ClbrBaseClasses.Function.Static?7
 eric5.Utilities.ClassBrowsers.ClbrBaseClasses.Function?1(module, name, file, lineno, signature='', separator=', ', modifierType=General)
 eric5.Utilities.ClassBrowsers.ClbrBaseClasses.Module?1(module, name, file, lineno)
+eric5.Utilities.ClassBrowsers.ClbrBaseClasses._ClbrBase.setEndLine?4(endLineNo)
 eric5.Utilities.ClassBrowsers.ClbrBaseClasses._ClbrBase?2(module, name, file, lineno)
 eric5.Utilities.ClassBrowsers.IDL_SOURCE?7
 eric5.Utilities.ClassBrowsers.PTL_SOURCE?7
@@ -7949,6 +7951,7 @@
 eric5.Utilities.ModuleParser.Function.General?7
 eric5.Utilities.ModuleParser.Function.Static?7
 eric5.Utilities.ModuleParser.Function.addDescription?4(description)
+eric5.Utilities.ModuleParser.Function.setEndLine?4(endLineNo)
 eric5.Utilities.ModuleParser.Function?1(module, name, file, lineno, signature='', pyqtSignature=None, modifierType=General)
 eric5.Utilities.ModuleParser.Module.addClass?4(name, _class)
 eric5.Utilities.ModuleParser.Module.addDescription?4(description)
Binary file Documentation/Help/source.qch has changed
--- a/Documentation/Help/source.qhp	Wed Jul 03 19:23:52 2013 +0200
+++ b/Documentation/Help/source.qhp	Wed Jul 03 19:34:42 2013 +0200
@@ -4274,6 +4274,7 @@
       <keyword name="EditorAssembly" id="EditorAssembly" ref="eric5.QScintilla.EditorAssembly.html#EditorAssembly" />
       <keyword name="EditorAssembly (Constructor)" id="EditorAssembly (Constructor)" ref="eric5.QScintilla.EditorAssembly.html#EditorAssembly.__init__" />
       <keyword name="EditorAssembly (Module)" id="EditorAssembly (Module)" ref="eric5.QScintilla.EditorAssembly.html" />
+      <keyword name="EditorAssembly.__editorCursorLineChanged" id="EditorAssembly.__editorCursorLineChanged" ref="eric5.QScintilla.EditorAssembly.html#EditorAssembly.__editorCursorLineChanged" />
       <keyword name="EditorAssembly.__globalsActivated" id="EditorAssembly.__globalsActivated" ref="eric5.QScintilla.EditorAssembly.html#EditorAssembly.__globalsActivated" />
       <keyword name="EditorAssembly.__membersActivated" id="EditorAssembly.__membersActivated" ref="eric5.QScintilla.EditorAssembly.html#EditorAssembly.__membersActivated" />
       <keyword name="EditorAssembly.__parseEditor" id="EditorAssembly.__parseEditor" ref="eric5.QScintilla.EditorAssembly.html#EditorAssembly.__parseEditor" />
@@ -4803,6 +4804,7 @@
       <keyword name="Function (Constructor)" id="Function (Constructor)" ref="eric5.Utilities.ClassBrowsers.rbclbr.html#Function.__init__" />
       <keyword name="Function (Constructor)" id="Function (Constructor)" ref="eric5.Utilities.ModuleParser.html#Function.__init__" />
       <keyword name="Function.addDescription" id="Function.addDescription" ref="eric5.Utilities.ModuleParser.html#Function.addDescription" />
+      <keyword name="Function.setEndLine" id="Function.setEndLine" ref="eric5.Utilities.ModuleParser.html#Function.setEndLine" />
       <keyword name="FunctionDefinition" id="FunctionDefinition" ref="eric5.Utilities.py3flakes.checker.html#FunctionDefinition" />
       <keyword name="FunctionDefinition" id="FunctionDefinition" ref="eric5.UtilitiesPython2.py2flakes.checker.html#FunctionDefinition" />
       <keyword name="FunctionScope" id="FunctionScope" ref="eric5.Utilities.py3flakes.checker.html#FunctionScope" />
@@ -12336,6 +12338,7 @@
       <keyword name="ZoomDialog.getZoomSize" id="ZoomDialog.getZoomSize" ref="eric5.QScintilla.ZoomDialog.html#ZoomDialog.getZoomSize" />
       <keyword name="_ClbrBase" id="_ClbrBase" ref="eric5.Utilities.ClassBrowsers.ClbrBaseClasses.html#_ClbrBase" />
       <keyword name="_ClbrBase (Constructor)" id="_ClbrBase (Constructor)" ref="eric5.Utilities.ClassBrowsers.ClbrBaseClasses.html#_ClbrBase.__init__" />
+      <keyword name="_ClbrBase.setEndLine" id="_ClbrBase.setEndLine" ref="eric5.Utilities.ClassBrowsers.ClbrBaseClasses.html#_ClbrBase.setEndLine" />
       <keyword name="_StrikeThroughExtension" id="_StrikeThroughExtension" ref="eric5.UI.Previewer.html#_StrikeThroughExtension" />
       <keyword name="_StrikeThroughExtension.extendMarkdown" id="_StrikeThroughExtension.extendMarkdown" ref="eric5.UI.Previewer.html#_StrikeThroughExtension.extendMarkdown" />
       <keyword name="__getMasterPassword" id="__getMasterPassword" ref="eric5.Utilities.crypto.__init__.html#__getMasterPassword" />
--- a/Documentation/Source/eric5.QScintilla.Editor.html	Wed Jul 03 19:23:52 2013 +0200
+++ b/Documentation/Source/eric5.QScintilla.Editor.html	Wed Jul 03 19:34:42 2013 +0200
@@ -71,6 +71,9 @@
 <dd>
 emitted when the cursor position
             was changed
+</dd><dt>cursorLineChanged(int)</dt>
+<dd>
+emitted when the cursor line was changed
 </dd><dt>editorAboutToBeSaved(str)</dt>
 <dd>
 emitted before the editor is saved
--- a/Documentation/Source/eric5.QScintilla.EditorAssembly.html	Wed Jul 03 19:23:52 2013 +0200
+++ b/Documentation/Source/eric5.QScintilla.EditorAssembly.html	Wed Jul 03 19:34:42 2013 +0200
@@ -62,6 +62,9 @@
 <td><a href="#EditorAssembly.__init__">EditorAssembly</a></td>
 <td>Constructor</td>
 </tr><tr>
+<td><a href="#EditorAssembly.__editorCursorLineChanged">__editorCursorLineChanged</a></td>
+<td>Private slot handling a line change of the cursor of the editor.</td>
+</tr><tr>
 <td><a href="#EditorAssembly.__globalsActivated">__globalsActivated</a></td>
 <td>Private method to jump to the line of the selected global entry and to populate the members combo box.</td>
 </tr><tr>
@@ -111,6 +114,16 @@
 <dd>
 reference to the task viewer object
 </dd>
+</dl><a NAME="EditorAssembly.__editorCursorLineChanged" ID="EditorAssembly.__editorCursorLineChanged"></a>
+<h4>EditorAssembly.__editorCursorLineChanged</h4>
+<b>__editorCursorLineChanged</b>(<i>lineno</i>)
+<p>
+        Private slot handling a line change of the cursor of the editor.
+</p><dl>
+<dt><i>lineno</i></dt>
+<dd>
+line number of the cursor (integer)
+</dd>
 </dl><a NAME="EditorAssembly.__globalsActivated" ID="EditorAssembly.__globalsActivated"></a>
 <h4>EditorAssembly.__globalsActivated</h4>
 <b>__globalsActivated</b>(<i>index, moveCursor=True</i>)
--- a/Documentation/Source/eric5.Utilities.ClassBrowsers.ClbrBaseClasses.html	Wed Jul 03 19:23:52 2013 +0200
+++ b/Documentation/Source/eric5.Utilities.ClassBrowsers.ClbrBaseClasses.html	Wed Jul 03 19:34:42 2013 +0200
@@ -594,6 +594,9 @@
 <tr>
 <td><a href="#_ClbrBase.__init__">_ClbrBase</a></td>
 <td>Constructor</td>
+</tr><tr>
+<td><a href="#_ClbrBase.setEndLine">setEndLine</a></td>
+<td>Public method to set the ending line number.</td>
 </tr>
 </table>
 <h3>Static Methods</h3>
@@ -619,6 +622,16 @@
 <dd>
 linenumber of the class definition
 </dd>
+</dl><a NAME="_ClbrBase.setEndLine" ID="_ClbrBase.setEndLine"></a>
+<h4>_ClbrBase.setEndLine</h4>
+<b>setEndLine</b>(<i>endLineNo</i>)
+<p>
+        Public method to set the ending line number.
+</p><dl>
+<dt><i>endLineNo</i></dt>
+<dd>
+number of the last line (integer)
+</dd>
 </dl>
 <div align="right"><a href="#top">Up</a></div>
 <hr />
--- a/Documentation/Source/eric5.Utilities.ModuleParser.html	Wed Jul 03 19:23:52 2013 +0200
+++ b/Documentation/Source/eric5.Utilities.ModuleParser.html	Wed Jul 03 19:34:42 2013 +0200
@@ -330,6 +330,9 @@
 </tr><tr>
 <td><a href="#Function.addDescription">addDescription</a></td>
 <td>Public method to store the functions docstring.</td>
+</tr><tr>
+<td><a href="#Function.setEndLine">setEndLine</a></td>
+<td>Public method to record the number of the last line of a class.</td>
 </tr>
 </table>
 <h3>Static Methods</h3>
@@ -374,6 +377,16 @@
 <dd>
 the docstring to be stored (string)
 </dd>
+</dl><a NAME="Function.setEndLine" ID="Function.setEndLine"></a>
+<h4>Function.setEndLine</h4>
+<b>setEndLine</b>(<i>endLineNo</i>)
+<p>
+        Public method to record the number of the last line of a class.
+</p><dl>
+<dt><i>endLineNo</i></dt>
+<dd>
+number of the last line (integer)
+</dd>
 </dl>
 <div align="right"><a href="#top">Up</a></div>
 <hr /><hr />
--- a/QScintilla/Editor.py	Wed Jul 03 19:23:52 2013 +0200
+++ b/QScintilla/Editor.py	Wed Jul 03 19:34:42 2013 +0200
@@ -41,6 +41,7 @@
     @signal redoAvailable(bool) emitted to signal the redo availability
     @signal cursorChanged(str, int, int) emitted when the cursor position
             was changed
+    @signal cursorLineChanged(int) emitted when the cursor line was changed
     @signal editorAboutToBeSaved(str) emitted before the editor is saved
     @signal editorSaved(str) emitted after the editor has been saved
     @signal editorRenamed(str) emitted after the editor got a new name
@@ -75,6 +76,7 @@
     undoAvailable = pyqtSignal(bool)
     redoAvailable = pyqtSignal(bool)
     cursorChanged = pyqtSignal(str, int, int)
+    cursorLineChanged = pyqtSignal(int)
     editorAboutToBeSaved = pyqtSignal(str)
     editorSaved = pyqtSignal(str)
     editorRenamed = pyqtSignal(str)
@@ -1578,6 +1580,9 @@
             self.__markOccurrencesTimer.stop()
             self.__markOccurrencesTimer.start()
         
+        if self.lastLine != line:
+            self.cursorLineChanged.emit(line)
+        
         if self.spell is not None:
             # do spell checking
             doSpelling = True
--- a/QScintilla/EditorAssembly.py	Wed Jul 03 19:23:52 2013 +0200
+++ b/QScintilla/EditorAssembly.py	Wed Jul 03 19:34:42 2013 +0200
@@ -50,6 +50,7 @@
         
         self.__globalsCombo.activated[int].connect(self.__globalsActivated)
         self.__membersCombo.activated[int].connect(self.__membersActivated)
+        self.__editor.cursorLineChanged.connect(self.__editorCursorLineChanged)
         
         self.__parseTimer = QTimer(self)
         self.__parseTimer.setSingleShot(True)
@@ -60,6 +61,8 @@
         
         self.__selectedGlobal = ""
         self.__selectedMember = ""
+        self.__globalsBoundaries = {}
+        self.__membersBoundaries = {}
         
         QTimer.singleShot(0, self.__parseEditor)
     
@@ -99,6 +102,9 @@
             
             # step 2: populate the members combo, if the entry is a class
             self.__membersCombo.clear()
+            self.__membersBoundaries = {}
+            self.__membersCombo.addItem("")
+            memberIndex = 0
             entryName = self.__globalsCombo.itemText(index)
             if self.__module:
                 if entryName in self.__module.classes:
@@ -114,10 +120,12 @@
                             icon = UI.PixmapCache.getIcon("class_protected.png")
                         else:
                             icon = UI.PixmapCache.getIcon("class.png")
-                        items[cl.name] = (icon, cl.lineno)
+                        items[cl.name] = (icon, cl.lineno, cl.endlineno)
                     for key in sorted(items.keys()):
                         itm = items[key]
                         self.__membersCombo.addItem(itm[0], key, itm[1])
+                        memberIndex += 1
+                        self.__membersBoundaries[(itm[1], itm[2])] = memberIndex
                 else:
                     return
                 
@@ -135,10 +143,12 @@
                         icon = UI.PixmapCache.getIcon("method_protected.png")
                     else:
                         icon = UI.PixmapCache.getIcon("method.png")
-                    items[meth.name] = (icon, meth.lineno)
+                    items[meth.name] = (icon, meth.lineno, meth.endlineno)
                 for key in sorted(items.keys()):
                     itm = items[key]
                     self.__membersCombo.addItem(itm[0], key, itm[1])
+                    memberIndex += 1
+                    self.__membersBoundaries[(itm[1], itm[2])] = memberIndex
                 
                 # step 2.2: add class instance attributes
                 items = {}
@@ -207,17 +217,22 @@
                 
                 self.__globalsCombo.clear()
                 self.__membersCombo.clear()
+                self.__globalsBoundaries = {}
+                self.__membersBoundaries = {}
                 
                 self.__globalsCombo.addItem("")
+                index = 0
                 
                 # step 1: add modules
                 items = {}
                 for module in self.__module.modules.values():
                     items[module.name] = (UI.PixmapCache.getIcon("module.png"),
-                                          module.lineno)
+                                          module.lineno, module.endlineno)
                 for key in sorted(items.keys()):
                     itm = items[key]
                     self.__globalsCombo.addItem(itm[0], key, itm[1])
+                    index += 1
+                    self.__globalsBoundaries[(itm[1], itm[2])] = index
                 
                 # step 2: add classes
                 items = {}
@@ -228,10 +243,12 @@
                         icon = UI.PixmapCache.getIcon("class_protected.png")
                     else:
                         icon = UI.PixmapCache.getIcon("class.png")
-                    items[cl.name] = (icon, cl.lineno)
+                    items[cl.name] = (icon, cl.lineno, cl.endlineno)
                 for key in sorted(items.keys()):
                     itm = items[key]
                     self.__globalsCombo.addItem(itm[0], key, itm[1])
+                    index += 1
+                    self.__globalsBoundaries[(itm[1], itm[2])] = index
                 
                 # step 3: add functions
                 items = {}
@@ -242,10 +259,12 @@
                         icon = UI.PixmapCache.getIcon("method_protected.png")
                     else:
                         icon = UI.PixmapCache.getIcon("method.png")
-                    items[func.name] = (icon, func.lineno)
+                    items[func.name] = (icon, func.lineno, func.endlineno)
                 for key in sorted(items.keys()):
                     itm = items[key]
                     self.__globalsCombo.addItem(itm[0], key, itm[1])
+                    index += 1
+                    self.__globalsBoundaries[(itm[1], itm[2])] = index
                 
                 # step 4: add attributes
                 items = {}
@@ -270,3 +289,33 @@
                 if index != -1:
                     self.__membersCombo.setCurrentIndex(index)
                     self.__membersActivated(index, moveCursor=False)
+    
+    def __editorCursorLineChanged(self, lineno):
+        """
+        Private slot handling a line change of the cursor of the editor.
+        
+        @param lineno line number of the cursor (integer)
+        """
+        lineno += 1     # cursor position is zero based, code info one based
+        
+        # step 1: search in the globals
+        for (lower, upper), index in self.__globalsBoundaries.items():
+            if upper == -1:
+                upper = 1000000     # it is the last line
+            if lower <= lineno <= upper:
+                break
+        else:
+            index = 0
+        self.__globalsCombo.setCurrentIndex(index)
+        self.__globalsActivated(index, moveCursor=False)
+        
+        # step 2: search in members
+        for (lower, upper), index in self.__membersBoundaries.items():
+            if upper == -1:
+                upper = 1000000     # it is the last line
+            if lower <= lineno <= upper:
+                break
+        else:
+            index = 0
+        self.__membersCombo.setCurrentIndex(index)
+        self.__membersActivated(index, moveCursor=False)
--- a/Utilities/ClassBrowsers/ClbrBaseClasses.py	Wed Jul 03 19:23:52 2013 +0200
+++ b/Utilities/ClassBrowsers/ClbrBaseClasses.py	Wed Jul 03 19:34:42 2013 +0200
@@ -25,6 +25,15 @@
         self.name = name
         self.file = file
         self.lineno = lineno
+        self.endlineno = -1     # marker for "not set"
+        
+    def setEndLine(self, endLineNo):
+        """
+        Public method to set the ending line number.
+        
+        @param endLineNo number of the last line (integer)
+        """
+        self.endlineno = endLineNo
 
 
 class ClbrBase(_ClbrBase):
@@ -121,7 +130,7 @@
         @param _class Class object to be added (Class)
         """
         self.classes[name] = _class
-        
+
 
 class ClbrVisibilityMixinBase(object):
     """
--- a/Utilities/ClassBrowsers/pyclbr.py	Wed Jul 03 19:23:52 2013 +0200
+++ b/Utilities/ClassBrowsers/pyclbr.py	Wed Jul 03 19:34:42 2013 +0200
@@ -320,6 +320,9 @@
             # close all classes indented at least as much
             while classstack and \
                   classstack[-1][1] >= thisindent:
+                if classstack[-1][0] is not None:
+                    # record the end line
+                    classstack[-1][0].setEndLine(lineno - 1)
                 del classstack[-1]
             if classstack:
                 # it's a class method
@@ -354,6 +357,9 @@
             # close all classes indented at least as much
             while classstack and \
                   classstack[-1][1] >= thisindent:
+                if classstack[-1][0] is not None:
+                    # record the end line
+                    classstack[-1][0].setEndLine(lineno - 1)
                 del classstack[-1]
             lineno = lineno + src.count('\n', last_lineno_pos, start)
             last_lineno_pos = start
--- a/Utilities/ModuleParser.py	Wed Jul 03 19:23:52 2013 +0200
+++ b/Utilities/ModuleParser.py	Wed Jul 03 19:34:42 2013 +0200
@@ -501,6 +501,7 @@
         @param src the source text to be scanned (string)
         """
         lineno, last_lineno_pos = 1, 0
+        lastGlobalEntry = None
         classstack = []  # stack of (class, indent) pairs
         conditionalsstack = []  # stack of indents of conditional defines
         deltastack = []
@@ -564,11 +565,9 @@
                 # close all classes indented at least as much
                 while classstack and \
                       classstack[-1][1] >= thisindent:
-                    if classstack[-1][1] == thisindent and \
-                       classstack[-1][0] is not None and \
-                       isinstance(classstack[-1][0], Class):
-                        # we got a class at the same indentation level;
-                        # record the end line of this class
+                    if classstack[-1][0] is not None and \
+                       isinstance(classstack[-1][0], (Class, Function)):
+                        # record the end line of this class or function
                         classstack[-1][0].setEndLine(lineno - 1)
                     del classstack[-1]
                 if classstack:
@@ -599,6 +598,12 @@
                                  meth_sig, meth_pyqtSig, modifierType=modifier)
                     self.__py_setVisibility(f)
                     self.addFunction(meth_name, f)
+                if not classstack:
+                    if lastGlobalEntry:
+                        lastGlobalEntry.setEndLine(lineno - 1)
+                    lastGlobalEntry = f
+                if cur_obj and isinstance(cur_obj, Function):
+                    cur_obj.setEndLine(lineno - 1)
                 cur_obj = f
                 classstack.append((None, thisindent))  # Marker for nested fns
                 
@@ -644,11 +649,9 @@
                 # close all classes indented at least as much
                 while classstack and \
                       classstack[-1][1] >= thisindent:
-                    if classstack[-1][1] == thisindent and \
-                       classstack[-1][0] is not None and \
-                       isinstance(classstack[-1][0], Class):
-                        # we got a class at the same indentation level;
-                        # record the end line of this class
+                    if classstack[-1][0] is not None and \
+                       isinstance(classstack[-1][0], (Class,  Function)):
+                        # record the end line of this class or function
                         classstack[-1][0].setEndLine(lineno - 1)
                     del classstack[-1]
                 class_name = m.group("ClassName")
@@ -684,6 +687,10 @@
                 cur_obj = cur_class
                 # add nested classes to the module
                 self.addClass(class_name, cur_class)
+                if not classstack:
+                    if lastGlobalEntry:
+                        lastGlobalEntry.setEndLine(lineno - 1)
+                    lastGlobalEntry = cur_class
                 classstack.append((cur_class, thisindent))
             
             elif m.start("Attribute") >= 0:
@@ -712,6 +719,9 @@
                                      isSignal=isSignal)
                     self.__py_setVisibility(attr)
                     self.addGlobal(variable_name, attr)
+                    if lastGlobalEntry:
+                        lastGlobalEntry.setEndLine(lineno - 1)
+                    lastGlobalEntry = None
                 else:
                     index = -1
                     while index >= -len(classstack):
@@ -772,6 +782,7 @@
         indent = 0
         i = 0
         cur_obj = self
+        lastGlobalEntry = None
         while True:
             m = self._getnext(src, i)
             if not m:
@@ -796,6 +807,10 @@
                 # close all classes/modules indented at least as much
                 while classstack and \
                       classstack[-1][1] >= thisindent:
+                    if classstack[-1][0] is not None and \
+                       isinstance(classstack[-1][0], (Class, Function, RbModule)):
+                        # record the end line of this class, function or module
+                        classstack[-1][0].setEndLine(lineno - 1)
                     del classstack[-1]
                 while acstack and \
                       acstack[-1][1] >= thisindent:
@@ -833,6 +848,12 @@
                     # it's a function
                     f = Function(self.name, meth_name, self.file, lineno, meth_sig)
                     self.addFunction(meth_name, f)
+                if not classstack:
+                    if lastGlobalEntry:
+                        lastGlobalEntry.setEndLine(lineno - 1)
+                    lastGlobalEntry = f
+                if cur_obj and isinstance(cur_obj, Function):
+                    cur_obj.setEndLine(lineno - 1)
                 cur_obj = f
                 classstack.append((None, thisindent))  # Marker for nested fns
             
@@ -856,12 +877,16 @@
                 # we found a class definition
                 thisindent = indent
                 indent += 1
+                lineno = lineno + src.count('\n', last_lineno_pos, start)
+                last_lineno_pos = start
                 # close all classes/modules indented at least as much
                 while classstack and \
                       classstack[-1][1] >= thisindent:
+                    if classstack[-1][0] is not None and \
+                       isinstance(classstack[-1][0], (Class, Function, RbModule)):
+                        # record the end line of this class, function or module
+                        classstack[-1][0].setEndLine(lineno - 1)
                     del classstack[-1]
-                lineno = lineno + src.count('\n', last_lineno_pos, start)
-                last_lineno_pos = start
                 class_name = m.group("ClassName") or m.group("ClassName2")
                 inherit = m.group("ClassSupers")
                 if inherit:
@@ -884,23 +909,32 @@
                     cur_class = classstack[-1][0]
                 else:
                     parent_obj.addClass(class_name, cur_class)
+                if not classstack:
+                    if lastGlobalEntry:
+                        lastGlobalEntry.setEndLine(lineno - 1)
+                    lastGlobalEntry = cur_class
                 cur_obj = cur_class
                 classstack.append((cur_class, thisindent))
                 while acstack and \
                       acstack[-1][1] >= thisindent:
                     del acstack[-1]
-                acstack.append(["public", thisindent])  # default access control is 'public'
+                acstack.append(["public", thisindent])
+                # default access control is 'public'
             
             elif m.start("Module") >= 0:
                 # we found a module definition
                 thisindent = indent
                 indent += 1
+                lineno = lineno + src.count('\n', last_lineno_pos, start)
+                last_lineno_pos = start
                 # close all classes/modules indented at least as much
                 while classstack and \
                       classstack[-1][1] >= thisindent:
+                    if classstack[-1][0] is not None and \
+                       isinstance(classstack[-1][0], (Class, Function, RbModule)):
+                        # record the end line of this class, function or module
+                        classstack[-1][0].setEndLine(lineno - 1)
                     del classstack[-1]
-                lineno = lineno + src.count('\n', last_lineno_pos, start)
-                last_lineno_pos = start
                 module_name = m.group("ModuleName")
                 # remember this class
                 cur_class = RbModule(self.name, module_name,
@@ -910,12 +944,17 @@
                     cur_class = self.modules[module_name]
                 else:
                     self.addModule(module_name, cur_class)
+                if not classstack:
+                    if lastGlobalEntry:
+                        lastGlobalEntry.setEndLine(lineno - 1)
+                    lastGlobalEntry = cur_class
                 cur_obj = cur_class
                 classstack.append((cur_class, thisindent))
                 while acstack and \
                       acstack[-1][1] >= thisindent:
                     del acstack[-1]
-                acstack.append(["public", thisindent])  # default access control is 'public'
+                acstack.append(["public", thisindent])
+                # default access control is 'public'
             
             elif m.start("AccessControl") >= 0:
                 aclist = m.group("AccessControlList")
@@ -976,6 +1015,9 @@
                     if attrName[0] != "@":
                         attr = Attribute(self.name, attrName, self.file, lineno)
                         self.addGlobal(attrName, attr)
+                    if lastGlobalEntry:
+                        lastGlobalEntry.setEndLine(lineno - 1)
+                    lastGlobalEntry = None
             
             elif m.start("Attr") >= 0:
                 lineno = lineno + src.count('\n', last_lineno_pos, start)
@@ -1290,6 +1332,7 @@
         self.name = name
         self.file = file
         self.lineno = lineno
+        self.endlineno = -1     # marker for "not set"
         signature = _commentsub('', signature)
         self.parameters = [e.strip() for e in signature.split(',')]
         self.description = ""
@@ -1304,6 +1347,14 @@
         @param description the docstring to be stored (string)
         """
         self.description = description
+    
+    def setEndLine(self, endLineNo):
+        """
+        Public method to record the number of the last line of a class.
+        
+        @param endLineNo number of the last line (integer)
+        """
+        self.endlineno = endLineNo
 
 
 class Attribute(VisibilityBase):
--- a/changelog	Wed Jul 03 19:23:52 2013 +0200
+++ b/changelog	Wed Jul 03 19:34:42 2013 +0200
@@ -26,6 +26,8 @@
      edit menu
   -- changed the line numbers margin to adjust themselves to the size needed
   -- added support for virtual space
+  -- added support to show the current class/method name in the combo boxes
+     at the top of the editor
 - Mini Editor
   -- changed the line numbers margin to adjust themselves to the size needed
   -- added support for virtual space

eric ide

mercurial