 (defvar merlin-buffer nil
   "Buffer for merlin input.")
 (make-variable-buffer-local 'merlin-buffer)
-
-;; Those variables will be bound dynamically in the scope of asynchronous
-;; closures (merlin-send-command-async & merlin-wait-for-answer)
-; (defvar merlin-result nil
-;   "Temporary variables to store command results.")
-; (make-variable-buffer-local 'merlin-result)
-
-; (defvar merlin-ready nil
-;   "If non-nil, the reception is done.")
-; (make-variable-buffer-local 'merlin-ready)
 
 (defvar merlin-dirty-point 0
   "Position after which buffer content may differ.")

    (merlin--reset)
    (merlin--check-project-file)))

(defun merlin-send-command-async (command callback-if-success &optional callback-if-exn)
  "Send COMMAND (with arguments ARGS) to merlin asynchronously.
Give the result to callback-if-success.  If merlin reported an
error and if CALLBACK-IF-EXN is non-nil, call the function with
the error message otherwise print a generic error message."
  (assert (merlin--acquired-buffer))
  (lexical-let*
      ((string (concat (prin1-to-string (if (listp command) command (list command)))
                        "\n"))
       (buffer (current-buffer))
       (name (buffer-name)))
    (if (not (equal (process-status (merlin-process)) 'run))
        (progn
          (error "Merlin process not running (try restarting with %s)"
                 (substitute-command-keys "\\[merlin-restart-process]"))
          nil)
      (with-current-buffer (merlin-process-buffer)
        (if merlin-debug (merlin-debug (format ">%s" string)))
        (tq-enqueue merlin-process-queue string "\n"
                    (cons callback-if-success (cons callback-if-exn command))
                    #'(lambda (closure answer)
                        (with-current-buffer buffer
                          (setq merlin-ready t)
                          (if merlin-debug (merlin-debug (format "<%s" answer)))
                          (let ((a (car (read-from-string answer))))
                            (if a
                                (cond ((string-equal (elt a 0) "return")
                                       (funcall (car closure) (elt a 1)))
                                      ((string-equal (elt a 0) "exception")
                                       (message "Merlin failed with exception: %s" (elt a 1)))
                                      ((progn
                                         (if (functionp (cadr closure))
                                             (funcall (cadr closure) (elt a 1))
                                           (message "Command %s failed with error %s" (cddr closure) (elt a 1))))))
                              (message "Invalid answer received from merlin.")))))
                    nil)
        nil)
      t)))

(defun merlin-send-command (command &optional callback-if-exn)
  "Send COMMAND (with arguments ARGS) to merlin and returns the result."
  (let ((merlin-result nil)
        (merlin-ready nil))
    (when (merlin-send-command-async command
                                     (lambda (data) (setq merlin-result data))
                                     callback-if-exn)
      (merlin-wait-for-answer))))

;; SPECIAL CASE OF COMMANDS


      (ignore-errors (kill-process merlin-process)))
    (kill-buffer buffer)))

(defun merlin--wait-for-answer (promise)
  "Waits for merlin to answer."
  (when promise
    (let ((w32-pipe-read-delay 0)) ;; fix 50ms latency of emacs on win32
      (while (not (car promise))
        (accept-process-output (merlin-process) 1.0)))
    (cdr promise)))

(defun merlin--reset ()
  "Rewind the knowledge of merlin of the current buffer to zero."
