     .on 'AppendSessionOutput', ({result}) -> session.add result
     .on 'NotAtInputPrompt', -> session.noPrompt()
     .on 'AtInputPrompt', ({why}) ->
-      if execQueue.length then D.socket.emit 'Execute', trace: 0, text: execQueue.shift() + '\n' else session.prompt why
+      if pending.length then D.socket.emit 'Execute', trace: 0, text: pending.shift() + '\n' else session.prompt why
       return
-    .on 'HadError', -> execQueue.splice 0, execQueue.length; return
+    .on 'HadError', -> pending.splice 0, pending.length; return
     .on 'FocusWindow', ({win}) -> $("#wintab#{win} a").click(); wins[win].widget.focus(); return
     .on 'WindowTypeChanged', ({win, tracer}) -> wins[win].widget.setDebugger tracer
     .on 'autocomplete', (token, skip, options) -> wins[token].widget.autocomplete skip, options

      autocomplete: (s, i) -> D.socket.emit 'Autocomplete', line: s, pos: i, token: 0
      exec: (lines, trace) ->
        if lines && lines.length
          if !trace then execQueue = lines[1..]
          D.socket.emit 'Execute', {trace, text: lines[0] + '\n'}
        return


  """

  isDead = 0
  pending = [] # pending lines to execute: AtInputPrompt consumes one item from the queue, HadError empties it

  # "wins" maps window ids, as they appear in the RIDE protocol, to window information objects that have the following properties:
  #   widget: a session or an editor
