diff --git a/Lib/idlelib/codecontext.py b/Lib/idlelib/codecontext.py index 635f68c86e1..b061f3b2fe8 100644 --- a/Lib/idlelib/codecontext.py +++ b/Lib/idlelib/codecontext.py @@ -4,7 +4,7 @@ Once code has scrolled off the top of a window, it can be difficult to determine which block you are in. This extension implements a pane at the top of each IDLE edit window which provides block structure hints. These hints are the lines which contain the block opening keywords, e.g. 'if', for the -enclosing block. The number of hint lines is determined by the numlines +enclosing block. The number of hint lines is determined by the maxlines variable in the codecontext section of config-extensions.def. Lines which do not open blocks are not shown in the context hints pane. @@ -80,7 +80,7 @@ class CodeContext: def reload(cls): "Load class variables from config." cls.context_depth = idleConf.GetOption("extensions", "CodeContext", - "numlines", type="int", default=3) + "maxlines", type="int", default=15) ## cls.bgcolor = idleConf.GetOption("extensions", "CodeContext", ## "bgcolor", type="str", default="LightGray") ## cls.fgcolor = idleConf.GetOption("extensions", "CodeContext", @@ -116,7 +116,7 @@ class CodeContext: padx += widget.tk.getint(widget.cget('padx')) border += widget.tk.getint(widget.cget('border')) self.label = tkinter.Label( - self.editwin.top, text="\n" * (self.context_depth - 1), + self.editwin.top, text="", anchor=W, justify=LEFT, font=self.textfont, bg=self.bgcolor, fg=self.fgcolor, width=1, # Don't request more than we get. @@ -191,11 +191,10 @@ class CodeContext: stopindent) self.info.extend(lines) self.topvisible = new_topvisible - # Empty lines in context pane. - context_strings = [""] * max(0, self.context_depth - len(self.info)) - # Followed by the context hint lines. - context_strings += [x[2] for x in self.info[-self.context_depth:]] - self.label["text"] = '\n'.join(context_strings) + # Last context_depth context lines. + context_strings = [x[2] for x in self.info[-self.context_depth:]] + showfirst = 0 if context_strings[0] else 1 + self.label["text"] = '\n'.join(context_strings[showfirst:]) def timer_event(self): "Event on editor text widget triggered every UPDATEINTERVAL ms." diff --git a/Lib/idlelib/config-extensions.def b/Lib/idlelib/config-extensions.def index 8689fd965e8..7e23fb0a73d 100644 --- a/Lib/idlelib/config-extensions.def +++ b/Lib/idlelib/config-extensions.def @@ -7,10 +7,7 @@ popupwait= 2000 [CodeContext] -numlines= 3 -visible= False -bgcolor= LightGray -fgcolor= Black +maxlines= 15 [FormatParagraph] max-width= 72 diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 36ac4a23a52..28ad4586394 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -1843,7 +1843,7 @@ class GenPage(Frame): self.format_width = tracers.add( StringVar(self), ('extensions', 'FormatParagraph', 'max-width')) self.context_lines = tracers.add( - StringVar(self), ('extensions', 'CodeContext', 'numlines')) + StringVar(self), ('extensions', 'CodeContext', 'maxlines')) # Create widgets: # Section frames. @@ -1910,7 +1910,7 @@ class GenPage(Frame): frame_format, textvariable=self.format_width, width=4) frame_context = Frame(frame_editor, borderwidth=0) - context_title = Label(frame_context, text='Context Lines :') + context_title = Label(frame_context, text='Max Context Lines :') self.context_int = Entry( frame_context, textvariable=self.context_lines, width=3) @@ -2012,7 +2012,7 @@ class GenPage(Frame): self.format_width.set(idleConf.GetOption( 'extensions', 'FormatParagraph', 'max-width', type='int')) self.context_lines.set(idleConf.GetOption( - 'extensions', 'CodeContext', 'numlines', type='int')) + 'extensions', 'CodeContext', 'maxlines', type='int')) # Set additional help sources. self.user_helplist = idleConf.GetAllExtraHelpSourcesList() @@ -2204,6 +2204,9 @@ ParenMatch: Style indicates what is highlighted when closer is entered: 'opener' - opener '({[' corresponding to closer; 'parens' - both chars; 'expression' (default) - also everything in between. Flash-delay is how long to highlight if cursor is not moved (0 means forever). + +CodeContext: Maxlines is the maximum number of code context lines to +display when Code Context is turned on for an editor window. ''' } diff --git a/Lib/idlelib/idle_test/test_codecontext.py b/Lib/idlelib/idle_test/test_codecontext.py index ed45828641b..4c775eee6b5 100644 --- a/Lib/idlelib/idle_test/test_codecontext.py +++ b/Lib/idlelib/idle_test/test_codecontext.py @@ -110,7 +110,7 @@ class CodeContextTest(unittest.TestCase): def test_reload(self): codecontext.CodeContext.reload() - self.assertEqual(self.cc.context_depth, 3) + self.assertEqual(self.cc.context_depth, 15) def test_toggle_code_context_event(self): eq = self.assertEqual @@ -127,7 +127,7 @@ class CodeContextTest(unittest.TestCase): eq(cc.label['font'], cc.textfont) eq(cc.label['fg'], cc.fgcolor) eq(cc.label['bg'], cc.bgcolor) - eq(cc.label['text'], '\n' * 2) + eq(cc.label['text'], '') # Toggle off. eq(toggle(), 'break') @@ -193,24 +193,26 @@ class CodeContextTest(unittest.TestCase): eq(cc.info, [(0, -1, '', False)]) eq(cc.topvisible, 1) + # Scroll down to line 1. + cc.text.yview(1) + cc.update_code_context() + eq(cc.info, [(0, -1, '', False)]) + eq(cc.topvisible, 2) + eq(cc.label['text'], '') + # Scroll down to line 2. cc.text.yview(2) cc.update_code_context() eq(cc.info, [(0, -1, '', False), (2, 0, 'class C1():', 'class')]) eq(cc.topvisible, 3) - # context_depth is 3 so it pads with blank lines. - eq(cc.label['text'], '\n' - '\n' - 'class C1():') + eq(cc.label['text'], 'class C1():') # Scroll down to line 3. Since it's a comment, nothing changes. cc.text.yview(3) cc.update_code_context() eq(cc.info, [(0, -1, '', False), (2, 0, 'class C1():', 'class')]) eq(cc.topvisible, 4) - eq(cc.label['text'], '\n' - '\n' - 'class C1():') + eq(cc.label['text'], 'class C1():') # Scroll down to line 4. cc.text.yview(4) @@ -219,8 +221,7 @@ class CodeContextTest(unittest.TestCase): (2, 0, 'class C1():', 'class'), (4, 4, ' def __init__(self, a, b):', 'def')]) eq(cc.topvisible, 5) - eq(cc.label['text'], '\n' - 'class C1():\n' + eq(cc.label['text'], 'class C1():\n' ' def __init__(self, a, b):') # Scroll down to line 11. Last 'def' is removed. @@ -232,7 +233,8 @@ class CodeContextTest(unittest.TestCase): (8, 8, ' if a > b:', 'if'), (10, 8, ' elif a < b:', 'elif')]) eq(cc.topvisible, 12) - eq(cc.label['text'], ' def compare(self):\n' + eq(cc.label['text'], 'class C1():\n' + ' def compare(self):\n' ' if a > b:\n' ' elif a < b:') @@ -245,7 +247,8 @@ class CodeContextTest(unittest.TestCase): (8, 8, ' if a > b:', 'if'), (10, 8, ' elif a < b:', 'elif')]) eq(cc.topvisible, 12) - eq(cc.label['text'], ' def compare(self):\n' + eq(cc.label['text'], 'class C1():\n' + ' def compare(self):\n' ' if a > b:\n' ' elif a < b:') diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 982dc0b7eff..26aba32c47e 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -1170,7 +1170,7 @@ class GenPageTest(unittest.TestCase): def test_context(self): self.page.context_int.delete(0, 'end') self.page.context_int.insert(0, '1') - self.assertEqual(extpage, {'CodeContext': {'numlines': '1'}}) + self.assertEqual(extpage, {'CodeContext': {'maxlines': '1'}}) def test_source_selected(self): d = self.page diff --git a/Misc/NEWS.d/next/IDLE/2018-05-24-20-42-44.bpo-33642.J0VQbS.rst b/Misc/NEWS.d/next/IDLE/2018-05-24-20-42-44.bpo-33642.J0VQbS.rst new file mode 100644 index 00000000000..d8ecb3938d4 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-05-24-20-42-44.bpo-33642.J0VQbS.rst @@ -0,0 +1,9 @@ +IDLE: Only display actual code context lines. +Instead of displaying a fixed number of lines, some blank, Code Context +now displays the variable number of actual context lines. When there +are no context lines, it shows a single blank line to indicate that the +feature is turned on. + +The Code Context configuration option is changed from 'numlines' +(default 3) to 'maxlines' (default 15) to avoid possible interference +between user settings for the old and new versions of Code Context.