 
 (defun intero-auto-install (buffer install-status &optional targets source-buffer)
   "Automatically install Intero."
-  (let ((source-buffer (or source-buffer (current-buffer))))
-    (switch-to-buffer buffer)
-    (erase-buffer)
-    (insert (cl-case install-status
-              (not-installed "Intero is not installed in the Stack environment.")
-              (wrong-version "The wrong version of Intero is installed for this Emacs package."))
-            (format "
+  (if (buffer-local-value 'intero-give-up buffer)
+      buffer
+    (let ((source-buffer (or source-buffer (current-buffer))))
+      (switch-to-buffer buffer)
+      (erase-buffer)
+      (insert (cl-case install-status
+                (not-installed "Intero is not installed in the Stack environment.")
+                (wrong-version "The wrong version of Intero is installed for this Emacs package."))
+              (format "
 
 Installing intero-%s automatically ...
 
 " intero-package-version))
-    (redisplay)
-    (cl-case (call-process "stack" nil (current-buffer) t "build"
-                           (with-current-buffer buffer
-                             (let* ((cabal-file (intero-cabal-find-file))
-                                    (package-name (intero-package-name cabal-file)))
-                               ;; For local development. Most users'll
-                               ;; never hit this behaviour.
-                               (if (string= package-name "intero")
-                                   "intero"
-                                 (concat "intero-" intero-package-version))))
-                           "ghc-paths" "syb")
-      (0
-       (message "Installed successfully! Starting Intero in a moment ...")
-       (bury-buffer buffer)
-       (switch-to-buffer source-buffer)
-       (intero-start-process-in-buffer buffer targets source-buffer))
-      (1 (insert (propertize "Could not install Intero!
+      (redisplay)
+      (cl-case (call-process "stack" nil (current-buffer) t "build"
+                             (with-current-buffer buffer
+                               (let* ((cabal-file (intero-cabal-find-file))
+                                      (package-name (intero-package-name cabal-file)))
+                                 ;; For local development. Most users'll
+                                 ;; never hit this behaviour.
+                                 (if (string= package-name "intero")
+                                     "intero"
+                                   (concat "intero-" intero-package-version))))
+                             "ghc-paths" "syb")
+        (0
+         (message "Installed successfully! Starting Intero in a moment ...")
+         (bury-buffer buffer)
+         (switch-to-buffer source-buffer)
+         (intero-start-process-in-buffer buffer targets source-buffer))
+        (1
+         (with-current-buffer buffer (setq-local intero-give-up t))
+         (insert (propertize "Could not install Intero!
 
 We don't know why it failed. Please read the above output and try
 installing manually. If that doesn't work, report this as a
 problem.
+
+WHAT TO DO NEXT
+
+If you don't want to Intero to try installing itself again for
+this project, just keep this buffer around in your Emacs.
+
+If you'd like to try again next time you try use an Intero
+feature, kill this buffer.
 "
-                             'face 'compilation-error))))))
+                             'face 'compilation-error))
+         nil)))))
 
 (defun intero-start-process-in-buffer (buffer &optional targets source-buffer)
   "Start an Intero worker in BUFFER for TARGETS, automatically
 performing a initial actions in SOURCE-BUFFER, if specified."
-  (let* ((options
-          (intero-make-options-list
-           (or targets
-               (list (buffer-local-value 'intero-package-name buffer)))))
-         (arguments options)
-         (process (with-current-buffer buffer
-                    (when debug-on-error
-                      (message "Intero arguments: %s" (combine-and-quote-strings arguments)))
-                    (message "Booting up intero ...")
-                    (apply #'start-process "stack" buffer "stack" "ghci"
-                           arguments))))
-    (set-process-query-on-exit-flag process nil)
-    (process-send-string process ":set -fobject-code\n")
-    (process-send-string process ":set prompt \"\\4\"\n")
-    (with-current-buffer buffer
-      (erase-buffer)
-      (setq intero-targets targets)
-      (setq intero-arguments arguments)
-      (setq intero-callbacks
-            (list (list source-buffer
-                        (lambda (source-buffer _msg)
-                          (when source-buffer
-                            (with-current-buffer source-buffer
-                              (when flycheck-mode
-                                (run-with-timer 0 nil
-                                                'intero-call-in-buffer
-                                                (current-buffer)
-                                                'flycheck-buffer))))
-                          (message "Booted up intero!"))))))
-    (set-process-filter process
-                        (lambda (process string)
-                          (when (buffer-live-p (process-buffer process))
-                            (with-current-buffer (process-buffer process)
-                              (goto-char (point-max))
-                              (insert string)
-                              (intero-read-buffer)))))
-    (set-process-sentinel process 'intero-sentinel)
-    buffer))
+  (if (buffer-local-value 'intero-give-up buffer)
+      buffer
+    (let* ((options
+            (intero-make-options-list
+             (or targets
+                 (list (buffer-local-value 'intero-package-name buffer)))))
+           (arguments options)
+           (process (with-current-buffer buffer
+                      (when debug-on-error
+                        (message "Intero arguments: %s" (combine-and-quote-strings arguments)))
+                      (message "Booting up intero ...")
+                      (apply #'start-process "stack" buffer "stack" "ghci"
+                             arguments))))
+      (set-process-query-on-exit-flag process nil)
+      (process-send-string process ":set -fobject-code\n")
+      (process-send-string process ":set prompt \"\\4\"\n")
+      (with-current-buffer buffer
+        (erase-buffer)
+        (setq intero-targets targets)
+        (setq intero-arguments arguments)
+        (setq intero-callbacks
+              (list (list source-buffer
+                          (lambda (source-buffer _msg)
+                            (when source-buffer
+                              (with-current-buffer source-buffer
+                                (when flycheck-mode
+                                  (run-with-timer 0 nil
+                                                  'intero-call-in-buffer
+                                                  (current-buffer)
+                                                  'intero-flycheck-buffer))))
+                            (message "Booted up intero!"))))))
+      (set-process-filter process
+                          (lambda (process string)
+                            (when (buffer-live-p (process-buffer process))
+                              (with-current-buffer (process-buffer process)
+                                (goto-char (point-max))
+                                (insert string)
+                                (intero-read-buffer)))))
+      (set-process-sentinel process 'intero-sentinel)
+      buffer)))
+
+(defun intero-flycheck-buffer ()
+  "Run flycheck in the buffer. Restarting in case there was a
+problem and flycheck is stuck."
+  (flycheck-mode -1)
+  (flycheck-mode)
+  (flycheck-buffer))
 
 (defun intero-make-options-list (targets)
   "Make the stack ghci options list."


(defun intero-check (checker cont)
  "Run a check and pass the status onto CONT."
  (let ((file-buffer (current-buffer)))
    (write-region (point-min) (point-max) (intero-buffer-file-name) nil 'no-message)
    (clear-visited-file-modtime)
    (intero-async-call
     'backend
     (concat ":l " (intero-buffer-file-name))
     (list :cont cont
           :file-buffer file-buffer
           :checker checker)
     (lambda (state string)
       (with-current-buffer (plist-get state :file-buffer)
         (funcall (plist-get state :cont)
                  'finished
                  (intero-parse-errors-warnings
                   (plist-get state :checker)
                   (current-buffer)
                   string))
         (when (string-match "OK, modules loaded: \\(.*\\)\\.$" string)
           (let ((modules (match-string 1 string)))
             (intero-async-call 'backend
                                (concat ":m + "
                                        (replace-regexp-in-string modules "," ""))
                                nil
                                (lambda (_st _))))))))))

(flycheck-define-generic-checker 'intero
  "A syntax and type checker for Haskell using an Intero worker

(defvar intero-deleting nil
  "The process of the buffer is being deleted.")
(make-variable-buffer-local 'intero-deleting)

(defvar intero-give-up nil
  "The backend could not start, or could not be
  installed. Abandon trying to automate it. The user will have to
  manually run M-x intero-restart or M-x intero-targets to
  destroy the buffer and create a fresh one without this variable
  enabled.")
(make-variable-buffer-local 'intero-give-up)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Interactive commands
