diff -r f27f594a96c3 Lib/idlelib/ScriptBinding.py --- a/Lib/idlelib/ScriptBinding.py Thu Mar 20 13:14:39 2014 +0000 +++ b/Lib/idlelib/ScriptBinding.py Sat Mar 22 21:23:36 2014 +0530 @@ -23,6 +23,7 @@ import tabnanny import tokenize import tkinter.messagebox as tkMessageBox +from tkinter import Toplevel, Label, Entry, Button from idlelib.EditorWindow import EditorWindow from idlelib import PyShell, IOBinding @@ -44,7 +45,9 @@ menudefs = [ ('run', [None, ('Check Module', '<>'), - ('Run Module', '<>'), ]), ] + ('Run Module', '<>'), + ('Command Line Arguments', '<>'), ]), ] + def __init__(self, editwin): self.editwin = editwin @@ -52,6 +55,7 @@ # XXX This should be done differently self.flist = self.editwin.flist self.root = self.editwin.root + self.arguments = '' if macosxSupport.runningAsOSXApp(): self.editwin.text_frame.bind('<>', self._run_module_event) @@ -154,11 +158,11 @@ from os.path import basename as _basename if (not _sys.argv or _basename(_sys.argv[0]) != _basename(__file__)): - _sys.argv = [__file__] + _sys.argv = [__file__] + {arguments!r} import os as _os _os.chdir({dirname!r}) del _sys, _basename, _os - \n""".format(filename=filename, dirname=dirname)) + \n""".format(filename=filename, dirname=dirname, arguments=self.parse_cmd_args())) 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. @@ -205,3 +209,55 @@ # XXX This should really be a function of EditorWindow... tkMessageBox.showerror(title, message, master=self.editwin.text) self.editwin.text.focus_set() + + def cmd_args_event(self, event): + def ok(event=None): + self.arguments = entry.get() + root.destroy() + + def cancel(event=None): + root.destroy() + + parent = self.editwin.text + root = Toplevel(master=parent) + root.geometry("%dx%d+%d+%d"%(350,50,parent.winfo_x()+200,parent.winfo_y()+200)) + root.title("Set command line arguments") + root.bind('', ok) + root.bind('', cancel) + label = Label(root, text="Command Line Arguments") + label.grid(row=0, column=0) + entry = Entry(root) + entry.grid(row=0, column=1) + entry.focus_set() + entry.insert(0, self.arguments) + ok = Button(root, text="Ok", command=ok) + ok.grid(row=1, column=1, stick='W') + cancel = Button(root, text="Cancel", command=cancel) + cancel.grid(row=1, column=1) + root.grab_set() + + def parse_cmd_args(self): + arg = [i for i in self.arguments.strip(' \t\n\r')] + in_single_quote = in_double_quote = False + + for i in range(len(arg)): + if arg[i] is '"' and not in_single_quote: + in_double_quote = not in_double_quote + if arg[i-1] is ' ': + arg[i] = '\n' + else: + arg[i] = '' + + if arg[i] == "'" and not in_double_quote: + in_single_quote = not in_single_quote + if arg[i-1] is ' ': + arg[i] = '\n' + else: + arg[i] = '' + + if not in_single_quote and not in_double_quote and arg[i] == ' ': + arg[i] = '\n' + + arg = ''.join(arg).split('\n') + arg = filter(None, arg) + return [i for i in arg] diff -r f27f594a96c3 Lib/idlelib/config-extensions.def --- a/Lib/idlelib/config-extensions.def Thu Mar 20 13:14:39 2014 +0000 +++ b/Lib/idlelib/config-extensions.def Sat Mar 22 21:23:36 2014 +0530 @@ -51,6 +51,7 @@ [ScriptBinding_cfgBindings] run-module= check-module= +cmd-args= [CallTips] enable=1 diff -r f27f594a96c3 Lib/idlelib/idle_test/mock_idle.py --- a/Lib/idlelib/idle_test/mock_idle.py Thu Mar 20 13:14:39 2014 +0000 +++ b/Lib/idlelib/idle_test/mock_idle.py Sat Mar 22 21:23:36 2014 +0530 @@ -11,6 +11,10 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.text = Text() self.undo = UndoDelegator() + self.flist = [] + self.root = '' + self.text_frame = text_frame() + def get_selection_indices(self): first = self.text.index('1.0') @@ -25,3 +29,9 @@ pass def undo_block_stop(*args): pass + +class text_frame: + '''Minimally immitate text_frame. Required for mock Editor. + ''' + def bind(self,event,meth): + pass diff -r f27f594a96c3 Lib/idlelib/idle_test/test_scriptbinding.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/idlelib/idle_test/test_scriptbinding.py Sat Mar 22 21:23:36 2014 +0530 @@ -0,0 +1,53 @@ +"""Unittest for idlelib.ScriptBinding""" +import unittest +from idlelib.ScriptBinding import ScriptBinding +from idlelib.idle_test.mock_idle import Editor + +class ScriptBindingTest(unittest.TestCase): + + def test_parse_cmd_args(self): + editwin = Editor() + sb = ScriptBinding(editwin) + parse = sb.parse_cmd_args + + sb.arguments = '' + self.assertEqual(parse(),[]) + + sb.arguments = '1' + self.assertEqual(parse(),['1']) + + sb.arguments = '1 2 3' + self.assertEqual(parse(),['1','2','3']) + + sb.arguments = '1 2 3 ' + self.assertEqual(parse(),['1', '2', '3']) + + sb.arguments = '1 2 34 --sum' + self.assertEqual(parse(),['1', '2', '34', '--sum']) + + sb.arguments = '1 \"2\' 3\'"' + self.assertEqual(parse(),['1', "2' 3'"]) + + sb.arguments = "1 2 3 foo='a'" + self.assertEqual(parse(),['1', '2', '3', 'foo=a']) + + sb.arguments = '1 2 3 foo="a"' + self.assertEqual(parse(),['1', '2', '3', 'foo=a']) + + sb.arguments = '1 2 3 foo=\"a\"' + self.assertEqual(parse(),['1', '2', '3', 'foo=a']) + + sb.arguments = '1 2 3 foo=\'a\'' + self.assertEqual(parse(),['1', '2', '3', 'foo=a']) + + sb.arguments = '1 2 3 \'foo=\'a\'\'' + self.assertEqual(parse(),['1', '2', '3', 'foo=a']) + + sb.arguments = '1 2 3 "foo=\'a\'"' + self.assertEqual(parse(),['1', '2', '3', "foo='a'"]) + + sb.arguments = '1 \'"2" "3"\'' + self.assertEqual(parse(),['1', '"2" "3"']) + +if __name__ == '__main__': + unittest.main(verbosity=2, exit=False)