Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
604e7b99
Commit
604e7b99
authored
Sep 25, 2018
by
Tal Einat
Committed by
GitHub
Sep 25, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-1529353: IDLE: squeeze large output in the shell (GH-7626)
parent
5b3cbcd4
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
974 additions
and
29 deletions
+974
-29
Lib/idlelib/config-main.def
Lib/idlelib/config-main.def
+3
-0
Lib/idlelib/configdialog.py
Lib/idlelib/configdialog.py
+35
-4
Lib/idlelib/editor.py
Lib/idlelib/editor.py
+4
-3
Lib/idlelib/idle_test/htest.py
Lib/idlelib/idle_test/htest.py
+1
-1
Lib/idlelib/idle_test/test_config.py
Lib/idlelib/idle_test/test_config.py
+3
-3
Lib/idlelib/idle_test/test_squeezer.py
Lib/idlelib/idle_test/test_squeezer.py
+509
-0
Lib/idlelib/idle_test/test_textview.py
Lib/idlelib/idle_test/test_textview.py
+5
-2
Lib/idlelib/pyshell.py
Lib/idlelib/pyshell.py
+4
-0
Lib/idlelib/squeezer.py
Lib/idlelib/squeezer.py
+355
-0
Lib/idlelib/textview.py
Lib/idlelib/textview.py
+52
-16
Misc/NEWS.d/next/IDLE/2018-08-13-16-31-24.bpo-1529353.wXfQJk.rst
...WS.d/next/IDLE/2018-08-13-16-31-24.bpo-1529353.wXfQJk.rst
+3
-0
No files found.
Lib/idlelib/config-main.def
View file @
604e7b99
...
...
@@ -66,6 +66,9 @@ font-size= 10
font-bold= 0
encoding= none
[PyShell]
auto-squeeze-min-lines= 50
[Indent]
use-spaces= 1
num-spaces= 4
...
...
Lib/idlelib/configdialog.py
View file @
604e7b99
...
...
@@ -30,10 +30,12 @@ from idlelib.autocomplete import AutoComplete
from
idlelib.codecontext
import
CodeContext
from
idlelib.parenmatch
import
ParenMatch
from
idlelib.paragraph
import
FormatParagraph
from
idlelib.squeezer
import
Squeezer
changes
=
ConfigChanges
()
# Reload changed options in the following classes.
reloadables
=
(
AutoComplete
,
CodeContext
,
ParenMatch
,
FormatParagraph
)
reloadables
=
(
AutoComplete
,
CodeContext
,
ParenMatch
,
FormatParagraph
,
Squeezer
)
class
ConfigDialog
(
Toplevel
):
...
...
@@ -1748,9 +1750,9 @@ class KeysPage(Frame):
self
.
customlist
.
SetMenu
(
item_list
,
item_list
[
0
])
# Revert to default key set.
self
.
keyset_source
.
set
(
idleConf
.
defaultCfg
[
'main'
]
.
Get
(
'Keys'
,
'default'
))
.
Get
(
'Keys'
,
'default'
))
self
.
builtin_name
.
set
(
idleConf
.
defaultCfg
[
'main'
].
Get
(
'Keys'
,
'name'
)
or
idleConf
.
default_keys
())
or
idleConf
.
default_keys
())
# User can't back out of these changes, they must be applied now.
changes
.
save_all
()
self
.
cd
.
save_all_changed_extensions
()
...
...
@@ -1817,6 +1819,10 @@ class GenPage(Frame):
frame_context: Frame
context_title: Label
(*)context_int: Entry - context_lines
frame_shell: LabelFrame
frame_auto_squeeze_min_lines: Frame
auto_squeeze_min_lines_title: Label
(*)auto_squeeze_min_lines_int: Entry - auto_squeeze_min_lines
frame_help: LabelFrame
frame_helplist: Frame
frame_helplist_buttons: Frame
...
...
@@ -1842,6 +1848,9 @@ class GenPage(Frame):
self
.
paren_bell
=
tracers
.
add
(
BooleanVar
(
self
),
(
'extensions'
,
'ParenMatch'
,
'bell'
))
self
.
auto_squeeze_min_lines
=
tracers
.
add
(
StringVar
(
self
),
(
'main'
,
'PyShell'
,
'auto-squeeze-min-lines'
))
self
.
autosave
=
tracers
.
add
(
IntVar
(
self
),
(
'main'
,
'General'
,
'autosave'
))
self
.
format_width
=
tracers
.
add
(
...
...
@@ -1855,8 +1864,10 @@ class GenPage(Frame):
text
=
' Window Preferences'
)
frame_editor
=
LabelFrame
(
self
,
borderwidth
=
2
,
relief
=
GROOVE
,
text
=
' Editor Preferences'
)
frame_shell
=
LabelFrame
(
self
,
borderwidth
=
2
,
relief
=
GROOVE
,
text
=
' Shell Preferences'
)
frame_help
=
LabelFrame
(
self
,
borderwidth
=
2
,
relief
=
GROOVE
,
text
=
' Additional Help Sources '
)
text
=
' Additional Help Sources '
)
# Frame_window.
frame_run
=
Frame
(
frame_window
,
borderwidth
=
0
)
startup_title
=
Label
(
frame_run
,
text
=
'At Startup'
)
...
...
@@ -1918,6 +1929,13 @@ class GenPage(Frame):
self
.
context_int
=
Entry
(
frame_context
,
textvariable
=
self
.
context_lines
,
width
=
3
)
# Frame_shell.
frame_auto_squeeze_min_lines
=
Frame
(
frame_shell
,
borderwidth
=
0
)
auto_squeeze_min_lines_title
=
Label
(
frame_auto_squeeze_min_lines
,
text
=
'Auto-Squeeze Min. Lines:'
)
self
.
auto_squeeze_min_lines_int
=
Entry
(
frame_auto_squeeze_min_lines
,
width
=
4
,
textvariable
=
self
.
auto_squeeze_min_lines
)
# frame_help.
frame_helplist
=
Frame
(
frame_help
)
...
...
@@ -1943,6 +1961,7 @@ class GenPage(Frame):
# Body.
frame_window
.
pack
(
side
=
TOP
,
padx
=
5
,
pady
=
5
,
expand
=
TRUE
,
fill
=
BOTH
)
frame_editor
.
pack
(
side
=
TOP
,
padx
=
5
,
pady
=
5
,
expand
=
TRUE
,
fill
=
BOTH
)
frame_shell
.
pack
(
side
=
TOP
,
padx
=
5
,
pady
=
5
,
expand
=
TRUE
,
fill
=
BOTH
)
frame_help
.
pack
(
side
=
TOP
,
padx
=
5
,
pady
=
5
,
expand
=
TRUE
,
fill
=
BOTH
)
# frame_run.
frame_run
.
pack
(
side
=
TOP
,
padx
=
5
,
pady
=
0
,
fill
=
X
)
...
...
@@ -1983,6 +2002,11 @@ class GenPage(Frame):
context_title
.
pack
(
side
=
LEFT
,
anchor
=
W
,
padx
=
5
,
pady
=
5
)
self
.
context_int
.
pack
(
side
=
TOP
,
padx
=
5
,
pady
=
5
)
# frame_auto_squeeze_min_lines
frame_auto_squeeze_min_lines
.
pack
(
side
=
TOP
,
padx
=
5
,
pady
=
0
,
fill
=
X
)
auto_squeeze_min_lines_title
.
pack
(
side
=
LEFT
,
anchor
=
W
,
padx
=
5
,
pady
=
5
)
self
.
auto_squeeze_min_lines_int
.
pack
(
side
=
TOP
,
padx
=
5
,
pady
=
5
)
# frame_help.
frame_helplist_buttons
.
pack
(
side
=
RIGHT
,
padx
=
5
,
pady
=
5
,
fill
=
Y
)
frame_helplist
.
pack
(
side
=
TOP
,
padx
=
5
,
pady
=
5
,
expand
=
TRUE
,
fill
=
BOTH
)
...
...
@@ -2018,6 +2042,10 @@ class GenPage(Frame):
self
.
context_lines
.
set
(
idleConf
.
GetOption
(
'extensions'
,
'CodeContext'
,
'maxlines'
,
type
=
'int'
))
# Set variables for shell windows.
self
.
auto_squeeze_min_lines
.
set
(
idleConf
.
GetOption
(
'main'
,
'PyShell'
,
'auto-squeeze-min-lines'
,
type
=
'int'
))
# Set additional help sources.
self
.
user_helplist
=
idleConf
.
GetAllExtraHelpSourcesList
()
self
.
helplist
.
delete
(
0
,
'end'
)
...
...
@@ -2211,6 +2239,9 @@ 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.
Shell Preferences: Auto-Squeeze Min. Lines is the minimum number of lines
of output to automatically "squeeze".
'''
}
...
...
Lib/idlelib/editor.py
View file @
604e7b99
...
...
@@ -2,9 +2,7 @@ import importlib.abc
import
importlib.util
import
os
import
platform
import
re
import
string
import
sys
import
tokenize
import
traceback
import
webbrowser
...
...
@@ -50,7 +48,6 @@ class EditorWindow(object):
from
idlelib.undo
import
UndoDelegator
from
idlelib.iomenu
import
IOBinding
,
encoding
from
idlelib
import
mainmenu
from
tkinter
import
Toplevel
,
EventType
from
idlelib.statusbar
import
MultiStatusBar
from
idlelib.autocomplete
import
AutoComplete
from
idlelib.autoexpand
import
AutoExpand
...
...
@@ -59,6 +56,7 @@ class EditorWindow(object):
from
idlelib.paragraph
import
FormatParagraph
from
idlelib.parenmatch
import
ParenMatch
from
idlelib.rstrip
import
Rstrip
from
idlelib.squeezer
import
Squeezer
from
idlelib.zoomheight
import
ZoomHeight
filesystemencoding
=
sys
.
getfilesystemencoding
()
# for file names
...
...
@@ -319,6 +317,9 @@ class EditorWindow(object):
text
.
bind
(
"<<zoom-height>>"
,
self
.
ZoomHeight
(
self
).
zoom_height_event
)
text
.
bind
(
"<<toggle-code-context>>"
,
self
.
CodeContext
(
self
).
toggle_code_context_event
)
squeezer
=
self
.
Squeezer
(
self
)
text
.
bind
(
"<<squeeze-current-text>>"
,
squeezer
.
squeeze_current_text_event
)
def
_filename_to_unicode
(
self
,
filename
):
"""Return filename as BMP unicode so diplayable in Tk."""
...
...
Lib/idlelib/idle_test/htest.py
View file @
604e7b99
...
...
@@ -163,7 +163,7 @@ _grep_dialog_spec = {
'msg'
:
"Click the 'Show GrepDialog' button.
\
n
"
"Test the various 'Find-in-files' functions.
\
n
"
"The results should be displayed in a new '*Output*' window.
\
n
"
"'Right-click'->'Goto file/line' anywhere in the search results "
"'Right-click'->'Go
to file/line' anywhere in the search results "
"should open that file
\
n
in a new EditorWindow."
}
...
...
Lib/idlelib/idle_test/test_config.py
View file @
604e7b99
...
...
@@ -356,11 +356,11 @@ class IdleConfTest(unittest.TestCase):
self
.
assertCountEqual
(
conf
.
GetSectionList
(
'default'
,
'main'
),
[
'General'
,
'EditorWindow'
,
'Indent'
,
'Theme'
,
[
'General'
,
'EditorWindow'
,
'
PyShell'
,
'
Indent'
,
'Theme'
,
'Keys'
,
'History'
,
'HelpFiles'
])
self
.
assertCountEqual
(
conf
.
GetSectionList
(
'user'
,
'main'
),
[
'General'
,
'EditorWindow'
,
'Indent'
,
'Theme'
,
[
'General'
,
'EditorWindow'
,
'
PyShell'
,
'
Indent'
,
'Theme'
,
'Keys'
,
'History'
,
'HelpFiles'
])
with
self
.
assertRaises
(
config
.
InvalidConfigSet
):
...
...
@@ -452,7 +452,7 @@ class IdleConfTest(unittest.TestCase):
self
.
assertCountEqual
(
conf
.
RemoveKeyBindNames
(
conf
.
GetSectionList
(
'default'
,
'extensions'
)),
[
'AutoComplete'
,
'CodeContext'
,
'FormatParagraph'
,
'ParenMatch'
,
'ZzDummy'
])
[
'AutoComplete'
,
'CodeContext'
,
'FormatParagraph'
,
'ParenMatch'
,
'ZzDummy'
])
def
test_get_extn_name_for_event
(
self
):
userextn
.
read_string
(
'''
...
...
Lib/idlelib/idle_test/test_squeezer.py
0 → 100644
View file @
604e7b99
This diff is collapsed.
Click to expand it.
Lib/idlelib/idle_test/test_textview.py
View file @
604e7b99
...
...
@@ -73,7 +73,6 @@ class TextFrameTest(unittest.TestCase):
@
classmethod
def
setUpClass
(
cls
):
"By itself, this tests that file parsed without exception."
cls
.
root
=
root
=
Tk
()
root
.
withdraw
()
cls
.
frame
=
tv
.
TextFrame
(
root
,
'test text'
)
...
...
@@ -126,11 +125,15 @@ class ViewFunctionTest(unittest.TestCase):
def
test_bad_encoding
(
self
):
p
=
os
.
path
fn
=
p
.
abspath
(
p
.
join
(
p
.
dirname
(
__file__
),
'..'
,
'CREDITS.txt'
))
tv
.
showerror
.
title
=
None
view
=
tv
.
view_file
(
root
,
'Title'
,
fn
,
'ascii'
,
modal
=
False
)
self
.
assertIsNone
(
view
)
self
.
assertEqual
(
tv
.
showerror
.
title
,
'Unicode Decode Error'
)
def
test_nowrap
(
self
):
view
=
tv
.
view_text
(
root
,
'Title'
,
'test'
,
modal
=
False
,
wrap
=
'none'
)
text_widget
=
view
.
viewframe
.
textframe
.
text
self
.
assertEqual
(
text_widget
.
cget
(
'wrap'
),
'none'
)
# Call ViewWindow with _utest=True.
class
ButtonClickTest
(
unittest
.
TestCase
):
...
...
Lib/idlelib/pyshell.py
View file @
604e7b99
...
...
@@ -856,6 +856,10 @@ class PyShell(OutputWindow):
(
"help"
,
"_Help"
),
]
# Extend right-click context menu
rmenu_specs
=
OutputWindow
.
rmenu_specs
+
[
(
"Squeeze"
,
"<<squeeze-current-text>>"
),
]
# New classes
from
idlelib.history
import
History
...
...
Lib/idlelib/squeezer.py
0 → 100644
View file @
604e7b99
This diff is collapsed.
Click to expand it.
Lib/idlelib/textview.py
View file @
604e7b99
"""Simple text browser for IDLE
"""
from
tkinter
import
Toplevel
,
Text
from
tkinter
import
Toplevel
,
Text
,
TclError
,
\
HORIZONTAL
,
VERTICAL
,
N
,
S
,
E
,
W
from
tkinter.ttk
import
Frame
,
Scrollbar
,
Button
from
tkinter.messagebox
import
showerror
from
idlelib.colorizer
import
color_config
class
AutoHiddenScrollbar
(
Scrollbar
):
"""A scrollbar that is automatically hidden when not needed.
Only the grid geometry manager is supported.
"""
def
set
(
self
,
lo
,
hi
):
if
float
(
lo
)
>
0.0
or
float
(
hi
)
<
1.0
:
self
.
grid
()
else
:
self
.
grid_remove
()
super
().
set
(
lo
,
hi
)
def
pack
(
self
,
**
kwargs
):
raise
TclError
(
f'
{
self
.
__class__
.
__name__
}
does not support "pack"'
)
def
place
(
self
,
**
kwargs
):
raise
TclError
(
f'
{
self
.
__class__
.
__name__
}
does not support "place"'
)
class
TextFrame
(
Frame
):
"Display text with scrollbar."
def
__init__
(
self
,
parent
,
rawtext
):
def
__init__
(
self
,
parent
,
rawtext
,
wrap
=
'word'
):
"""Create a frame for Textview.
parent - parent widget for this frame
...
...
@@ -21,27 +41,39 @@ class TextFrame(Frame):
self
[
'relief'
]
=
'sunken'
self
[
'height'
]
=
700
self
.
text
=
text
=
Text
(
self
,
wrap
=
'word'
,
highlightthickness
=
0
)
self
.
text
=
text
=
Text
(
self
,
wrap
=
wrap
,
highlightthickness
=
0
)
color_config
(
text
)
self
.
scroll
=
scroll
=
Scrollbar
(
self
,
orient
=
'vertical'
,
takefocus
=
False
,
command
=
text
.
yview
)
text
[
'yscrollcommand'
]
=
scroll
.
set
text
.
grid
(
row
=
0
,
column
=
0
,
sticky
=
N
+
S
+
E
+
W
)
self
.
grid_rowconfigure
(
0
,
weight
=
1
)
self
.
grid_columnconfigure
(
0
,
weight
=
1
)
text
.
insert
(
0.0
,
rawtext
)
text
[
'state'
]
=
'disabled'
text
.
focus_set
()
scroll
.
pack
(
side
=
'right'
,
fill
=
'y'
)
text
.
pack
(
side
=
'left'
,
expand
=
True
,
fill
=
'both'
)
# vertical scrollbar
self
.
yscroll
=
yscroll
=
AutoHiddenScrollbar
(
self
,
orient
=
VERTICAL
,
takefocus
=
False
,
command
=
text
.
yview
)
text
[
'yscrollcommand'
]
=
yscroll
.
set
yscroll
.
grid
(
row
=
0
,
column
=
1
,
sticky
=
N
+
S
)
if
wrap
==
'none'
:
# horizontal scrollbar
self
.
xscroll
=
xscroll
=
AutoHiddenScrollbar
(
self
,
orient
=
HORIZONTAL
,
takefocus
=
False
,
command
=
text
.
xview
)
text
[
'xscrollcommand'
]
=
xscroll
.
set
xscroll
.
grid
(
row
=
1
,
column
=
0
,
sticky
=
E
+
W
)
class
ViewFrame
(
Frame
):
"Display TextFrame and Close button."
def
__init__
(
self
,
parent
,
text
):
def
__init__
(
self
,
parent
,
text
,
wrap
=
'word'
):
super
().
__init__
(
parent
)
self
.
parent
=
parent
self
.
bind
(
'<Return>'
,
self
.
ok
)
self
.
bind
(
'<Escape>'
,
self
.
ok
)
self
.
textframe
=
TextFrame
(
self
,
text
)
self
.
textframe
=
TextFrame
(
self
,
text
,
wrap
=
wrap
)
self
.
button_ok
=
button_ok
=
Button
(
self
,
text
=
'Close'
,
command
=
self
.
ok
,
takefocus
=
False
)
self
.
textframe
.
pack
(
side
=
'top'
,
expand
=
True
,
fill
=
'both'
)
...
...
@@ -55,7 +87,7 @@ class ViewFrame(Frame):
class
ViewWindow
(
Toplevel
):
"A simple text viewer dialog for IDLE."
def
__init__
(
self
,
parent
,
title
,
text
,
modal
=
True
,
def
__init__
(
self
,
parent
,
title
,
text
,
modal
=
True
,
wrap
=
'word'
,
*
,
_htest
=
False
,
_utest
=
False
):
"""Show the given text in a scrollable window with a 'close' button.
...
...
@@ -65,6 +97,7 @@ class ViewWindow(Toplevel):
parent - parent of this dialog
title - string which is title of popup dialog
text - text to display in dialog
wrap - type of text wrapping to use ('word', 'char' or 'none')
_htest - bool; change box location when running htest.
_utest - bool; don't wait_window when running unittest.
"""
...
...
@@ -76,7 +109,7 @@ class ViewWindow(Toplevel):
self
.
geometry
(
f'=750x500+
{
x
}
+
{
y
}
'
)
self
.
title
(
title
)
self
.
viewframe
=
ViewFrame
(
self
,
text
)
self
.
viewframe
=
ViewFrame
(
self
,
text
,
wrap
=
wrap
)
self
.
protocol
(
"WM_DELETE_WINDOW"
,
self
.
ok
)
self
.
button_ok
=
button_ok
=
Button
(
self
,
text
=
'Close'
,
command
=
self
.
ok
,
takefocus
=
False
)
...
...
@@ -96,20 +129,22 @@ class ViewWindow(Toplevel):
self
.
destroy
()
def
view_text
(
parent
,
title
,
text
,
modal
=
True
,
_utest
=
False
):
def
view_text
(
parent
,
title
,
text
,
modal
=
True
,
wrap
=
'word'
,
_utest
=
False
):
"""Create text viewer for given text.
parent - parent of this dialog
title - string which is the title of popup dialog
text - text to display in this dialog
wrap - type of text wrapping to use ('word', 'char' or 'none')
modal - controls if users can interact with other windows while this
dialog is displayed
_utest - bool; controls wait_window on unittest
"""
return
ViewWindow
(
parent
,
title
,
text
,
modal
,
_utest
=
_utest
)
return
ViewWindow
(
parent
,
title
,
text
,
modal
,
wrap
=
wrap
,
_utest
=
_utest
)
def
view_file
(
parent
,
title
,
filename
,
encoding
,
modal
=
True
,
_utest
=
False
):
def
view_file
(
parent
,
title
,
filename
,
encoding
,
modal
=
True
,
wrap
=
'word'
,
_utest
=
False
):
"""Create text viewer for text in filename.
Return error message if file cannot be read. Otherwise calls view_text
...
...
@@ -127,7 +162,8 @@ def view_file(parent, title, filename, encoding, modal=True, _utest=False):
message
=
str
(
err
),
parent
=
parent
)
else
:
return
view_text
(
parent
,
title
,
contents
,
modal
,
_utest
=
_utest
)
return
view_text
(
parent
,
title
,
contents
,
modal
,
wrap
=
wrap
,
_utest
=
_utest
)
return
None
...
...
Misc/NEWS.d/next/IDLE/2018-08-13-16-31-24.bpo-1529353.wXfQJk.rst
0 → 100644
View file @
604e7b99
Enable "squeezing" of long outputs in the shell, to avoid performance
degradation and to clean up the history without losing it. Squeezed outputs
may be copied, viewed in a separate window, and "unsqueezed".
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment