text: from tkinter import *
  from idlelib.EditorWindow import EditorWindow
  import re
  import tkinter.messagebox as tkMessageBox
  from idlelib import IOBinding
  
  class OutputWindow(EditorWindow):
  
      """An editor window that can serve as an output file.
  
      Also the future base class for the Python shell window.
      This class has no input facilities.
      """
  
      def __init__(self, *args):
          EditorWindow.__init__(self, *args)
          self.text.bind("<<goto-file-line>>", self.goto_file_line)
  
      # Customize EditorWindow
  
      def ispythonsource(self, filename):
          # No colorization needed
          return 0
  
      def short_title(self):
          return "Output"
  
      def maybesave(self):
          # Override base class method -- don't ask any questions
          if self.get_saved():
              return "yes"
          else:
              return "no"
  
      # Act as output file
  
      def write(self, s, tags=(), mark="insert"):
          if isinstance(s, (bytes, bytes)):
              s = s.decode(IOBinding.encoding, "replace")
          self.text.insert(mark, s, tags)
          self.text.see(mark)
          self.text.update()
  
      def writelines(self, lines):
          for line in lines:
              self.write(line)
  
      def flush(self):
          pass
  
      # Our own right-button menu
  
      rmenu_specs = [
          ("Go to file/line", "<<goto-file-line>>"),
      ]
  
      file_line_pats = [
          # order of patterns matters
          r'file "([^"]*)", line (\d+)',
          r'([^\s]+)\((\d+)\)',
          r'^(\s*\S.*?):\s*(\d+):',  # Win filename, maybe starting with spaces
          r'([^\s]+):\s*(\d+):',     # filename or path, ltrim
          r'^\s*(\S.*?):\s*(\d+):',  # Win abs path with embedded spaces, ltrim
      ]
  
      file_line_progs = None
  
      def goto_file_line(self, event=None):
          if self.file_line_progs is None:
              l = []
              for pat in self.file_line_pats:
                  l.append(re.compile(pat, re.IGNORECASE))
              self.file_line_progs = l
          # x, y = self.event.x, self.event.y
          # self.text.mark_set("insert", "@%d,%d" % (x, y))
          line = self.text.get("insert linestart", "insert lineend")
          result = self._file_line_helper(line)
          if not result:
              # Try the previous line.  This is handy e.g. in tracebacks,
              # where you tend to right-click on the displayed source line
              line = self.text.get("insert -1line linestart",
                                   "insert -1line lineend")
              result = self._file_line_helper(line)
              if not result:
                  tkMessageBox.showerror(
                      "No special line",
                      "The line you point at doesn't look like "
                      "a valid file name followed by a line number.",
                      master=self.text)
                  return
          filename, lineno = result
          edit = self.flist.open(filename)
          edit.gotoline(lineno)
  
      def _file_line_helper(self, line):
          for prog in self.file_line_progs:
              match = prog.search(line)
              if match:
                  filename, lineno = match.group(1, 2)
                  try:
                      f = open(filename, "r")
                      f.close()
                      break
                  except IOError:
                      continue
          else:
              return None
          try:
              return filename, int(lineno)
          except TypeError:
              return None
  
  # These classes are currently not used but might come in handy
  
  class OnDemandOutputWindow:
  
      tagdefs = {
          # XXX Should use IdlePrefs.ColorPrefs
          "stdout":  {"foreground": "blue"},
          "stderr":  {"foreground": "#007700"},
      }
  
      def __init__(self, flist):
          self.flist = flist
          self.owin = None
  
      def write(self, s, tags, mark):
          if not self.owin:
              self.setup()
          self.owin.write(s, tags, mark)
  
      def setup(self):
          self.owin = owin = OutputWindow(self.flist)
          text = owin.text
          for tag, cnf in self.tagdefs.items():
              if cnf:
                  text.tag_configure(tag, **cnf)
          text.tag_raise('sel')
          self.write = self.owin.write
  