Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Lib/idlelib/config-extensions.def
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ enable_shell=False
enable_editor=True
[ScriptBinding_cfgBindings]
run-module=<Key-F5>
run-module-arguments=<Key-F7>
check-module=<Alt-Key-x>

[ZoomHeight]
Expand Down
91 changes: 84 additions & 7 deletions Lib/idlelib/runscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import tokenize

import tkinter.messagebox as tkMessageBox
from tkinter import Frame, Button, Label, Entry, Toplevel
from tkinter import TOP, TRUE, FALSE, BOTH, LEFT, BOTTOM

from idlelib.config import idleConf
from idlelib import macosx
Expand All @@ -38,12 +40,78 @@
"""


class ArgumentsInputBox(Toplevel):

def __init__(self, parent, title, _htest=False):
"""
_htest - bool, change box location when running htest
"""
Toplevel.__init__(self, parent)
self.parent = parent
self.title(title)
self.resizable(height=False, width=True)
self.grab_set()
self.protocol("WM_DELETE_WINDOW", self.cancel)

self.geometry(
"+%d+%d" % (parent.winfo_rootx() + parent.winfo_width() / 2 - 150,
parent.winfo_rooty() + (30 if not _htest else 150)))
self.minsize(width=300, height=50)

def set_callback(self, callback):
self.callback = callback

def show_input_box(self):
self.create_input_box()
self.create_action_buttons().pack(side=BOTTOM)

def create_input_box(self):
self.frameMain = frameMain = Frame(self)
frameMain.pack(side=TOP, expand=TRUE, fill=BOTH)

self.label = label = Label(frameMain, text="Command-line arguments: ")
label.pack(expand=TRUE, fill=BOTH)

self.entry = entry = Entry(frameMain)
entry.bind("<Return>", lambda event: self.run())
entry.pack(expand=TRUE, fill=BOTH)
entry.focus_set()

def create_action_buttons(self):
if macosx.isAquaTk():
# Changing the default padding on OSX results in unreadable
# text in the buttons
paddingArgs = {}
else:
paddingArgs = {'padx': 6, 'pady': 3}
outer = Frame(self, pady=2)
buttons = Frame(outer, pady=2)
for txt, cmd in (
('Run', self.run),
('Cancel', self.cancel)):
Button(buttons, text=txt, command=cmd, takefocus=FALSE,
**paddingArgs).pack(side=LEFT, padx=5)
# add space above buttons
Frame(outer, height=2, borderwidth=0).pack(side=TOP)
buttons.pack(side=BOTTOM)
return outer

def run(self):
args = self.entry.get()
self.destroy()
self.callback(None, args)

def cancel(self):
self.destroy()


class ScriptBinding:

menudefs = [
('run', [None,
('Check Module', '<<check-module>>'),
('Run Module', '<<run-module>>'), ]), ]
('Run Module', '<<run-module>>'),
('Run Module with Arguments', '<<run-module-arguments>>'), ]), ]

def __init__(self, editwin):
self.editwin = editwin
Expand All @@ -55,6 +123,11 @@ def __init__(self, editwin):
if macosx.isCocoaTk():
self.editwin.text_frame.bind('<<run-module-event-2>>', self._run_module_event)

def run_module_arguments_event(self, event):
aw = ArgumentsInputBox(event.widget, 'Run with arguments')
aw.set_callback(self.run_module_event)
aw.show_input_box()

def check_module_event(self, event):
filename = self.getfilename()
if not filename:
Expand Down Expand Up @@ -112,7 +185,7 @@ def checksyntax(self, filename):
finally:
shell.set_warning_stream(saved_stream)

def run_module_event(self, event):
def run_module_event(self, event, args=None):
if macosx.isCocoaTk():
# Tk-Cocoa in MacOSX is broken until at least
# Tk 8.5.9, and without this rather
Expand All @@ -123,9 +196,9 @@ def run_module_event(self, event):
lambda: self.editwin.text_frame.event_generate('<<run-module-event-2>>'))
return 'break'
else:
return self._run_module_event(event)
return self._run_module_event(event, args)

def _run_module_event(self, event):
def _run_module_event(self, event, args=None):
"""Run the module after setting up the environment.

First check the syntax. If OK, make sure the shell is active and
Expand All @@ -148,7 +221,7 @@ def _run_module_event(self, event):
self.editwin._filename_to_unicode(filename))
dirname = os.path.dirname(filename)
# XXX Too often this discards arguments the user just set...
interp.runcommand("""if 1:
command = """if 1:
__file__ = {filename!r}
import sys as _sys
from os.path import basename as _basename
Expand All @@ -157,8 +230,12 @@ def _run_module_event(self, event):
_sys.argv = [__file__]
import os as _os
_os.chdir({dirname!r})
del _sys, _basename, _os
\n""".format(filename=filename, dirname=dirname))
\n""".format(filename=filename, dirname=dirname)
if args:
for arg in args.split():
command += '_sys.argv.append({arg})\n'.format(arg=repr(arg))
command += 'del _sys, _basename, _os\n'
interp.runcommand(command)
interp.prepend_syspath(filename)
# XXX KBK 03Jul04 When run w/o subprocess, runtime warnings still
# go to __stderr__. With subprocess, they go to the shell.
Expand Down