Mercurial > cpython-lru_cache-weakref
annotate Lib/idlelib/ScriptBinding.py @ 27998:e27f58a50737 legacy-trunk
SF bug #690377: Dud footnote reference in distutils docs
| author | Raymond Hettinger <python@rcn.com> |
|---|---|
| date | Fri, 21 Feb 2003 02:47:09 +0000 |
| parents | 8e7432cdf7d8 |
| children | 7875fcaae7a3 |
| rev | line source |
|---|---|
| 13975 | 1 """Extension to execute code outside the Python shell window. |
| 2 | |
|
23784
24b0f6d693e3
Rework the code to have only the GvR RPC. Output from execution of user
Kurt B. Kaiser <kbk@shore.net>
parents:
23547
diff
changeset
|
3 This adds the following commands: |
| 13975 | 4 |
|
23784
24b0f6d693e3
Rework the code to have only the GvR RPC. Output from execution of user
Kurt B. Kaiser <kbk@shore.net>
parents:
23547
diff
changeset
|
5 - Check module does a full syntax check of the current module. |
| 26693 | 6 It also runs the tabnanny to catch any inconsistent tabs. |
| 13975 | 7 |
| 25123 | 8 - Run module executes the module's code in the __main__ namespace. The window |
| 26693 | 9 must have been saved previously. The module is added to sys.modules, and is |
| 10 also added to the __main__ namespace. | |
| 13975 | 11 |
| 26693 | 12 XXX GvR Redesign this interface (yet again) as follows: |
| 23547 | 13 |
| 27390 | 14 - Present a dialog box for ``Run Module'' |
| 23547 | 15 |
| 16 - Allow specify command line arguments in the dialog box | |
| 17 | |
| 13975 | 18 """ |
| 19 | |
| 26693 | 20 import re |
| 21 import string | |
| 22 import tabnanny | |
| 23 import tokenize | |
| 13975 | 24 import tkMessageBox |
| 25 | |
| 26693 | 26 IDENTCHARS = string.ascii_letters + string.digits + "_" |
| 27 | |
| 13975 | 28 indent_message = """Error: Inconsistent indentation detected! |
| 29 | |
| 30 This means that either: | |
| 31 | |
| 23547 | 32 1) your indentation is outright incorrect (easy to fix), or |
| 13975 | 33 |
| 23547 | 34 2) your indentation mixes tabs and spaces in a way that depends on \ |
| 13975 | 35 how many spaces a tab is worth. |
| 36 | |
| 37 To fix case 2, change all tabs to spaces by using Select All followed \ | |
| 38 by Untabify Region (both in the Edit menu).""" | |
| 39 | |
|
23784
24b0f6d693e3
Rework the code to have only the GvR RPC. Output from execution of user
Kurt B. Kaiser <kbk@shore.net>
parents:
23547
diff
changeset
|
40 |
| 26693 | 41 # XXX 11Jun02 KBK TBD Implement stop-execution |
| 42 | |
| 13975 | 43 class ScriptBinding: |
|
18497
42741e677338
py-cvs merge, better error dialog
Steven M. Gava <elguavas@python.net>
parents:
13975
diff
changeset
|
44 |
| 13975 | 45 menudefs = [ |
|
23784
24b0f6d693e3
Rework the code to have only the GvR RPC. Output from execution of user
Kurt B. Kaiser <kbk@shore.net>
parents:
23547
diff
changeset
|
46 ('run', [None, |
| 26693 | 47 ('Check Module', '<<check-module>>'), |
| 27390 | 48 ('Run Module', '<<run-module>>'), ]), ] |
| 13975 | 49 |
| 50 def __init__(self, editwin): | |
| 51 self.editwin = editwin | |
| 52 # Provide instance variables referenced by Debugger | |
| 53 # XXX This should be done differently | |
| 54 self.flist = self.editwin.flist | |
| 55 self.root = self.flist.root | |
| 56 | |
| 57 def check_module_event(self, event): | |
| 58 filename = self.getfilename() | |
| 59 if not filename: | |
| 60 return | |
| 61 if not self.tabnanny(filename): | |
| 62 return | |
| 26693 | 63 self.checksyntax(filename) |
| 13975 | 64 |
| 65 def tabnanny(self, filename): | |
| 66 f = open(filename, 'r') | |
| 67 try: | |
| 25312 | 68 tabnanny.process_tokens(tokenize.generate_tokens(f.readline)) |
| 13975 | 69 except tokenize.TokenError, msg: |
| 26475 | 70 self.errorbox("Token error", "Token error:\n%s" % msg) |
| 71 return False | |
| 13975 | 72 except tabnanny.NannyNag, nag: |
| 73 # The error messages from tabnanny are too confusing... | |
| 74 self.editwin.gotoline(nag.get_lineno()) | |
| 75 self.errorbox("Tab/space error", indent_message) | |
| 26475 | 76 return False |
| 77 return True | |
| 13975 | 78 |
| 79 def checksyntax(self, filename): | |
| 80 f = open(filename, 'r') | |
| 81 source = f.read() | |
| 82 f.close() | |
| 83 if '\r' in source: | |
| 84 source = re.sub(r"\r\n", "\n", source) | |
| 85 if source and source[-1] != '\n': | |
| 86 source = source + '\n' | |
| 87 try: | |
| 26693 | 88 # If successful, return the compiled code |
| 89 return compile(source, filename, "exec") | |
| 13975 | 90 except (SyntaxError, OverflowError), err: |
| 91 try: | |
| 92 msg, (errorfilename, lineno, offset, line) = err | |
| 93 if not errorfilename: | |
| 94 err.args = msg, (filename, lineno, offset, line) | |
| 95 err.filename = filename | |
| 26693 | 96 self.colorize_syntax_error(msg, lineno, offset) |
| 13975 | 97 except: |
| 98 msg = "*** " + str(err) | |
| 99 self.errorbox("Syntax error", | |
| 100 "There's an error in your program:\n" + msg) | |
| 26693 | 101 return False |
| 26959 | 102 |
| 26693 | 103 def colorize_syntax_error(self, msg, lineno, offset): |
| 104 text = self.editwin.text | |
| 105 pos = "0.0 + %d lines + %d chars" % (lineno-1, offset-1) | |
| 106 text.tag_add("ERROR", pos) | |
| 107 char = text.get(pos) | |
| 108 if char and char in IDENTCHARS: | |
| 109 text.tag_add("ERROR", pos + " wordstart", pos) | |
| 110 if '\n' == text.get(pos): # error at line end | |
| 111 text.mark_set("insert", pos) | |
| 112 else: | |
| 113 text.mark_set("insert", pos + "+1c") | |
| 114 text.see(pos) | |
| 26959 | 115 |
| 27390 | 116 def run_module_event(self, event): |
| 117 "Check syntax, if ok run the module in the shell top level" | |
| 13975 | 118 filename = self.getfilename() |
| 119 if not filename: | |
| 120 return | |
| 26693 | 121 code = self.checksyntax(filename) |
| 122 if not code: | |
| 123 return | |
| 13975 | 124 flist = self.editwin.flist |
| 125 shell = flist.open_shell() | |
| 126 interp = shell.interp | |
| 25123 | 127 interp.restart_subprocess() |
| 23547 | 128 # XXX Too often this discards arguments the user just set... |
| 129 interp.runcommand("""if 1: | |
| 130 _filename = %s | |
| 131 import sys as _sys | |
| 132 from os.path import basename as _basename | |
| 133 if (not _sys.argv or | |
| 134 _basename(_sys.argv[0]) != _basename(_filename)): | |
| 135 _sys.argv = [_filename] | |
| 26693 | 136 del _filename, _sys, _basename |
| 23547 | 137 \n""" % `filename`) |
| 26693 | 138 interp.runcode(code) |
| 13975 | 139 |
| 140 def getfilename(self): | |
|
26713
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
141 """Get source filename. If not saved, offer to save (or create) file |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
142 |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
143 The debugger requires a source file. Make sure there is one, and that |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
144 the current version of the source buffer has been saved. If the user |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
145 declines to save or cancels the Save As dialog, return None. |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
146 """ |
| 13975 | 147 if not self.editwin.get_saved(): |
|
26713
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
148 msg = """Source Must Be Saved |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
149 OK to Save?""" |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
150 mb = tkMessageBox.Message( |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
151 title="Save Before Run or Check", |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
152 message=msg, |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
153 icon=tkMessageBox.QUESTION, |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
154 type=tkMessageBox.OKCANCEL, |
|
27194
59309d4bf841
Default the OK key in the Save Before Run dialog.
Kurt B. Kaiser <kbk@shore.net>
parents:
26959
diff
changeset
|
155 default=tkMessageBox.OK, |
|
26713
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
156 master=self.editwin.text) |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
157 reply = mb.show() |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
158 if reply == "ok": |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
159 self.editwin.io.save(None) |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
160 else: |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
161 return None |
|
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
162 # filename is None if file doesn't exist |
| 13975 | 163 filename = self.editwin.io.filename |
|
26713
eab6d7c80341
If Edit window has not been saved, offer to save if user tries to Run or
Kurt B. Kaiser <kbk@shore.net>
parents:
26693
diff
changeset
|
164 self.editwin.text.focus_set() |
| 13975 | 165 return filename |
| 166 | |
| 167 def errorbox(self, title, message): | |
| 168 # XXX This should really be a function of EditorWindow... | |
| 169 tkMessageBox.showerror(title, message, master=self.editwin.text) | |
| 170 self.editwin.text.focus_set() |
