 class GhcModiProcess
   editorCount: 0
   process: null
+  commandQueue: []
+  commandRunning: false
 
   constructor: ->
 

{Range,Point} = require('atom')
Temp = require('temp')
FS = require('fs')
CP = require('child_process')

  spawnProcess: =>
    return unless atom.config.get('haskell-ghc-mod.enableGhcModi')
    return if @process?
    modiPath = atom.config.get('haskell-ghc-mod.ghcModiPath')
    @process = CP.spawn(modiPath,[],@processOptions())
    @process.on 'stderr', (data) ->
      console.error(data)
    @process.on 'exit', (code) ->
      @spawnProcess() if code!=0

  killProcess: =>
    @process?.stdin?.end?()
    @process.kill()
    @process=null

  # Tear down any state and detach
  destroy: ->
    @killProcess()

  queueCmd: (runFunc, command, callback) =>
    @commandQueue.push({f:runFunc,cmd:command,cb:callback})
    @runQueuedCommands()

  runQueuedCommands: =>
    return if @commandQueue.length==0 or @commandRunning
    @commandRunning = true
    {f,cmd,cb}=@commandQueue.shift()
    f cmd, (lines) =>
      cb lines
      @commandRunning=false
      @runQueuedCommands()

  runCmd: (command, callback) =>
    unless atom.config.get('haskell-ghc-mod.enableGhcModi')
      @runModCmd command, (lines) ->
        callback lines.map (line) ->
          replaceAll(line,'\0','\n')
    else
      @spawnProcess() unless @process
      @process.stdout.once 'data', (data)->
        lines = "#{data}".split("\n")
        result = lines[lines.length-2]
        console.error ("Ghc-modi terminated:\n"+"#{result}")\
          unless result.match(/^OK/)
        lines = lines.slice(0,-2)
        callback lines.map (line)->
