/Lib/idlelib/OutputWindow.py

http://unladen-swallow.googlecode.com/ · Python · 144 lines · 101 code · 23 blank · 20 comment · 20 complexity · 24ea25e8bc42ee6ca5d4e51c83b96cae MD5 · raw file

  1. from Tkinter import *
  2. from EditorWindow import EditorWindow
  3. import re
  4. import tkMessageBox
  5. import IOBinding
  6. class OutputWindow(EditorWindow):
  7. """An editor window that can serve as an output file.
  8. Also the future base class for the Python shell window.
  9. This class has no input facilities.
  10. """
  11. def __init__(self, *args):
  12. EditorWindow.__init__(self, *args)
  13. self.text.bind("<<goto-file-line>>", self.goto_file_line)
  14. # Customize EditorWindow
  15. def ispythonsource(self, filename):
  16. # No colorization needed
  17. return 0
  18. def short_title(self):
  19. return "Output"
  20. def maybesave(self):
  21. # Override base class method -- don't ask any questions
  22. if self.get_saved():
  23. return "yes"
  24. else:
  25. return "no"
  26. # Act as output file
  27. def write(self, s, tags=(), mark="insert"):
  28. # Tk assumes that byte strings are Latin-1;
  29. # we assume that they are in the locale's encoding
  30. if isinstance(s, str):
  31. try:
  32. s = unicode(s, IOBinding.encoding)
  33. except UnicodeError:
  34. # some other encoding; let Tcl deal with it
  35. pass
  36. self.text.insert(mark, s, tags)
  37. self.text.see(mark)
  38. self.text.update()
  39. def writelines(self, l):
  40. map(self.write, l)
  41. def flush(self):
  42. pass
  43. # Our own right-button menu
  44. rmenu_specs = [
  45. ("Go to file/line", "<<goto-file-line>>"),
  46. ]
  47. file_line_pats = [
  48. # order of patterns matters
  49. r'file "([^"]*)", line (\d+)',
  50. r'([^\s]+)\((\d+)\)',
  51. r'^(\s*\S.*?):\s*(\d+):', # Win filename, maybe starting with spaces
  52. r'([^\s]+):\s*(\d+):', # filename or path, ltrim
  53. r'^\s*(\S.*?):\s*(\d+):', # Win abs path with embedded spaces, ltrim
  54. ]
  55. file_line_progs = None
  56. def goto_file_line(self, event=None):
  57. if self.file_line_progs is None:
  58. l = []
  59. for pat in self.file_line_pats:
  60. l.append(re.compile(pat, re.IGNORECASE))
  61. self.file_line_progs = l
  62. # x, y = self.event.x, self.event.y
  63. # self.text.mark_set("insert", "@%d,%d" % (x, y))
  64. line = self.text.get("insert linestart", "insert lineend")
  65. result = self._file_line_helper(line)
  66. if not result:
  67. # Try the previous line. This is handy e.g. in tracebacks,
  68. # where you tend to right-click on the displayed source line
  69. line = self.text.get("insert -1line linestart",
  70. "insert -1line lineend")
  71. result = self._file_line_helper(line)
  72. if not result:
  73. tkMessageBox.showerror(
  74. "No special line",
  75. "The line you point at doesn't look like "
  76. "a valid file name followed by a line number.",
  77. master=self.text)
  78. return
  79. filename, lineno = result
  80. edit = self.flist.open(filename)
  81. edit.gotoline(lineno)
  82. def _file_line_helper(self, line):
  83. for prog in self.file_line_progs:
  84. match = prog.search(line)
  85. if match:
  86. filename, lineno = match.group(1, 2)
  87. try:
  88. f = open(filename, "r")
  89. f.close()
  90. break
  91. except IOError:
  92. continue
  93. else:
  94. return None
  95. try:
  96. return filename, int(lineno)
  97. except TypeError:
  98. return None
  99. # These classes are currently not used but might come in handy
  100. class OnDemandOutputWindow:
  101. tagdefs = {
  102. # XXX Should use IdlePrefs.ColorPrefs
  103. "stdout": {"foreground": "blue"},
  104. "stderr": {"foreground": "#007700"},
  105. }
  106. def __init__(self, flist):
  107. self.flist = flist
  108. self.owin = None
  109. def write(self, s, tags, mark):
  110. if not self.owin:
  111. self.setup()
  112. self.owin.write(s, tags, mark)
  113. def setup(self):
  114. self.owin = owin = OutputWindow(self.flist)
  115. text = owin.text
  116. for tag, cnf in self.tagdefs.items():
  117. if cnf:
  118. text.tag_configure(tag, **cnf)
  119. text.tag_raise('sel')
  120. self.write = self.owin.write