about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.el
diff options
context:
space:
mode:
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.el')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.el3648
1 files changed, 0 insertions, 3648 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.el b/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.el
deleted file mode 100644
index 0553b6307300..000000000000
--- a/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.el
+++ /dev/null
@@ -1,3648 +0,0 @@
-;;; intero.el --- Complete development mode for Haskell
-
-;; Copyright (c) 2016 Chris Done
-;; Copyright (c) 2016 Steve Purcell
-;; Copyright (C) 2016 Артур Файзрахманов
-;; Copyright (c) 2015 Athur Fayzrakhmanov
-;; Copyright (C) 2015 Gracjan Polak
-;; Copyright (c) 2013 Herbert Valerio Riedel
-;; Copyright (c) 2007 Stefan Monnier
-
-;; Author: Chris Done <chrisdone@fpcomplete.com>
-;; Maintainer: Chris Done <chrisdone@fpcomplete.com>
-;; URL: https://github.com/commercialhaskell/intero
-;; Package-Version: 20180703.18
-;; Created: 3rd June 2016
-;; Version: 0.1.13
-;; Keywords: haskell, tools
-;; Package-Requires: ((flycheck "0.25") (company "0.8") (emacs "24.4") (haskell-mode "13.0"))
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
-
-;;; Commentary:
-;;
-;; Mode that enables:
-;;
-;; * Flycheck type checking ✓
-;; * Company mode completion ✓
-;; * Go to definition ✓
-;; * Type of selection ✓
-;; * Info ✓
-;; * REPL ✓
-;; * Apply suggestions (extensions, imports, etc.) ✓
-;; * Find uses
-;; * Completion of stack targets ✓
-;; * List all types in all expressions
-;; * Import management
-;; * Dependency management
-
-;;; Code:
-
-(require 'flycheck)
-(require 'json)
-(require 'warnings)
-(require 'cl-lib)
-(require 'company)
-(require 'comint)
-(require 'widget)
-(require 'eldoc)
-(eval-when-compile
-  (require 'wid-edit))
-(require 'tramp)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Configuration
-
-(defgroup intero nil
-  "Complete development mode for Haskell"
-  :group 'haskell)
-
-(defcustom intero-package-version
-  (cl-case system-type
-    ;; Until <https://github.com/haskell/network/issues/313> is fixed:
-    (windows-nt "0.1.32")
-    (cygwin "0.1.32")
-    (t "0.1.32"))
-  "Package version to auto-install.
-
-This version does not necessarily have to be the latest version
-of intero published on Hackage.  Sometimes there are changes to
-Intero which have no use for the Emacs mode.  It is only bumped
-when the Emacs mode actually requires newer features from the
-intero executable, otherwise we force our users to upgrade
-pointlessly."
-  :group 'intero
-  :type 'string)
-
-(defcustom intero-repl-no-load
-  t
-  "Pass --no-load when starting the repl.
-This causes it to skip loading the files from the selected target."
-  :group 'intero
-  :type 'boolean)
-
-(defcustom intero-repl-no-build
-  t
-  "Pass --no-build when starting the repl.
-This causes it to skip building the target."
-  :group 'intero
-  :type 'boolean)
-
-(defcustom intero-debug nil
-  "Show debug output."
-  :group 'intero
-  :type 'boolean)
-
-(defcustom intero-whitelist
-  nil
-  "Projects to whitelist.
-
-It should be a list of directories.
-
-To use this, use the following mode hook:
-  (add-hook 'haskell-mode-hook 'intero-mode-whitelist)
-or use `intero-global-mode' and add \"/\" to `intero-blacklist'."
-  :group 'intero
-  :type 'string)
-
-(defcustom intero-blacklist
-  nil
-  "Projects to blacklist.
-
-It should be a list of directories.
-
-To use this, use the following mode hook:
-  (add-hook 'haskell-mode-hook 'intero-mode-blacklist)
-or use `intero-global-mode'."
-  :group 'intero
-  :type 'string)
-
-(defcustom intero-stack-executable
-  "stack"
-  "Name or path to the Stack executable to use."
-  :group 'intero
-  :type 'string)
-
-(defcustom intero-pop-to-repl
-  t
-  "When non-nil, pop to REPL when code is sent to it."
-  :group 'intero
-  :type 'boolean)
-
-(defcustom intero-extra-ghc-options nil
-  "Extra GHC options to pass to intero executable.
-
-For example, this variable can be used to run intero with extra
-warnings and perform more checks via flycheck error reporting."
-  :group 'intero
-  :type '(repeat string))
-
-(defcustom intero-extra-ghci-options nil
-  "Extra options to pass to GHCi when running `intero-repl'.
-
-For example, this variable can be used to enable some ghci extensions
-by default."
-  :group 'intero
-  :type '(repeat string))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Modes
-
-(defvar intero-mode-map (make-sparse-keymap)
-  "Intero minor mode's map.")
-
-(defvar-local intero-lighter " Intero"
-  "Lighter for the intero minor mode.")
-
-;;;###autoload
-(define-minor-mode intero-mode
-  "Minor mode for Intero.
-
-\\{intero-mode-map}"
-  :lighter intero-lighter
-  :keymap intero-mode-map
-  (when (bound-and-true-p interactive-haskell-mode)
-    (when (fboundp 'interactive-haskell-mode)
-      (message "Disabling interactive-haskell-mode ...")
-      (interactive-haskell-mode -1)))
-  (if intero-mode
-      (progn
-        (intero-flycheck-enable)
-        (add-hook 'completion-at-point-functions 'intero-completion-at-point nil t)
-        (add-to-list (make-local-variable 'company-backends) 'intero-company)
-        (company-mode)
-        (setq-local company-minimum-prefix-length 1)
-        (unless eldoc-documentation-function
-          (setq-local eldoc-documentation-function #'ignore))
-        (add-function :before-until (local 'eldoc-documentation-function) #'intero-eldoc)
-        )
-    (progn
-      (remove-function (local 'eldoc-documentation-function) #'intero-eldoc)
-      (message "Intero mode disabled."))))
-
-;;;###autoload
-(defun intero-mode-whitelist ()
-  "Run intero-mode when the current project is in `intero-whitelist'."
-  (interactive)
-  (when (intero-directories-contain-file (buffer-file-name) intero-whitelist)
-    (intero-mode)))
-
-;;;###autoload
-(defun intero-mode-blacklist ()
-  "Run intero-mode unless the current project is in `intero-blacklist'."
-  (interactive)
-  (unless (intero-directories-contain-file (buffer-file-name) intero-blacklist)
-    (intero-mode)))
-
-(dolist (f '(intero-mode-whitelist intero-mode-blacklist))
-  (make-obsolete
-   f
-   "use `intero-global-mode', which honours `intero-whitelist' and `intero-blacklist'."
-   "2017-05-13"))
-
-
-(define-key intero-mode-map (kbd "C-c C-t") 'intero-type-at)
-(define-key intero-mode-map (kbd "M-?") 'intero-uses-at)
-(define-key intero-mode-map (kbd "C-c C-i") 'intero-info)
-(define-key intero-mode-map (kbd "M-.") 'intero-goto-definition)
-(define-key intero-mode-map (kbd "C-c C-l") 'intero-repl-load)
-(define-key intero-mode-map (kbd "C-c C-c") 'intero-repl-eval-region)
-(define-key intero-mode-map (kbd "C-c C-z") 'intero-repl)
-(define-key intero-mode-map (kbd "C-c C-r") 'intero-apply-suggestions)
-(define-key intero-mode-map (kbd "C-c C-e") 'intero-expand-splice-at-point)
-
-(defun intero-directories-contain-file (file dirs)
-  "Return non-nil if FILE is contained in at least one of DIRS."
-  (and (not (null file))
-       (cl-some (lambda (directory)
-                  (file-in-directory-p file directory))
-                dirs)))
-
-(defun intero-mode-maybe ()
-  "Enable `intero-mode' in all Haskell mode buffers.
-The buffer's filename (or working directory) is checked against
-`intero-whitelist' and `intero-blacklist'.  If both the whitelist
-and blacklist match, then the whitelist entry wins, and
-`intero-mode' is enabled."
-  (when (and (derived-mode-p 'haskell-mode)
-             (let* ((file (or (buffer-file-name) default-directory))
-                    (blacklisted (intero-directories-contain-file
-                                  file intero-blacklist))
-                    (whitelisted (intero-directories-contain-file
-                                  file intero-whitelist)))
-               (or whitelisted (not blacklisted))))
-    (intero-mode 1)))
-
-;;;###autoload
-(define-globalized-minor-mode intero-global-mode
-  intero-mode intero-mode-maybe
-  :require 'intero)
-
-(define-obsolete-function-alias 'global-intero-mode 'intero-global-mode)
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Global variables/state
-
-(defvar intero-temp-file-buffer-mapping
-  (make-hash-table)
-  "A mapping from file names to buffers.")
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Buffer-local variables/state
-
-(defvar-local intero-callbacks (list)
-  "List of callbacks waiting for output.
-LIST is a FIFO.")
-
-(defvar-local intero-async-network-cmd nil
-  "Command to send to the async network process when we connect.")
-
-(defvar-local intero-async-network-connected nil
-  "Did we successfully connect to the intero service?")
-
-(defvar-local intero-async-network-state nil
-  "State to pass to the callback once we get a response.")
-
-(defvar-local intero-async-network-worker nil
-  "The worker we're associated with.")
-
-(defvar-local intero-async-network-callback nil
-  "Callback to call when the connection is closed.")
-
-(defvar-local intero-arguments (list)
-  "Arguments used to call the stack process.")
-
-(defvar-local intero-targets (list)
-  "Targets used for the stack process.")
-
-(defvar-local intero-repl-last-loaded nil
-  "Last loaded module in the REPL.")
-
-(defvar-local intero-repl-send-after-load nil
-  "Send a command after every load.")
-
-(defvar-local intero-start-time nil
-  "Start time of the stack process.")
-
-(defvar-local intero-source-buffer (list)
-  "Buffer from which Intero was first requested to start.")
-
-(defvar-local intero-project-root nil
-  "The project root of the current buffer.")
-
-(defvar-local intero-package-name nil
-  "The package name associated with the current buffer.")
-
-(defvar-local intero-deleting nil
-  "The process of the buffer is being deleted.")
-
-(defvar-local intero-give-up nil
-  "When non-nil, give up trying to start the backend.
-A true value indicates that the backend could not start, or could
-not be installed.  The user will have to manually run
-`intero-restart' or `intero-targets' to destroy the buffer and
-create a fresh one without this variable enabled.")
-
-(defvar-local intero-try-with-build nil
-  "Try starting intero without --no-build.
-This is slower, but will build required dependencies.")
-
-(defvar-local intero-starting nil
-  "When non-nil, indicates that the intero process starting up.")
-
-(defvar-local intero-service-port nil
-  "Port that the intero process is listening on for asynchronous commands.")
-
-(defvar-local intero-hoogle-port nil
-  "Port that hoogle server is listening on.")
-
-(defvar-local intero-suggestions nil
-  "Auto actions for the buffer.")
-
-(defvar-local intero-extensions nil
-  "Extensions supported by the compiler.")
-
-(defvar-local intero-ghc-version nil
-  "GHC version used by the project.")
-
-(defvar-local intero-buffer-host nil
-  "The hostname of the box hosting the intero process for the current buffer.")
-
-(defvar-local intero-stack-yaml nil
-  "The yaml file that intero should tell stack to use. When nil,
-  intero relies on stack's default, usually the 'stack.yaml' in
-  the project root.")
-
-(defun intero-inherit-local-variables (buffer)
-  "Make the current buffer inherit values of certain local variables from BUFFER."
-  (let ((variables '(intero-stack-executable
-                     intero-repl-no-build
-                     intero-repl-no-load
-                     intero-stack-yaml
-                     ;; TODO: shouldn’t more of the above be here?
-                     )))
-    (cl-loop for v in variables do
-             (set (make-local-variable v) (buffer-local-value v buffer)))))
-
-(defmacro intero-with-temp-buffer (&rest body)
-  "Run BODY in `with-temp-buffer', but inherit certain local variables from the current buffer first."
-  (declare (indent 0) (debug t))
-  `(let ((initial-buffer (current-buffer)))
-     (with-temp-buffer
-       (intero-inherit-local-variables initial-buffer)
-       ,@body)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Interactive commands
-
-(defun intero-add-package (package)
-  "Add a dependency on PACKAGE to the currently-running project backend."
-  (interactive "sPackage: ")
-  (intero-blocking-call 'backend (concat ":set -package " package))
-  (flycheck-buffer))
-
-(defun intero-toggle-debug ()
-  "Toggle debugging mode on/off."
-  (interactive)
-  (setq intero-debug (not intero-debug))
-  (message "Intero debugging is: %s" (if intero-debug "ON" "OFF")))
-
-(defun intero-list-buffers ()
-  "List hidden process buffers created by intero.
-
-You can use this to kill them or look inside."
-  (interactive)
-  (let ((buffers (cl-remove-if-not
-                  (lambda (buffer)
-                    (string-match-p " intero:" (buffer-name buffer)))
-                  (buffer-list))))
-    (if buffers
-        (display-buffer
-         (list-buffers-noselect
-          nil
-          buffers))
-      (error "There are no Intero process buffers"))))
-
-(defun intero-cd ()
-  "Change directory in the backend process."
-  (interactive)
-  (intero-async-call
-   'backend
-   (concat ":cd "
-           (read-directory-name "Change Intero directory: "))))
-
-(defun intero-fontify-expression (expression)
-  "Return a haskell-fontified version of EXPRESSION."
-  (intero-with-temp-buffer
-    (when (fboundp 'haskell-mode)
-      (let ((flycheck-checkers nil)
-            (haskell-mode-hook nil))
-        (haskell-mode)))
-    (insert expression)
-    (if (fboundp 'font-lock-ensure)
-        (font-lock-ensure)
-      (font-lock-fontify-buffer))
-    (buffer-string)))
-
-(defun intero-uses-at ()
-  "Highlight where the identifier at point is used."
-  (interactive)
-  (let* ((thing (intero-thing-at-point))
-         (uses (split-string (apply #'intero-get-uses-at thing)
-                             "\n"
-                             t)))
-    (unless (null uses)
-      (let ((highlighted nil))
-        (cl-loop
-         for use in uses
-         when (string-match
-               "\\(.*?\\):(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\))$"
-               use)
-         do (let* ((returned-file (match-string 1 use))
-                   (loaded-file (intero-extend-path-by-buffer-host returned-file))
-                   (sline (string-to-number (match-string 2 use)))
-                   (scol (string-to-number (match-string 3 use)))
-                   (eline (string-to-number (match-string 4 use)))
-                   (ecol (string-to-number (match-string 5 use)))
-                   (start (save-excursion (goto-char (point-min))
-                                          (forward-line (1- sline))
-                                          (forward-char (1- scol))
-                                          (point))))
-              (when (intero-temp-file-p loaded-file)
-                (unless highlighted
-                  (intero-highlight-uses-mode))
-                (setq highlighted t)
-                (intero-highlight-uses-mode-highlight
-                 start
-                 (save-excursion (goto-char (point-min))
-                                 (forward-line (1- eline))
-                                 (forward-char (1- ecol))
-                                 (point))
-                 (= start (car thing))))))))))
-
-(defun intero-type-at (insert)
-  "Get the type of the thing or selection at point.
-
-With prefix argument INSERT, inserts the type above the current
-line as a type signature."
-  (interactive "P")
-  (let* ((thing (intero-thing-at-point))
-         (origin-buffer (current-buffer))
-         (origin (buffer-name))
-         (package (intero-package-name))
-         (ty (apply #'intero-get-type-at thing))
-         (string (buffer-substring (nth 0 thing) (nth 1 thing))))
-    (if insert
-        (save-excursion
-          (goto-char (line-beginning-position))
-          (insert (intero-fontify-expression ty) "\n"))
-      (with-current-buffer (intero-help-buffer)
-        (let ((buffer-read-only nil)
-              (help-string
-               (concat
-                (intero-fontify-expression string)
-                " in `"
-                (propertize origin 'origin-buffer origin-buffer)
-                "'"
-                " (" package ")"
-                "\n\n"
-                (intero-fontify-expression ty))))
-          (erase-buffer)
-          (intero-help-push-history origin-buffer help-string)
-          (intero-help-pagination)
-          (insert help-string)
-          (goto-char (point-min))))
-      (message
-       "%s" (intero-fontify-expression ty)))))
-
-(defun intero-info (ident)
-  "Get the info of the thing with IDENT at point."
-  (interactive (list (intero-ident-at-point)))
-  (let ((origin-buffer (current-buffer))
-        (package (intero-package-name))
-        (info (intero-get-info-of ident))
-        (origin (buffer-name)))
-    (with-current-buffer (pop-to-buffer (intero-help-buffer))
-      (let ((buffer-read-only nil)
-            (help-string
-             (concat
-              (intero-fontify-expression ident)
-              " in `"
-              (propertize origin 'origin-buffer origin-buffer)
-              "'"
-              " (" package ")"
-              "\n\n"
-              (intero-fontify-expression info))))
-        (erase-buffer)
-        (intero-help-push-history origin-buffer help-string)
-        (intero-help-pagination)
-        (insert help-string)
-        (goto-char (point-min))))))
-
-(defun intero-goto-definition ()
-  "Jump to the definition of the thing at point.
-Returns nil when unable to find definition."
-  (interactive)
-  (let ((result (apply #'intero-get-loc-at (intero-thing-at-point))))
-
-    (if (not (string-match "\\(.*?\\):(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\))$"
-                       result))
-        (message "%s" result)
-      (if (fboundp 'xref-push-marker-stack) ;; Emacs 25
-          (xref-push-marker-stack)
-        (with-no-warnings
-          (ring-insert find-tag-marker-ring (point-marker))))
-      (let* ((returned-file (match-string 1 result))
-             (line (string-to-number (match-string 2 result)))
-             (col (string-to-number (match-string 3 result)))
-             (loaded-file (intero-extend-path-by-buffer-host returned-file)))
-        (if (intero-temp-file-p loaded-file)
-            (let ((original-buffer (intero-temp-file-origin-buffer loaded-file)))
-              (if original-buffer
-                  (switch-to-buffer original-buffer)
-                (error "Attempted to load temp file.  Try restarting Intero.
-If the problem persists, please report this as a bug!")))
-          (find-file
-           (expand-file-name
-            returned-file
-            (intero-extend-path-by-buffer-host (intero-project-root)))))
-        (pop-mark)
-        (goto-char (point-min))
-        (forward-line (1- line))
-        (forward-char (1- col))
-        t))))
-
-(defmacro intero-with-dump-splices (exp)
-  "Run EXP but with dump-splices enabled in the intero backend process."
-  `(when (intero-blocking-call 'backend ":set -ddump-splices")
-     (let ((result ,exp))
-       (progn
-         nil ; Disable dump-splices here in future
-         result))))
-
-(defun intero-expand-splice-at-point ()
-  "Show the expansion of the template haskell splice at point."
-  (interactive)
-  (unless (intero-gave-up 'backend)
-    (intero-with-dump-splices
-     (let* ((output (intero-blocking-call
-                     'backend
-                     (concat ":load " (intero-path-for-ghci (intero-temp-file-name)))))
-            (msgs (intero-parse-errors-warnings-splices nil (current-buffer) output))
-            (line (line-number-at-pos))
-            (column (if (save-excursion
-                          (forward-char 1)
-                          (looking-back "$(" 1))
-                        (+ 2 (current-column))
-                      (if (looking-at-p "$(")
-                          (+ 3 (current-column))
-                        (1+ (current-column)))))
-            (expansion-msg
-             (cl-loop for msg in msgs
-                      when (and (eq (flycheck-error-level msg) 'splice)
-                                (= (flycheck-error-line msg) line)
-                                (<= (flycheck-error-column msg) column))
-                      return (flycheck-error-message msg)))
-            (expansion
-             (when expansion-msg
-               (string-trim
-                (replace-regexp-in-string "^Splicing expression" "" expansion-msg)))))
-       (when expansion
-         (message "%s" (intero-fontify-expression expansion)))))))
-
-(defun intero-restart ()
-  "Simply restart the process with the same configuration as before."
-  (interactive)
-  (when (intero-buffer-p 'backend)
-    (let ((targets (buffer-local-value 'intero-targets
-                                       (intero-buffer 'backend)))
-          (stack-yaml (buffer-local-value 'intero-stack-yaml
-                                          (intero-buffer 'backend))))
-      (intero-destroy 'backend)
-      (intero-get-worker-create 'backend targets (current-buffer) stack-yaml)
-      (intero-repl-restart))))
-
-(defun intero-read-targets ()
-  "Read a list of stack targets."
-  (let ((old-targets
-         (buffer-local-value 'intero-targets (intero-buffer 'backend)))
-        (available-targets (intero-get-targets)))
-    (if available-targets
-        (intero-multiswitch
-         "Set the targets to use for stack ghci:"
-         (mapcar (lambda (target)
-                   (list :key target
-                         :title target
-                         :default (member target old-targets)))
-                 available-targets))
-      (split-string (read-from-minibuffer "Targets: " nil nil nil nil old-targets)
-                    " "
-                    t))))
-
-(defun intero-targets (targets save-dir-local)
-  "Set the TARGETS to use for stack ghci.
-When SAVE-DIR-LOCAL is non-nil, save TARGETS as the
-directory-local value for `intero-targets'."
-  (interactive (list (intero-read-targets)
-                     (y-or-n-p "Save selected target(s) in directory local variables for future sessions? ")))
-  (intero-destroy)
-  (intero-get-worker-create 'backend targets (current-buffer))
-  (intero-repl-restart)
-  (when save-dir-local
-    (save-window-excursion
-      (let ((default-directory (intero-project-root)))
-        (add-dir-local-variable 'haskell-mode 'intero-targets targets)
-        (save-buffer)))))
-
-(defun intero-stack-yaml (file save-dir-local)
-  "Change the yaml FILE that intero should tell stack to use.
-Intero will be restarted with the new configuration.  When
-SAVE-DIR-LOCAL is non-nil, save FILE as the directory-local value
-for `intero-stack-yaml'."
-  (interactive (list (read-file-name
-                      "Select YAML config: "
-                      (file-name-as-directory (intero-project-root)))
-                     (y-or-n-p "Save selected stack yaml config in directory local variable for future sessions? ")))
-  (let ((stack-yaml (expand-file-name file)))
-    (setq intero-stack-yaml stack-yaml)
-    (with-current-buffer (intero-buffer 'backend)
-      (setq intero-stack-yaml stack-yaml))
-    (intero-restart)
-    (intero-repl-restart)
-    (when save-dir-local
-      (save-window-excursion
-        (let ((default-directory (intero-project-root)))
-          (add-dir-local-variable 'haskell-mode 'intero-stack-yaml stack-yaml)
-          (save-buffer))))))
-
-(defun intero-destroy (&optional worker)
-  "Stop WORKER and kill its associated process buffer.
-If not provided, WORKER defaults to the current worker process."
-  (interactive)
-  (if worker
-      (intero-delete-worker worker)
-    (intero-delete-worker 'backend)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; DevelMain integration
-
-(defun intero-devel-reload ()
-  "Reload the module `DevelMain' and then run `DevelMain.update'.
-
-This is for doing live update of the code of servers or GUI
-applications.  Put your development version of the program in
-`DevelMain', and define `update' to auto-start the program on a
-new thread, and use the `foreign-store' package to access the
-running context across :load/:reloads in Intero."
-  (interactive)
-  (unwind-protect
-      (with-current-buffer
-          (or (get-buffer "DevelMain.hs")
-              (if (y-or-n-p
-                   "You need to open a buffer named DevelMain.hs.  Find now? ")
-                  (ido-find-file)
-                (error "No DevelMain.hs buffer")))
-        (message "Reloading ...")
-        (intero-async-call
-         'backend
-         ":load DevelMain"
-         (current-buffer)
-         (lambda (buffer reply)
-           (if (string-match-p "^O[Kk], modules loaded" reply)
-               (intero-async-call
-                'backend
-                "DevelMain.update"
-                buffer
-                (lambda (_buffer reply)
-                  (message "DevelMain updated. Output was:\n%s"
-                           reply)))
-             (progn
-               (message "DevelMain FAILED. Switch to DevelMain.hs and compile that.")
-               (switch-to-buffer buffer)
-               (flycheck-buffer)
-               (flycheck-list-errors))))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Flycheck integration
-
-(defun intero-flycheck-enable ()
-  "Enable intero's flycheck support in this buffer."
-  (flycheck-select-checker 'intero)
-  (setq intero-check-last-mod-time nil
-        intero-check-last-results nil)
-  (flycheck-mode))
-
-(defun intero-check (checker cont)
-  "Run a check with CHECKER and pass the status onto CONT."
-  (if (intero-gave-up 'backend)
-      (run-with-timer 0
-                      nil
-                      cont
-                      'interrupted)
-    (let* ((file-buffer (current-buffer))
-           (staging-file (intero-path-for-ghci (intero-staging-file-name)))
-           (temp-file (intero-path-for-ghci (intero-temp-file-name))))
-      ;; We queue up to :move the staging file to the target temp
-      ;; file, which also updates its modified time.
-      (intero-async-call
-       'backend
-       (format ":move %s %s" staging-file temp-file))
-      ;; We load up the target temp file, which has only been updated
-      ;; by the copy above.
-      (intero-async-call
-       'backend
-       (concat ":load " temp-file)
-       (list :cont cont
-             :file-buffer file-buffer
-             :checker checker)
-       (lambda (state string)
-         (with-current-buffer (plist-get state :file-buffer)
-           (let* ((compile-ok (string-match "O[Kk], modules loaded: \\(.*\\)\\.$" string))
-                  (modules (match-string 1 string))
-                  (msgs (intero-parse-errors-warnings-splices
-                         (plist-get state :checker)
-                         (current-buffer)
-                         string)))
-             (intero-collect-compiler-messages msgs)
-             (let ((results (cl-remove-if (lambda (msg)
-                                            (eq 'splice (flycheck-error-level msg)))
-                                          msgs)))
-               (setq intero-check-last-results results)
-               (funcall (plist-get state :cont) 'finished results))
-             (when compile-ok
-               (intero-async-call 'backend
-                                  (concat ":module + "
-                                          (replace-regexp-in-string "," "" modules))
-                                  nil
-                                  (lambda (_st _))))))))
-      ;; We sleep for at least one second to allow a buffer period
-      ;; between module updates. GHCi will consider a module Foo to be
-      ;; unchanged even if its filename has changed or timestmap has
-      ;; changed, if the timestamp is less than 1 second.
-      (intero-async-call
-       'backend
-       ":sleep 1"))))
-
-(flycheck-define-generic-checker 'intero
-  "A syntax and type checker for Haskell using an Intero worker
-process."
-  :start 'intero-check
-  :modes '(haskell-mode literate-haskell-mode)
-  :predicate (lambda () intero-mode))
-
-(add-to-list 'flycheck-checkers 'intero)
-
-(defun intero-parse-errors-warnings-splices (checker buffer string)
-  "Parse flycheck errors and warnings.
-CHECKER and BUFFER are added to each item parsed from STRING."
-  (intero-with-temp-buffer
-    (insert string)
-    (goto-char (point-min))
-    (let ((messages (list))
-          (temp-file (intero-temp-file-name buffer))
-          (found-error-as-warning nil))
-      (while (search-forward-regexp
-              (concat "[\r\n]\\([A-Z]?:?[^ \r\n:][^:\n\r]+\\):\\([0-9()-:]+\\):"
-                      "[ \n\r]+\\([[:unibyte:][:nonascii:]]+?\\)\n[^ ]")
-              nil t 1)
-        (let* ((local-file (intero-canonicalize-path (match-string 1)))
-               (file (intero-extend-path-by-buffer-host local-file buffer))
-               (location-raw (match-string 2))
-               (msg (replace-regexp-in-string
-                     "[\n\r ]*|$"
-                     ""
-                     (match-string 3))) ;; Replace gross bullet points.
-               (type (cond ((string-match "^Warning:" msg)
-                            (setq msg (replace-regexp-in-string "^Warning: *" "" msg))
-                            (if (string-match-p
-                                 (rx bol
-                                     "["
-                                     (or "-Wdeferred-type-errors"
-                                         "-Wdeferred-out-of-scope-variables"
-                                         "-Wtyped-holes")
-                                     "]")
-                                 msg)
-                                (progn (setq found-error-as-warning t)
-                                       'error)
-                              'warning))
-                           ((string-match-p "^Splicing " msg) 'splice)
-                           (t                                 'error)))
-               (location (intero-parse-error
-                          (concat local-file ":" location-raw ": x")))
-               (line (plist-get location :line))
-               (column (plist-get location :col)))
-          (setq messages
-                (cons (flycheck-error-new-at
-                       line column type
-                       msg
-                       :checker checker
-                       :buffer buffer
-                       :filename (if (intero-paths-for-same-file temp-file file)
-                                     (intero-buffer-file-name buffer)
-                                   file))
-                      messages)))
-        (forward-line -1))
-      (delete-dups
-       (if found-error-as-warning
-           (cl-remove-if (lambda (msg) (eq 'warning (flycheck-error-level msg))) messages)
-         messages)))))
-
-(defconst intero-error-regexp-alist
-  `((,(concat
-       "^ *\\(?1:[^\t\r\n]+?\\):"
-       "\\(?:"
-       "\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)\\(?:-\\(?5:[0-9]+\\)\\)?" ;; "121:1" & "12:3-5"
-       "\\|"
-       "(\\(?2:[0-9]+\\),\\(?4:[0-9]+\\))-(\\(?3:[0-9]+\\),\\(?5:[0-9]+\\))" ;; "(289,5)-(291,36)"
-       "\\)"
-       ":\\(?6: Warning:\\)?")
-     1 (2 . 3) (4 . 5) (6 . nil)) ;; error/warning locus
-
-    ;; multiple declarations
-    ("^    \\(?:Declared at:\\|            \\) \\(?1:[^ \t\r\n]+\\):\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)$"
-     1 2 4 0) ;; info locus
-
-    ;; this is the weakest pattern as it's subject to line wrapping et al.
-    (" at \\(?1:[^ \t\r\n]+\\):\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)\\(?:-\\(?5:[0-9]+\\)\\)?[)]?$"
-     1 2 (4 . 5) 0)) ;; info locus
-  "Regexps used for matching GHC compile messages.")
-
-(defun intero-parse-error (string)
-  "Parse the line number from the error in STRING."
-  (save-match-data
-    (when (string-match (mapconcat #'car intero-error-regexp-alist "\\|")
-                        string)
-      (let ((string3 (match-string 3 string))
-            (string5 (match-string 5 string)))
-        (list :file (match-string 1 string)
-              :line (string-to-number (match-string 2 string))
-              :col (string-to-number (match-string 4 string))
-              :line2 (when string3
-                       (string-to-number string3))
-              :col2 (when string5
-                      (string-to-number string5)))))))
-
-(defun intero-call-in-buffer (buffer func &rest args)
-  "In BUFFER, call FUNC with ARGS."
-  (with-current-buffer buffer
-    (apply func args)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Traditional completion-at-point function
-
-(defun intero-completion-at-point ()
-  "A (blocking) function suitable for use in `completion-at-point-functions'."
-  (let ((prefix-info (intero-completions-grab-prefix)))
-    (when prefix-info
-      (cl-destructuring-bind
-          (beg end prefix _type) prefix-info
-        (let ((completions
-               (intero-completion-response-to-list
-                (intero-blocking-call
-                 'backend
-                 (format ":complete repl %S" prefix)))))
-          (when completions
-            (list beg end completions)))))))
-
-(defun intero-repl-completion-at-point ()
-  "A (blocking) function suitable for use in `completion-at-point-functions'.
-Should only be used in the repl"
-  (let* ((beg (save-excursion (intero-repl-beginning-of-line) (point)))
-         (end (point))
-         (str (buffer-substring-no-properties beg end))
-         (repl-buffer (current-buffer))
-         (proc (get-buffer-process (current-buffer))))
-    (with-temp-buffer
-      (comint-redirect-send-command-to-process
-       (format ":complete repl %S" str) ;; command
-       (current-buffer) ;; output buffer
-       proc ;; target process
-       nil  ;; echo
-       t)   ;; no-display
-      (while (not (with-current-buffer repl-buffer
-                    comint-redirect-completed))
-        (sleep-for 0.01))
-      (let* ((completions (intero-completion-response-to-list (buffer-string)))
-             (first-line (car completions)))
-        (when (string-match "[^ ]* [^ ]* " first-line) ;; "2 2 :load src/"
-          (setq first-line (replace-match "" nil nil first-line))
-          (list (+ beg (length first-line)) end (cdr completions)))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Company integration (auto-completion)
-
-(defconst intero-pragmas
-  '("CONLIKE" "SCC" "DEPRECATED" "INCLUDE" "INCOHERENT" "INLINABLE" "INLINE"
-    "LANGUAGE" "LINE" "MINIMAL" "NOINLINE" "NOUNPACK" "OPTIONS" "OPTIONS_GHC"
-    "OVERLAPPABLE" "OVERLAPPING" "OVERLAPS" "RULES" "SOURCE" "SPECIALIZE"
-    "UNPACK" "WARNING")
-  "Pragmas that GHC supports.")
-
-(defun intero-company (command &optional arg &rest ignored)
-  "Company source for intero, with the standard COMMAND and ARG args.
-Other arguments are IGNORED."
-  (interactive (list 'interactive))
-  (cl-case command
-    (interactive (company-begin-backend 'intero-company))
-    (prefix
-     (unless (intero-gave-up 'backend)
-       (or (let ((hole (intero-grab-hole)))
-             (when hole
-               (save-excursion
-                 (goto-char (cdr hole))
-                 (buffer-substring (car hole) (cdr hole)))))
-           (let ((prefix-info (intero-completions-grab-prefix)))
-             (when prefix-info
-               (cl-destructuring-bind
-                   (beg end prefix _type) prefix-info
-                 prefix))))))
-    (candidates
-     (unless (intero-gave-up 'backend)
-       (let ((beg-end (intero-grab-hole)))
-         (if beg-end
-             (cons :async
-                   (-partial 'intero-async-fill-at
-                             (current-buffer)
-                             (car beg-end)))
-           (let ((prefix-info (intero-completions-grab-prefix)))
-             (when prefix-info
-               (cons :async
-                     (-partial 'intero-company-callback
-                               (current-buffer)
-                               prefix-info))))))))))
-
-(define-obsolete-function-alias 'company-intero 'intero-company)
-
-(defun intero-company-callback (source-buffer prefix-info cont)
-  "Generate completions for SOURCE-BUFFER based on PREFIX-INFO and call CONT on the results."
-  (cl-destructuring-bind
-      (beg end prefix type) prefix-info
-    (or (and (bound-and-true-p intero-mode)
-             (cl-case type
-               (haskell-completions-module-name-prefix
-                (intero-get-repl-completions source-buffer (concat "import " prefix) cont)
-                t)
-               (haskell-completions-identifier-prefix
-                (intero-get-completions source-buffer beg end cont)
-                t)
-               (haskell-completions-language-extension-prefix
-                (intero-get-repl-completions
-                 source-buffer
-                 (concat ":set -X" prefix)
-                 (-partial (lambda (cont results)
-                             (funcall cont
-                                      (mapcar (lambda (x)
-                                                (replace-regexp-in-string "^-X" "" x))
-                                              results)))
-                           cont))
-                t)
-               (haskell-completions-pragma-name-prefix
-                (funcall cont
-                         (cl-remove-if-not
-                          (lambda (candidate)
-                            (string-prefix-p prefix candidate))
-                          intero-pragmas))
-                t)))
-        (intero-get-repl-completions source-buffer prefix cont))))
-
-(defun intero-completions-grab-prefix (&optional minlen)
-  "Grab prefix at point for possible completion.
-If specified, MINLEN is the shortest completion which will be
-considered."
-  (when (intero-completions-can-grab-prefix)
-    (let ((prefix (cond
-                   ((intero-completions-grab-pragma-prefix))
-                   ((intero-completions-grab-identifier-prefix)))))
-      (cond ((and minlen prefix)
-             (when (>= (length (nth 2 prefix)) minlen)
-               prefix))
-            (prefix prefix)))))
-
-(defun intero-completions-can-grab-prefix ()
-  "Check if the case is appropriate for grabbing completion prefix."
-  (when (not (region-active-p))
-    (when (looking-at-p (rx (| space line-end punct)))
-      (when (not (bobp))
-        (save-excursion
-          (backward-char)
-          (not (looking-at-p (rx (| space line-end)))))))))
-
-(defun intero-completions-grab-identifier-prefix ()
-  "Grab identifier prefix."
-  (let ((pos-at-point (intero-ident-pos-at-point))
-        (p (point)))
-    (when pos-at-point
-      (let* ((start (car pos-at-point))
-             (end (cdr pos-at-point))
-             (type 'haskell-completions-identifier-prefix)
-             (case-fold-search nil)
-             value)
-        (when (<= p end)
-          (setq end p)
-          (setq value (buffer-substring-no-properties start end))
-          (when (string-match-p (rx bos upper) value)
-            (save-excursion
-              (goto-char (line-beginning-position))
-              (when (re-search-forward
-                     (rx "import"
-                         (? (1+ space) "qualified")
-                         (1+ space)
-                         upper
-                         (1+ (| alnum ".")))
-                     p    ;; bound
-                     t)   ;; no-error
-                (if (equal p (point))
-                    (setq type 'haskell-completions-module-name-prefix)
-                  (when (re-search-forward
-                         (rx (| " as " "("))
-                         start
-                         t)
-                    (setq type 'haskell-completions-identifier-prefix))))))
-          (when (nth 8 (syntax-ppss))
-            (setq type 'haskell-completions-general-prefix))
-          (when value (list start end value type)))))))
-
-(defun intero-completions-grab-pragma-prefix ()
-  "Grab completion prefix for pragma completions.
-Returns a list of form '(prefix-start-position
-prefix-end-position prefix-value prefix-type) for pramga names
-such as WARNING, DEPRECATED, LANGUAGE etc.  Also returns
-completion prefixes for options in case OPTIONS_GHC pragma, or
-language extensions in case of LANGUAGE pragma.  Obsolete OPTIONS
-pragma is supported also."
-  (when (nth 4 (syntax-ppss))
-    ;; We're inside comment
-    (let ((p (point))
-          (comment-start (nth 8 (syntax-ppss)))
-          (case-fold-search nil)
-          prefix-start
-          prefix-end
-          prefix-type
-          prefix-value)
-      (save-excursion
-        (goto-char comment-start)
-        (when (looking-at (rx "{-#" (1+ (| space "\n"))))
-          (let ((pragma-start (match-end 0)))
-            (when (> p pragma-start)
-              ;; point stands after `{-#`
-              (goto-char pragma-start)
-              (when (looking-at (rx (1+ (| upper "_"))))
-                ;; found suitable sequence for pragma name
-                (let ((pragma-end (match-end 0))
-                      (pragma-value (match-string-no-properties 0)))
-                  (if (eq p pragma-end)
-                      ;; point is at the end of (in)complete pragma name
-                      ;; prepare resulting values
-                      (progn
-                        (setq prefix-start pragma-start)
-                        (setq prefix-end pragma-end)
-                        (setq prefix-value pragma-value)
-                        (setq prefix-type
-                              'haskell-completions-pragma-name-prefix))
-                    (when (and (> p pragma-end)
-                               (or (equal "OPTIONS_GHC" pragma-value)
-                                   (equal "OPTIONS" pragma-value)
-                                   (equal "LANGUAGE" pragma-value)))
-                      ;; point is after pragma name, so we need to check
-                      ;; special cases of `OPTIONS_GHC` and `LANGUAGE` pragmas
-                      ;; and provide a completion prefix for possible ghc
-                      ;; option or language extension.
-                      (goto-char pragma-end)
-                      (when (re-search-forward
-                             (rx (* anything)
-                                 (1+ (regexp "\\S-")))
-                             p
-                             t)
-                        (let* ((str (match-string-no-properties 0))
-                               (split (split-string str (rx (| space "\n")) t))
-                               (val (car (last split)))
-                               (end (point)))
-                          (when (and (equal p end)
-                                     (not (string-match-p "#" val)))
-                            (setq prefix-value val)
-                            (backward-char (length val))
-                            (setq prefix-start (point))
-                            (setq prefix-end end)
-                            (setq
-                             prefix-type
-                             (if (not (equal "LANGUAGE" pragma-value))
-                                 'haskell-completions-ghc-option-prefix
-                               'haskell-completions-language-extension-prefix
-                               )))))))))))))
-      (when prefix-value
-        (list prefix-start prefix-end prefix-value prefix-type)))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Hole filling
-
-(defun intero-async-fill-at (buffer beg cont)
-  "Make the blocking call to the process."
-  (with-current-buffer buffer
-    (intero-async-call
-     'backend
-     (format
-      ":fill %s %d %d"
-      (intero-path-for-ghci (intero-temp-file-name))
-      (save-excursion (goto-char beg)
-                      (line-number-at-pos))
-      (save-excursion (goto-char beg)
-                      (1+ (current-column))))
-     (list :buffer (current-buffer) :cont cont)
-     (lambda (state reply)
-       (if (or (string-match "^Couldn't guess" reply)
-               (string-match "^Unable to " reply)
-               (intero-parse-error reply))
-           (funcall (plist-get state :cont) (list))
-         (with-current-buffer (plist-get state :buffer)
-           (let ((candidates
-                  (split-string
-                   (replace-regexp-in-string
-                    "\n$" ""
-                    reply)
-                   "[\r\n]"
-                   t)))
-             (when candidates
-               (funcall (plist-get state :cont) candidates)))))))))
-
-(defun intero-grab-hole ()
-  "When user is at a hole _ or _foo, return the starting point of
-that hole."
-  (let ((beg-end (intero-ident-pos-at-point)))
-    (when beg-end
-      (let ((string (buffer-substring-no-properties (car beg-end) (cdr beg-end))))
-        (when (string-match-p "^_" string)
-          beg-end)))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; ELDoc integration
-
-(defvar-local intero-eldoc-cache (make-hash-table :test 'equal)
-  "Cache for types of regions, used by `intero-eldoc'.
-This is not for saving on requests (we make a request even if
-something is in cache, overwriting the old entry), but rather for
-making types show immediately when we do have them cached.")
-
-(defun intero-eldoc-maybe-print (msg)
-  "Print MSG with eldoc if eldoc would display a message now.
-Like `eldoc-print-current-symbol-info', but just printing MSG
-instead of using `eldoc-documentation-function'."
-  (with-demoted-errors "eldoc error: %s"
-    (and (or (eldoc-display-message-p)
-             ;; Erase the last message if we won't display a new one.
-             (when eldoc-last-message
-               (eldoc-message nil)
-               nil))
-         (eldoc-message msg))))
-
-(defun intero-eldoc ()
-  "ELDoc backend for intero."
-  (let ((buffer (intero-buffer 'backend)))
-    (when (and buffer (process-live-p (get-buffer-process buffer)))
-      (apply #'intero-get-type-at-async
-             (lambda (beg end ty)
-               (let ((response-status (intero-haskell-utils-repl-response-error-status ty)))
-                 (if (eq 'no-error response-status)
-                     (let ((msg (intero-fontify-expression
-                                 (replace-regexp-in-string "[ \n]+" " " ty))))
-                       ;; Got an updated type-at-point, cache and print now:
-                       (puthash (list beg end)
-                                msg
-                                intero-eldoc-cache)
-                       (intero-eldoc-maybe-print msg))
-                   ;; But if we're seeing errors, invalidate cache-at-point:
-                   (remhash (list beg end) intero-eldoc-cache))))
-             (intero-thing-at-point))))
-  ;; If we have something cached at point, print that first:
-  (gethash (intero-thing-at-point) intero-eldoc-cache))
-
-(defun intero-haskell-utils-repl-response-error-status (response)
-  "Parse response REPL's RESPONSE for errors.
-Returns one of the following symbols:
-
-+ unknown-command
-+ option-missing
-+ interactive-error
-+ no-error
-
-*Warning*: this funciton covers only three kind of responses:
-
-* \"unknown command …\"
-  REPL missing requested command
-* \"<interactive>:3:5: …\"
-  interactive REPL error
-* \"Couldn't guess that module name. Does it exist?\"
-  (:type-at and maybe some other commands error)
-* *all other reposnses* are treated as success reposneses and
-  'no-error is returned."
-  (let ((first-line (car (split-string response "\n" t))))
-    (cond
-     ((null first-line) 'no-error)
-     ((string-match-p "^unknown command" first-line)
-      'unknown-command)
-     ((string-match-p
-       "^Couldn't guess that module name. Does it exist?"
-       first-line)
-      'option-missing)
-     ((string-match-p "^<interactive>:" first-line)
-      'interactive-error)
-     ((string-match-p "^<no location info>:" first-line)
-      'inspection-error)
-     (t 'no-error))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; REPL
-
-(defconst intero-prompt-regexp "^\4 ")
-
-(defvar-local intero-repl-previous-buffer nil
-  "Records the buffer to which `intero-repl-switch-back' should jump.
-This is set by `intero-repl-buffer', and should otherwise be nil.")
-
-(defun intero-repl-clear-buffer ()
-  "Clear the current REPL buffer."
-  (interactive)
-  (let ((comint-buffer-maximum-size 0))
-    (comint-truncate-buffer)))
-
-(defmacro intero-with-repl-buffer (prompt-options &rest body)
-  "Evaluate given forms with the REPL as the current buffer.
-The REPL will be started if necessary, and the REPL buffer will
-be activated after evaluation.  PROMPT-OPTIONS are passed to
-`intero-repl-buffer'.  BODY is the forms to be evaluated."
-  (declare (indent defun))
-  (let ((repl-buffer (cl-gensym)))
-    `(let ((,repl-buffer (intero-repl-buffer ,prompt-options t)))
-       (with-current-buffer ,repl-buffer
-         ,@body)
-       (when intero-pop-to-repl
-         (pop-to-buffer ,repl-buffer)))))
-
-(defun intero-repl-after-load ()
-  "Set the command to run after load."
-  (interactive)
-  (if (eq major-mode 'intero-repl-mode)
-      (setq intero-repl-send-after-load
-            (read-from-minibuffer
-             "Command to run: "
-             (or intero-repl-send-after-load
-                 (car (ring-elements comint-input-ring))
-                 "")))
-    (error "Run this in the REPL.")))
-
-(defun intero-repl-load (&optional prompt-options)
-  "Load the current file in the REPL.
-If PROMPT-OPTIONS is non-nil, prompt with an options list."
-  (interactive "P")
-  (save-buffer)
-  (let ((file (intero-path-for-ghci (intero-buffer-file-name))))
-    (intero-with-repl-buffer prompt-options
-      (comint-simple-send
-         (get-buffer-process (current-buffer))
-         ":set prompt \"\\n\"")
-        (if (or (not intero-repl-last-loaded)
-                (not (equal file intero-repl-last-loaded)))
-            (progn
-              (comint-simple-send
-               (get-buffer-process (current-buffer))
-               (concat ":load " file))
-              (setq intero-repl-last-loaded file))
-          (comint-simple-send
-           (get-buffer-process (current-buffer))
-           ":reload"))
-        (when intero-repl-send-after-load
-          (comint-simple-send
-           (get-buffer-process (current-buffer))
-           intero-repl-send-after-load))
-        (comint-simple-send (get-buffer-process (current-buffer))
-                            ":set prompt \"\\4 \""))))
-
-(defun intero-repl-eval-region (begin end &optional prompt-options)
-  "Evaluate the code in region from BEGIN to END in the REPL.
-If the region is unset, the current line will be used.
-PROMPT-OPTIONS are passed to `intero-repl-buffer' if supplied."
-  (interactive "r")
-  (unless (use-region-p)
-    (setq begin (line-beginning-position)
-          end (line-end-position)))
-  (let ((text (buffer-substring-no-properties begin end)))
-    (intero-with-repl-buffer prompt-options
-      (comint-simple-send
-       (get-buffer-process (current-buffer))
-       text))))
-
-(defun intero-repl (&optional prompt-options)
-  "Start up the REPL for this stack project.
-If PROMPT-OPTIONS is non-nil, prompt with an options list."
-  (interactive "P")
-  (switch-to-buffer-other-window (intero-repl-buffer prompt-options t)))
-
-(defun intero-repl-restart ()
-  "Restart the REPL."
-  (interactive)
-  (let* ((root (intero-project-root))
-         (package-name (intero-package-name))
-         (backend-buffer (intero-buffer 'backend))
-         (name (format "*intero:%s:%s:repl*"
-                       (file-name-nondirectory root)
-                       package-name)))
-    (when (get-buffer name)
-      (with-current-buffer (get-buffer name)
-        (goto-char (point-max))
-        (let ((process (get-buffer-process (current-buffer))))
-          (when process (kill-process process)))
-        (intero-repl-mode-start backend-buffer
-                                (buffer-local-value 'intero-targets backend-buffer)
-                                nil
-                                (buffer-local-value 'intero-stack-yaml backend-buffer))))))
-
-(defun intero-repl-buffer (prompt-options &optional store-previous)
-  "Start the REPL buffer.
-If PROMPT-OPTIONS is non-nil, prompt with an options list.  When
-STORE-PREVIOUS is non-nil, note the caller's buffer in
-`intero-repl-previous-buffer'."
-  (let* ((root (intero-project-root))
-         (package-name (intero-package-name))
-         (name (format "*intero:%s:%s:repl*"
-                       (file-name-nondirectory root)
-                       package-name))
-         (initial-buffer (current-buffer))
-         (backend-buffer (intero-buffer 'backend)))
-    (with-current-buffer
-        (or (get-buffer name)
-            (with-current-buffer
-                (get-buffer-create name)
-              ;; The new buffer doesn't know if the initial buffer was hosted
-              ;; remotely or not, so we need to extend by the host of the
-              ;; initial buffer to cd. We could also achieve this by setting the
-              ;; buffer's intero-buffer-host, but intero-repl-mode wipes this, so
-              ;; we defer setting that until after.
-              (cd (intero-extend-path-by-buffer-host root initial-buffer))
-              (intero-repl-mode) ; wipes buffer-local variables
-              (intero-inherit-local-variables initial-buffer)
-              (setq intero-buffer-host (intero-buffer-host initial-buffer))
-              (intero-repl-mode-start backend-buffer
-                                      (buffer-local-value 'intero-targets backend-buffer)
-                                      prompt-options
-                                      (buffer-local-value 'intero-stack-yaml backend-buffer))
-              (current-buffer)))
-      (progn
-        (when store-previous
-          (setq intero-repl-previous-buffer initial-buffer))
-        (current-buffer)))))
-
-(defvar intero-hyperlink-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map [mouse-1]  'intero-find-file-with-line-and-char)
-    (define-key map [C-return] 'intero-find-file-with-line-and-char)
-    map)
-  "Keymap for clicking on links in REPL.")
-
-(define-derived-mode intero-repl-mode comint-mode "Intero-REPL"
-  "Interactive prompt for Intero."
-  (when (and (not (eq major-mode 'fundamental-mode))
-             (eq this-command 'intero-repl-mode))
-    (error "You probably meant to run: M-x intero-repl"))
-  (setq-local comint-prompt-regexp intero-prompt-regexp)
-  (setq-local warning-suppress-types (cons '(undo discard-info) warning-suppress-types))
-  (setq-local comint-prompt-read-only t)
-  (add-hook 'completion-at-point-functions 'intero-repl-completion-at-point nil t)
-  (company-mode))
-
-(defun intero-repl-mode-start (backend-buffer targets prompt-options stack-yaml)
-  "Start the process for the repl in the current buffer.
-BACKEND-BUFFER is used for options.  TARGETS is the targets to
-load.  If PROMPT-OPTIONS is non-nil, prompt with an options list.
-STACK-YAML is the stack yaml config to use.  When nil, tries to
-use project-wide intero-stack-yaml when nil, otherwise uses
-stack's default)."
-  (setq intero-targets targets)
-  (setq intero-repl-last-loaded nil)
-  (when stack-yaml
-    (setq intero-stack-yaml stack-yaml))
-  (when prompt-options
-    (intero-repl-options backend-buffer))
-  (let ((stack-yaml (if stack-yaml
-                        stack-yaml
-                      (buffer-local-value 'intero-stack-yaml backend-buffer)))
-        (arguments (intero-make-options-list
-                    "ghci"
-                    (or targets
-                        (let ((package-name (buffer-local-value 'intero-package-name
-                                                                backend-buffer)))
-                          (unless (equal "" package-name)
-                            (list package-name))))
-                    (buffer-local-value 'intero-repl-no-build backend-buffer)
-                    (buffer-local-value 'intero-repl-no-load backend-buffer)
-                    nil
-                    stack-yaml)))
-    (insert (propertize
-             (format "Starting:\n  %s ghci %s\n" intero-stack-executable
-                     (combine-and-quote-strings arguments))
-             'face 'font-lock-comment-face))
-    (let* ((script-buffer
-            (with-current-buffer (find-file-noselect (intero-make-temp-file "intero-script"))
-              (insert ":set prompt \"\"
-:set -fbyte-code
-:set -fdefer-type-errors
-:set -fdiagnostics-color=never
-:set prompt \"\\4 \"
-")
-              (basic-save-buffer)
-              (current-buffer)))
-           (script
-            (with-current-buffer script-buffer
-              (intero-localize-path (intero-buffer-file-name)))))
-      (let ((process
-             (get-buffer-process
-              (apply #'make-comint-in-buffer "intero" (current-buffer) intero-stack-executable nil "ghci"
-                     (append arguments
-                             (list "--verbosity" "silent")
-                             (list "--ghci-options"
-                                   (concat "-ghci-script=" script))
-                             (cl-mapcan (lambda (x) (list "--ghci-options" x)) intero-extra-ghci-options))))))
-        (when (process-live-p process)
-          (set-process-query-on-exit-flag process nil)
-          (message "Started Intero process for REPL.")
-          (kill-buffer script-buffer))))))
-
-(defun intero-repl-options (backend-buffer)
-  "Open an option menu to set options used when starting the REPL.
-Default options come from user customization and any temporary
-changes in the BACKEND-BUFFER."
-  (interactive)
-  (let* ((old-options
-          (list
-           (list :key "load-all"
-                 :title "Load all modules"
-                 :default (not (buffer-local-value 'intero-repl-no-load backend-buffer)))
-           (list :key "build-first"
-                 :title "Build project first"
-                 :default (not (buffer-local-value 'intero-repl-no-build backend-buffer)))))
-         (new-options (intero-multiswitch "Start REPL with options:" old-options)))
-    (with-current-buffer backend-buffer
-      (setq-local intero-repl-no-load (not (member "load-all" new-options)))
-      (setq-local intero-repl-no-build (not (member "build-first" new-options))))))
-
-(font-lock-add-keywords
- 'intero-repl-mode
- '(("\\(\4\\)"
-    (0 (prog1 ()
-         (compose-region (match-beginning 1)
-                         (match-end 1)
-                         ?λ))))))
-
-(define-key intero-repl-mode-map [remap move-beginning-of-line] 'intero-repl-beginning-of-line)
-(define-key intero-repl-mode-map [remap delete-backward-char] 'intero-repl-delete-backward-char)
-(define-key intero-repl-mode-map (kbd "C-c C-k") 'intero-repl-clear-buffer)
-(define-key intero-repl-mode-map (kbd "C-c C-z") 'intero-repl-switch-back)
-
-(defun intero-repl-delete-backward-char ()
-  "Delete backwards, excluding the prompt."
-  (interactive)
-  (unless (looking-back intero-prompt-regexp (line-beginning-position))
-    (call-interactively 'delete-backward-char)))
-
-(defun intero-repl-beginning-of-line ()
-  "Go to the beginning of the line, excluding the prompt."
-  (interactive)
-  (if (search-backward-regexp intero-prompt-regexp (line-beginning-position) t 1)
-      (goto-char (+ 2 (line-beginning-position)))
-    (call-interactively 'move-beginning-of-line)))
-
-(defun intero-repl-switch-back ()
-  "Switch back to the buffer from which this REPL buffer was reached."
-  (interactive)
-  (if intero-repl-previous-buffer
-      (switch-to-buffer-other-window intero-repl-previous-buffer)
-    (message "No previous buffer.")))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Buffer operations
-
-(defun intero-thing-at-point ()
-  "Return (list START END) of something at the point."
-  (if (region-active-p)
-      (list (region-beginning)
-            (region-end))
-    (let ((pos (intero-ident-pos-at-point)))
-      (if pos
-          (list (car pos) (cdr pos))
-        (list (point) (point))))))
-
-(defun intero-ident-at-point ()
-  "Return the identifier under point, or nil if none found.
-May return a qualified name."
-  (let ((reg (intero-ident-pos-at-point)))
-    (when reg
-      (buffer-substring-no-properties (car reg) (cdr reg)))))
-
-(defun intero-ident-pos-at-point ()
-  "Return the span of the identifier near point going backward.
-Returns nil if no identifier found or point is inside string or
-comment.  May return a qualified name."
-  (when (not (nth 8 (syntax-ppss)))
-    ;; Do not handle comments and strings
-    (let (start end)
-      ;; Initial point position is non-deterministic, it may occur anywhere
-      ;; inside identifier span, so the approach is:
-      ;; - first try go left and find left boundary
-      ;; - then try go right and find right boundary
-      ;;
-      ;; In both cases assume the longest path, e.g. when going left take into
-      ;; account than point may occur at the end of identifier, when going right
-      ;; take into account that point may occur at the beginning of identifier.
-      ;;
-      ;; We should handle `.` character very careful because it is heavily
-      ;; overloaded.  Examples of possible cases:
-      ;; Control.Monad.>>=  -- delimiter
-      ;; Control.Monad.when -- delimiter
-      ;; Data.Aeson..:      -- delimiter and operator symbol
-      ;; concat.map         -- composition function
-      ;; .?                 -- operator symbol
-      (save-excursion
-        ;; First, skip whitespace if we're on it, moving point to last
-        ;; identifier char.  That way, if we're at "map ", we'll see the word
-        ;; "map".
-        (when (and (looking-at-p (rx eol))
-                   (not (bolp)))
-          (backward-char))
-        (when (and (not (eobp))
-                   (eq (char-syntax (char-after)) ? ))
-          (skip-chars-backward " \t")
-          (backward-char))
-        ;; Now let's try to go left.
-        (save-excursion
-          (if (not (intero-mode--looking-at-varsym))
-              ;; Looking at non-operator char, this is quite simple
-              (progn
-                (skip-syntax-backward "w_")
-                ;; Remember position
-                (setq start (point)))
-            ;; Looking at operator char.
-            (while (and (not (bobp))
-                        (intero-mode--looking-at-varsym))
-              ;; skip all operator chars backward
-              (setq start (point))
-              (backward-char))
-            ;; Extra check for case when reached beginning of the buffer.
-            (when (intero-mode--looking-at-varsym)
-              (setq start (point))))
-          ;; Slurp qualification part if present.  If identifier is qualified in
-          ;; case of non-operator point will stop before `.` dot, but in case of
-          ;; operator it will stand at `.` delimiting dot.  So if we're looking
-          ;; at `.` let's step one char forward and try to get qualification
-          ;; part.
-          (goto-char start)
-          (when (looking-at-p (rx "."))
-            (forward-char))
-          (let ((pos (intero-mode--skip-qualification-backward)))
-            (when pos
-              (setq start pos))))
-        ;; Finally, let's try to go right.
-        (save-excursion
-          ;; Try to slurp qualification part first.
-          (skip-syntax-forward "w_")
-          (setq end (point))
-          (while (and (looking-at-p (rx "." upper))
-                      (not (zerop (progn (forward-char)
-                                         (skip-syntax-forward "w_")))))
-            (setq end (point)))
-          ;; If point was at non-operator we already done, otherwise we need an
-          ;; extra check.
-          (while (intero-mode--looking-at-varsym)
-            (forward-char)
-            (setq end (point))))
-        (when (not (= start end))
-          (cons start end))))))
-
-(defun intero-mode--looking-at-varsym ()
-  "Return t when point stands at operator symbol."
-  (when (not (eobp))
-    (let ((lex (intero-lexeme-classify-by-first-char (char-after))))
-      (or (eq lex 'varsym)
-          (eq lex 'consym)))))
-
-(defun intero-mode--skip-qualification-backward ()
-  "Skip qualified part of identifier backward.
-Expects point stands *after* delimiting dot.
-Returns beginning position of qualified part or nil if no qualified part found."
-  (when (not (and (bobp)
-                  (looking-at-p (rx bol))))
-    (let ((case-fold-search nil)
-          pos)
-      (while (and (eq (char-before) ?.)
-                  (progn (backward-char)
-                         (not (zerop (skip-syntax-backward "w'"))))
-                  (skip-syntax-forward "'")
-                  (looking-at-p "[[:upper:]]"))
-        (setq pos (point)))
-      pos)))
-
-(defun intero-lexeme-classify-by-first-char (char)
-  "Classify token by CHAR.
-CHAR is a chararacter that is assumed to be the first character
-of a token."
-  (let ((category (get-char-code-property char 'general-category)))
-
-    (cond
-     ((or (member char '(?! ?# ?$ ?% ?& ?* ?+ ?. ?/ ?< ?= ?> ?? ?@ ?^ ?| ?~ ?\\ ?-))
-          (and (> char 127)
-               (member category '(Pc Pd Po Sm Sc Sk So))))
-      'varsym)
-     ((equal char ?:)
-      'consym)
-     ((equal char ?\')
-      'char)
-     ((equal char ?\")
-      'string)
-     ((member category '(Lu Lt))
-      'conid)
-     ((or (equal char ?_)
-          (member category '(Ll Lo)))
-      'varid)
-     ((and (>= char ?0) (<= char ?9))
-      'number)
-     ((member char '(?\] ?\[ ?\( ?\) ?\{ ?\} ?\` ?\, ?\;))
-      'special))))
-
-(defun intero-buffer-file-name (&optional buffer)
-  "Call function `buffer-file-name' for BUFFER and clean its result.
-The path returned is canonicalized and stripped of any text properties."
-  (let ((name (buffer-file-name buffer)))
-    (when name
-      (intero-canonicalize-path (substring-no-properties name)))))
-
-(defun intero-paths-for-same-file (path-1 path-2)
-  "Compare PATH-1 and PATH-2 to see if they represent the same file."
-  (let ((simplify-path #'(lambda (path)
-                           (if (tramp-tramp-file-p path)
-                               (let* ((dissection (tramp-dissect-file-name path))
-                                      (host (tramp-file-name-host dissection))
-                                      (localname (tramp-file-name-localname dissection)))
-                                 (concat host ":" localname))
-                             (expand-file-name path)))))
-    (string= (funcall simplify-path path-1) (funcall simplify-path path-2))))
-
-(defun intero-buffer-host (&optional buffer)
-  "Get the hostname of the box hosting the file behind the BUFFER."
-  (with-current-buffer (or buffer (current-buffer))
-    (let ((file (intero-buffer-file-name)))
-      (if intero-buffer-host
-          intero-buffer-host
-        (setq intero-buffer-host
-              (when file
-                (if (tramp-tramp-file-p file)
-                    (tramp-file-name-host (tramp-dissect-file-name file))
-                  "")))))))
-
-(defun intero-extend-path-by-buffer-host (path &optional buffer)
-  "Take a PATH, and extend it by the host of the provided BUFFER (default to current buffer).  Return PATH unchanged if the file is local, or the BUFFER has no host."
-  (with-current-buffer (or buffer (current-buffer))
-    (if (or (eq nil (intero-buffer-host)) (eq "" (intero-buffer-host)))
-        path
-      (expand-file-name
-       (concat "/"
-               (intero-buffer-host)
-               ":"
-               path)))))
-
-(defvar-local intero-temp-file-name nil
-  "The name of a temporary file to which the current buffer's content is copied.")
-
-(defun intero-temp-file-p (path)
-  "Is PATH a temp file?"
-  (string= (file-name-directory path)
-           (file-name-directory (intero-temp-file-dir))))
-
-(defun intero-temp-file-origin-buffer (temp-file)
-  "Get the original buffer that TEMP-FILE was created for."
-  (or
-   (gethash (intero-canonicalize-path temp-file)
-            intero-temp-file-buffer-mapping)
-   (cl-loop
-    for buffer in (buffer-list)
-    when (string= (intero-canonicalize-path temp-file)
-                  (buffer-local-value 'intero-temp-file-name buffer))
-    return buffer)))
-
-(defun intero-unmangle-file-path (file)
-  "If FILE is an intero temp file, return the original source path, otherwise FILE."
-  (or (when (intero-temp-file-p file)
-        (let ((origin-buffer (intero-temp-file-origin-buffer file)))
-          (when origin-buffer
-            (buffer-file-name origin-buffer))))
-      file))
-
-(defun intero-make-temp-file (prefix &optional dir-flag suffix)
-  "Like `make-temp-file', but using a different temp directory.
-PREFIX, DIR-FLAG and SUFFIX are all passed to `make-temp-file'
-unmodified.  A different directory is applied so that if docker
-is used with stack, the commands run inside docker can find the
-path."
-  (let ((temporary-file-directory
-         (intero-temp-file-dir)))
-    (make-directory temporary-file-directory t)
-    (make-temp-file prefix dir-flag suffix)))
-
-(defun intero-temp-file-dir ()
-  "Get the temporary file directory for the current intero project."
-  (let* ((intero-absolute-project-root
-          (intero-extend-path-by-buffer-host (intero-project-root)))
-         (temporary-file-directory
-          (expand-file-name ".stack-work/intero/"
-                            intero-absolute-project-root)))
-    temporary-file-directory))
-
-(defun intero-temp-file-name (&optional buffer)
-  "Return the name of a temp file pertaining to BUFFER."
-  (with-current-buffer (or buffer (current-buffer))
-    (or intero-temp-file-name
-        (progn (setq intero-temp-file-name
-                     (intero-canonicalize-path
-                      (intero-make-temp-file
-                       "intero" nil
-                       (concat "-TEMP." (if (buffer-file-name)
-                                            (file-name-extension (buffer-file-name))
-                                          "hs")))))
-               (puthash intero-temp-file-name
-                        (current-buffer)
-                        intero-temp-file-buffer-mapping)
-               intero-temp-file-name))))
-
-(defun intero-staging-file-name (&optional buffer)
-  "Return the name of a temp file containing an up-to-date copy of BUFFER's contents."
-  (with-current-buffer (or buffer (current-buffer))
-    (let* ((contents (buffer-string))
-           (fname (intero-canonicalize-path
-                   (intero-make-temp-file
-                    "intero" nil
-                    (concat "-STAGING." (if (buffer-file-name)
-                                            (file-name-extension (buffer-file-name))
-                                          "hs"))))))
-      (with-temp-file fname
-        (insert contents))
-      fname)))
-
-(defun intero-quote-path-for-ghci (path)
-  "Quote PATH as necessary so that it can be passed to a GHCi :command."
-  (concat "\"" (replace-regexp-in-string "\\([\\\"]\\)" "\\\\\\1" path nil nil) "\""))
-
-(defun intero-path-for-ghci (path)
-  "Turn a possibly-remote PATH into one that can be passed to a GHCi :command."
-  (intero-quote-path-for-ghci (intero-localize-path path)))
-
-(defun intero-localize-path (path)
-  "Turn a possibly-remote PATH to a purely local one.
-This is used to create paths which a remote intero process can load."
-  (if (tramp-tramp-file-p path)
-      (tramp-file-name-localname (tramp-dissect-file-name path))
-    path))
-
-(defun intero-canonicalize-path (path)
-  "Return a standardized version of PATH.
-Path names are standardised and drive names are
-capitalized (relevant on Windows)."
-  (intero-capitalize-drive-letter (convert-standard-filename path)))
-
-(defun intero-capitalize-drive-letter (path)
-  "Ensures the drive letter is capitalized in PATH.
-This applies to paths of the form
-x:\\foo\\bar (i.e., Windows)."
-  (save-match-data
-    (let ((drive-path (split-string path ":\\\\")))
-      (if (or (null (car drive-path)) (null (cdr drive-path)))
-          path
-        (concat (upcase (car drive-path)) ":\\" (cadr drive-path))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Query/commands
-
-(defun intero-get-all-types ()
-  "Get all types in all expressions in all modules."
-  (intero-blocking-network-call 'backend ":all-types"))
-
-(defun intero-get-type-at (beg end)
-  "Get the type at the given region denoted by BEG and END."
-  (let ((result (intero-get-type-at-helper beg end)))
-    (if (string-match (regexp-quote "Couldn't guess that module name. Does it exist?")
-                      result)
-        (progn (flycheck-buffer)
-               (message "No type information yet, compiling module ...")
-               (intero-get-type-at-helper-process beg end))
-      result)))
-
-(defun intero-get-type-at-helper (beg end)
-  (replace-regexp-in-string
-   "\n$" ""
-   (intero-blocking-network-call
-    'backend
-    (intero-format-get-type-at beg end))))
-
-(defun intero-get-type-at-helper-process (beg end)
-  (replace-regexp-in-string
-   "\n$" ""
-   (intero-blocking-call
-    'backend
-    (intero-format-get-type-at beg end))))
-
-(defun intero-get-type-at-async (cont beg end)
-  "Call CONT with type of the region denoted by BEG and END.
-CONT is called within the current buffer, with BEG, END and the
-type as arguments."
-  (intero-async-network-call
-   'backend
-   (intero-format-get-type-at beg end)
-   (list :cont cont
-         :source-buffer (current-buffer)
-         :beg beg
-         :end end)
-   (lambda (state reply)
-     (with-current-buffer (plist-get state :source-buffer)
-       (funcall (plist-get state :cont)
-                (plist-get state :beg)
-                (plist-get state :end)
-                (replace-regexp-in-string "\n$" "" reply))))))
-
-(defun intero-format-get-type-at (beg end)
-  "Compose a request for getting types in region from BEG to END."
-  (format ":type-at %s %d %d %d %d %S"
-          (intero-path-for-ghci (intero-temp-file-name))
-          (save-excursion (goto-char beg)
-                          (line-number-at-pos))
-          (save-excursion (goto-char beg)
-                          (1+ (current-column)))
-          (save-excursion (goto-char end)
-                          (line-number-at-pos))
-          (save-excursion (goto-char end)
-                          (1+ (current-column)))
-          (buffer-substring-no-properties beg end)))
-
-(defun intero-get-info-of (thing)
-  "Get info for THING."
-  (let ((optimistic-result
-         (replace-regexp-in-string
-          "\n$" ""
-          (intero-blocking-call
-           'backend
-           (format ":info %s" thing)))))
-    (if (string-match-p "^<interactive>" optimistic-result)
-        ;; Load the module Interpreted so that we get information,
-        ;; then restore bytecode.
-        (progn (intero-async-call
-                'backend
-                ":set -fbyte-code")
-               (set-buffer-modified-p t)
-               (save-buffer)
-               (unless (member 'save flycheck-check-syntax-automatically)
-                 (intero-async-call
-                  'backend
-                  (concat ":load " (intero-path-for-ghci (intero-temp-file-name)))))
-               (intero-async-call
-                'backend
-                ":set -fobject-code")
-               (replace-regexp-in-string
-                "\n$" ""
-                (intero-blocking-call
-                 'backend
-                 (format ":info %s" thing))))
-      optimistic-result)))
-
-(defconst intero-unloaded-module-string "Couldn't guess that module name. Does it exist?")
-
-(defun intero-get-loc-at (beg end)
-  "Get the location of the identifier denoted by BEG and END."
-  (let ((result (intero-get-loc-at-helper beg end)))
-    (if (string-match (regexp-quote intero-unloaded-module-string)
-                      result)
-        (progn (flycheck-buffer)
-               (message "No location information yet, compiling module ...")
-               (intero-get-loc-at-helper-process beg end))
-      result)))
-
-(defun intero-get-loc-at-helper (beg end)
-  "Make the blocking call to the process."
-  (replace-regexp-in-string
-   "\n$" ""
-   (intero-blocking-network-call
-    'backend
-    (format ":loc-at %s %d %d %d %d %S"
-            (intero-path-for-ghci (intero-temp-file-name))
-            (save-excursion (goto-char beg)
-                            (line-number-at-pos))
-            (save-excursion (goto-char beg)
-                            (1+ (current-column)))
-            (save-excursion (goto-char end)
-                            (line-number-at-pos))
-            (save-excursion (goto-char end)
-                            (1+ (current-column)))
-            (buffer-substring-no-properties beg end)))))
-
-(defun intero-get-loc-at-helper-process (beg end)
-  "Make the blocking call to the process."
-  (replace-regexp-in-string
-   "\n$" ""
-   (intero-blocking-call
-    'backend
-    (format ":loc-at %s %d %d %d %d %S"
-            (intero-path-for-ghci (intero-temp-file-name))
-            (save-excursion (goto-char beg)
-                            (line-number-at-pos))
-            (save-excursion (goto-char beg)
-                            (1+ (current-column)))
-            (save-excursion (goto-char end)
-                            (line-number-at-pos))
-            (save-excursion (goto-char end)
-                            (1+ (current-column)))
-            (buffer-substring-no-properties beg end)))))
-
-(defun intero-get-uses-at (beg end)
-  "Return usage list for identifier denoted by BEG and END."
-  (let ((result (intero-get-uses-at-helper beg end)))
-    (if (string-match (regexp-quote intero-unloaded-module-string)
-                      result)
-        (progn (flycheck-buffer)
-               (message "No use information yet, compiling module ...")
-               (intero-get-uses-at-helper-process beg end))
-      result)))
-
-(defun intero-get-uses-at-helper (beg end)
-  "Return usage list for identifier denoted by BEG and END."
-  (replace-regexp-in-string
-   "\n$" ""
-   (intero-blocking-network-call
-    'backend
-    (format ":uses %s %d %d %d %d %S"
-            (intero-path-for-ghci (intero-temp-file-name))
-            (save-excursion (goto-char beg)
-                            (line-number-at-pos))
-            (save-excursion (goto-char beg)
-                            (1+ (current-column)))
-            (save-excursion (goto-char end)
-                            (line-number-at-pos))
-            (save-excursion (goto-char end)
-                            (1+ (current-column)))
-            (buffer-substring-no-properties beg end)))))
-
-(defun intero-get-uses-at-helper-process (beg end)
-  "Return usage list for identifier denoted by BEG and END."
-  (replace-regexp-in-string
-   "\n$" ""
-   (intero-blocking-call
-    'backend
-    (format ":uses %s %d %d %d %d %S"
-            (intero-path-for-ghci (intero-temp-file-name))
-            (save-excursion (goto-char beg)
-                            (line-number-at-pos))
-            (save-excursion (goto-char beg)
-                            (1+ (current-column)))
-            (save-excursion (goto-char end)
-                            (line-number-at-pos))
-            (save-excursion (goto-char end)
-                            (1+ (current-column)))
-            (buffer-substring-no-properties beg end)))))
-
-(defun intero-get-completions (source-buffer beg end cont)
-  "Get completions and send to SOURCE-BUFFER.
-Prefix is marked by positions BEG and END.  Completions are
-passed to CONT in SOURCE-BUFFER."
-  (intero-async-network-call
-   'backend
-   (format ":complete-at %s %d %d %d %d %S"
-           (intero-path-for-ghci (intero-temp-file-name))
-           (save-excursion (goto-char beg)
-                           (line-number-at-pos))
-           (save-excursion (goto-char beg)
-                           (1+ (current-column)))
-           (save-excursion (goto-char end)
-                           (line-number-at-pos))
-           (save-excursion (goto-char end)
-                           (1+ (current-column)))
-           (buffer-substring-no-properties beg end))
-   (list :cont cont :source-buffer source-buffer)
-   (lambda (state reply)
-     (with-current-buffer
-         (plist-get state :source-buffer)
-       (funcall
-        (plist-get state :cont)
-        (intero-completion-response-to-list reply))))))
-
-(defun intero-completion-response-to-list (reply)
-  "Convert the REPLY from a backend completion to a list."
-  (if (string-match-p "^*** Exception" reply)
-      (list)
-    (mapcar
-     (lambda (x)
-       (replace-regexp-in-string "\\\"" "" x))
-     (split-string reply "\n" t))))
-
-(defun intero-get-repl-completions (source-buffer prefix cont)
-  "Get REPL completions and send to SOURCE-BUFFER.
-Completions for PREFIX are passed to CONT in SOURCE-BUFFER."
-  (intero-async-call
-   'backend
-   (format ":complete repl %S" prefix)
-   (list :cont cont :source-buffer source-buffer)
-   (lambda (state reply)
-     (with-current-buffer
-         (plist-get state :source-buffer)
-       (funcall
-        (plist-get state :cont)
-        (mapcar
-         (lambda (x)
-           (replace-regexp-in-string "\\\"" "" x))
-         (cdr (split-string reply "\n" t))))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Process communication
-
-(defun intero-call-process (program &optional infile destination display &rest args)
-  "Synchronously call PROGRAM.
-INFILE, DESTINATION, DISPLAY and ARGS are as for
-'call-process'/'process-file'.  Provides TRAMP compatibility for
-'call-process'; when the 'default-directory' is on a remote
-machine, PROGRAM is launched on that machine."
-  (let ((process-args (append (list program infile destination display) args)))
-    (apply 'process-file process-args)))
-
-(defun intero-call-stack (&optional infile destination display stack-yaml &rest args)
-  "Synchronously call stack using the same arguments as `intero-call-process'.
-INFILE, DESTINATION, DISPLAY and ARGS are as for
-`call-process'/`process-file'.  STACK-YAML specifies which stack
-yaml config to use, or stack's default when nil."
-  (let ((stack-yaml-args (when stack-yaml
-                           (list "--stack-yaml" stack-yaml))))
-    (apply #'intero-call-process intero-stack-executable
-           infile destination display
-           (append stack-yaml-args args))))
-
-(defun intero-delete-worker (worker)
-  "Delete the given WORKER."
-  (when (intero-buffer-p worker)
-    (with-current-buffer (intero-get-buffer-create worker)
-      (when (get-buffer-process (current-buffer))
-        (setq intero-deleting t)
-        (kill-process (get-buffer-process (current-buffer)))
-        (delete-process (get-buffer-process (current-buffer))))
-      (kill-buffer (current-buffer)))))
-
-(defun intero-blocking-call (worker cmd)
-  "Send WORKER the command string CMD and block pending its result."
-  (let ((result (list nil)))
-    (intero-async-call
-     worker
-     cmd
-     result
-     (lambda (result reply)
-       (setf (car result) reply)))
-    (let ((buffer (intero-buffer worker)))
-      (while (not (null (buffer-local-value 'intero-callbacks buffer)))
-        (sleep-for 0.0001)))
-    (car result)))
-
-(defun intero-blocking-network-call (worker cmd)
-  "Send WORKER the command string CMD via the network and block pending its result."
-  (let ((result (list nil)))
-    (intero-async-network-call
-     worker
-     cmd
-     result
-     (lambda (result reply)
-       (setf (car result) reply)))
-    (while (eq (car result) nil)
-      (sleep-for 0.0001))
-    (car result)))
-
-(defun intero-async-network-call (worker cmd &optional state callback)
-  "Send WORKER the command string CMD, via a network connection.
-The result, along with the given STATE, is passed to CALLBACK
-as (CALLBACK STATE REPLY)."
-  (if (file-remote-p default-directory)
-      (intero-async-call worker cmd state callback)
-      (let ((buffer (intero-buffer worker)))
-        (if (and buffer (process-live-p (get-buffer-process buffer)))
-            (with-current-buffer buffer
-              (if intero-service-port
-                  (let* ((buffer (generate-new-buffer (format " intero-network:%S" worker)))
-                         (process
-                          (make-network-process
-                           :name (format "%S" worker)
-                           :buffer buffer
-                           :host 'local
-                           :service intero-service-port
-                           :family 'ipv4
-                           :nowait t
-                           :noquery t
-                           :sentinel 'intero-network-call-sentinel)))
-                    (with-current-buffer buffer
-                      (setq intero-async-network-cmd cmd)
-                      (setq intero-async-network-state state)
-                      (setq intero-async-network-worker worker)
-                      (setq intero-async-network-callback callback)))
-                (progn (when intero-debug (message "No `intero-service-port', falling back ..."))
-                       (intero-async-call worker cmd state callback))))
-          (error "Intero process is not running: run M-x intero-restart to start it")))))
-
-(defun intero-network-call-sentinel (process event)
-  (pcase event
-    ;; This event sometimes gets sent when (delete-process) is called, but
-    ;; inconsistently. We can't rely on it for killing buffers, but we need to
-    ;; handle the possibility.
-    ("deleted\n")
-
-    ("open\n"
-     (with-current-buffer (process-buffer process)
-       (when intero-debug (message "Connected to service, sending %S" intero-async-network-cmd))
-       (setq intero-async-network-connected t)
-       (if intero-async-network-cmd
-           (process-send-string process (concat intero-async-network-cmd "\n"))
-         (delete-process process)
-         (kill-buffer (process-buffer process)))))
-    (_
-     (with-current-buffer (process-buffer process)
-       (if intero-async-network-connected
-           (when intero-async-network-callback
-             (when intero-debug (message "Calling callback with %S" (buffer-string)))
-             (funcall intero-async-network-callback
-                      intero-async-network-state
-                      (buffer-string)))
-         ;; We didn't successfully connect, so let's fallback to the
-         ;; process pipe.
-         (when intero-async-network-callback
-           (when intero-debug (message "Failed to connect, falling back ... "))
-           (setq intero-async-network-callback nil)
-           (intero-async-call
-            intero-async-network-worker
-            intero-async-network-cmd
-            intero-async-network-state
-            intero-async-network-callback))))
-     (delete-process process)
-     (kill-buffer (process-buffer process)))))
-
-(defun intero-async-call (worker cmd &optional state callback)
-  "Send WORKER the command string CMD.
-The result, along with the given STATE, is passed to CALLBACK
-as (CALLBACK STATE REPLY)."
-  (let ((buffer (intero-buffer worker)))
-    (if (and buffer (process-live-p (get-buffer-process buffer)))
-        (progn (with-current-buffer buffer
-                 (setq intero-callbacks
-                       (append intero-callbacks
-                               (list (list state
-                                           (or callback #'ignore)
-                                           cmd)))))
-               (when intero-debug
-                 (message "[Intero] -> %s" cmd))
-               (comint-simple-send (intero-process worker) cmd))
-      (error "Intero process is not running: run M-x intero-restart to start it"))))
-
-(defun intero-buffer (worker)
-  "Get the WORKER buffer for the current directory."
-  (let ((buffer (intero-get-buffer-create worker))
-        (targets (buffer-local-value 'intero-targets (current-buffer))))
-    (if (get-buffer-process buffer)
-        buffer
-      (intero-get-worker-create worker targets (current-buffer)
-                                (buffer-local-value
-                                 'intero-stack-yaml (current-buffer))))))
-
-(defun intero-process (worker)
-  "Get the WORKER process for the current directory."
-  (get-buffer-process (intero-buffer worker)))
-
-(defun intero-get-worker-create (worker &optional targets source-buffer stack-yaml)
-  "Start the given WORKER.
-If provided, use the specified TARGETS, SOURCE-BUFFER and STACK-YAML."
-  (let* ((buffer (intero-get-buffer-create worker)))
-    (if (get-buffer-process buffer)
-        buffer
-      (let ((install-status (intero-installed-p)))
-        (if (eq install-status 'installed)
-            (intero-start-process-in-buffer buffer targets source-buffer stack-yaml)
-          (intero-auto-install buffer install-status targets source-buffer stack-yaml))))))
-
-(defun intero-auto-install (buffer install-status &optional targets source-buffer stack-yaml)
-  "Automatically install Intero appropriately for BUFFER.
-INSTALL-STATUS indicates the current installation status.
-If supplied, use the given TARGETS, SOURCE-BUFFER and STACK-YAML."
-  (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.")))
-      (if (intero-version>= (intero-stack-version) '(1 6 1))
-          (intero-copy-compiler-tool-auto-install source-buffer targets buffer)
-        (intero-old-auto-install source-buffer targets buffer stack-yaml)))))
-
-(defun intero-copy-compiler-tool-auto-install (source-buffer targets buffer)
-  "Automatically install Intero appropriately for BUFFER.
-Use the given TARGETS, SOURCE-BUFFER and STACK-YAML."
-  (let ((ghc-version (intero-ghc-version-raw)))
-    (insert
-     (format "
-
-Installing intero-%s for GHC %s ...
-
-" intero-package-version ghc-version))
-    (redisplay)
-    (cl-case
-        (let ((default-directory (make-temp-file "intero" t)))
-          (intero-call-stack
-           nil (current-buffer) t nil "build"
-           "--copy-compiler-tool"
-           (concat "intero-" intero-package-version)
-           "--flag" "haskeline:-terminfo"
-           "--resolver" (concat "ghc-" ghc-version)
-           "ghc-paths-0.1.0.9" "mtl-2.2.2" "network-2.7.0.0" "random-1.1" "syb-0.7"))
-      (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))
-       nil))))
-
-(defun intero-old-auto-install (source-buffer targets buffer stack-yaml)
-  "Automatically install Intero appropriately for BUFFER.
-Use the given TARGETS, SOURCE-BUFFER and STACK-YAML."
-  (insert
-   "
-
-Installing intero-%s automatically ...
-
-" intero-package-version)
-  (redisplay)
-  (cl-case (intero-call-stack
-            nil (current-buffer) t stack-yaml
-            "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"
-            "--flag" "haskeline:-terminfo")
-    (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))
-     nil)))
-
-(defun intero-start-process-in-buffer (buffer &optional targets source-buffer stack-yaml)
-  "Start an Intero worker in BUFFER.
-Uses the specified TARGETS if supplied.
-Automatically performs initial actions in SOURCE-BUFFER, if specified.
-Uses the default stack config file, or STACK-YAML file if given."
-  (if (buffer-local-value 'intero-give-up buffer)
-      buffer
-    (let* ((options
-            (intero-make-options-list
-             (intero-executable-path stack-yaml)
-             (or targets
-                 (let ((package-name (buffer-local-value 'intero-package-name buffer)))
-                   (unless (equal "" package-name)
-                     (list package-name))))
-             (not (buffer-local-value 'intero-try-with-build buffer))
-             t ;; pass --no-load to stack
-             t ;; pass -ignore-dot-ghci to intero
-             stack-yaml ;; let stack choose a default when nil
-             ))
-           (arguments (cons "ghci" options))
-           (process (with-current-buffer buffer
-                      (when intero-debug
-                        (message "Intero arguments: %s" (combine-and-quote-strings arguments)))
-                      (message "Booting up intero ...")
-                      (apply #'start-file-process "stack" buffer intero-stack-executable
-                             arguments))))
-      (set-process-query-on-exit-flag process nil)
-      (process-send-string process ":set -fobject-code\n")
-      (process-send-string process ":set -fdefer-type-errors\n")
-      (process-send-string process ":set -fdiagnostics-color=never\n")
-      (process-send-string process ":set prompt \"\\4\"\n")
-      (with-current-buffer buffer
-        (erase-buffer)
-        (when stack-yaml
-          (setq intero-stack-yaml stack-yaml))
-        (setq intero-targets targets)
-        (setq intero-start-time (current-time))
-        (setq intero-source-buffer source-buffer)
-        (setq intero-arguments arguments)
-        (setq intero-starting t)
-        (setq intero-callbacks
-              (list (list (cons source-buffer
-                                buffer)
-                          (lambda (buffers msg)
-                            (let ((source-buffer (car buffers))
-                                  (process-buffer (cdr buffers)))
-                              (with-current-buffer process-buffer
-                                (when (string-match "^Intero-Service-Port: \\([0-9]+\\)\n" msg)
-                                  (setq intero-service-port (string-to-number (match-string 1 msg))))
-                                (setq-local intero-starting nil))
-                              (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 intero-debug
-           (message "[Intero] <- %s" string))
-         (when (buffer-live-p (process-buffer process))
-           (with-current-buffer (process-buffer process)
-             (goto-char (point-max))
-             (insert string)
-             (when (and intero-try-with-build
-                        intero-starting)
-               (let ((last-line (buffer-substring-no-properties
-                                 (line-beginning-position)
-                                 (line-end-position))))
-                 (if (string-match-p "^Progress" last-line)
-                     (message "Booting up intero (building dependencies: %s)"
-                              (downcase
-                               (or (car (split-string (replace-regexp-in-string
-                                                       "\u0008+" "\n"
-                                                       last-line)
-                                                      "\n" t))
-                                   "...")))
-                   (message "Booting up intero ..."))))
-             (intero-read-buffer)))))
-      (set-process-sentinel process 'intero-sentinel)
-      buffer)))
-
-(defun intero-flycheck-buffer ()
-  "Run flycheck in the buffer.
-Restarts flycheck in case there was a problem and flycheck is stuck."
-  (flycheck-mode -1)
-  (flycheck-mode)
-  (flycheck-buffer))
-
-(defun intero-make-options-list (with-ghc targets no-build no-load ignore-dot-ghci stack-yaml)
-  "Make the stack ghci options list.
-TARGETS are the build targets.  When non-nil, NO-BUILD and
-NO-LOAD enable the correspondingly-named stack options.  When
-IGNORE-DOT-GHCI is non-nil, it enables the corresponding GHCI
-option.  STACK-YAML is the stack config file to use (or stack's
-default when nil)."
-  (append (when stack-yaml
-            (list "--stack-yaml" stack-yaml))
-          (list "--with-ghc"
-                with-ghc
-                "--docker-run-args=--interactive=true --tty=false"
-                )
-          (when no-build
-            (list "--no-build"))
-          (when no-load
-            (list "--no-load"))
-          (when ignore-dot-ghci
-            (list "--ghci-options" "-ignore-dot-ghci"))
-          (cl-mapcan (lambda (x) (list "--ghci-options" x)) intero-extra-ghc-options)
-          targets))
-
-(defun intero-sentinel (process change)
-  "Handle when PROCESS reports a CHANGE.
-This is a standard process sentinel function."
-  (when (buffer-live-p (process-buffer process))
-    (when (and (not (process-live-p process)))
-      (let ((buffer (process-buffer process)))
-        (if (with-current-buffer buffer intero-deleting)
-            (message "Intero process deleted.")
-          (if (and (intero-unsatisfied-package-p buffer)
-                   (not (buffer-local-value 'intero-try-with-build buffer)))
-              (progn (with-current-buffer buffer (setq-local intero-try-with-build t))
-                     (intero-start-process-in-buffer
-                      buffer
-                      (buffer-local-value 'intero-targets buffer)
-                      (buffer-local-value 'intero-source-buffer buffer)))
-            (progn (with-current-buffer buffer (setq-local intero-give-up t))
-                   (intero-show-process-problem process change))))))))
-
-(defun intero-unsatisfied-package-p (buffer)
-  "Return non-nil if BUFFER contain GHCi's unsatisfied package complaint."
-  (with-current-buffer buffer
-    (save-excursion
-      (goto-char (point-min))
-      (search-forward-regexp "cannot satisfy -package" nil t 1))))
-
-(defun intero-executable-path (stack-yaml)
-  "The path for the intero executable."
-  (intero-with-temp-buffer
-    (cl-case (save-excursion
-               (intero-call-stack
-                nil (current-buffer) t intero-stack-yaml "path" "--compiler-tools-bin"))
-      (0 (replace-regexp-in-string "[\r\n]+$" "/intero" (buffer-string)))
-      (1 "intero"))))
-
-(defun intero-installed-p ()
-  "Return non-nil if intero (of the right version) is installed in the stack environment."
-  (redisplay)
-  (intero-with-temp-buffer
-    (if (= 0 (intero-call-stack
-              nil t nil intero-stack-yaml
-              "exec"
-              "--verbosity" "silent"
-              "--"
-              (intero-executable-path intero-stack-yaml)
-              "--version"))
-        (progn
-          (goto-char (point-min))
-          ;; This skipping comes due to https://github.com/commercialhaskell/intero/pull/216/files
-          (when (looking-at "Intero ")
-            (goto-char (match-end 0)))
-          ;;
-          (if (string= (buffer-substring (point) (line-end-position))
-                       intero-package-version)
-              'installed
-            'wrong-version))
-      'not-installed)))
-
-(defun intero-show-process-problem (process change)
-  "Report to the user that PROCESS reported CHANGE, causing it to end."
-  (message "Problem with Intero!")
-  (switch-to-buffer (process-buffer process))
-  (goto-char (point-max))
-  (insert "\n---\n\n")
-  (insert
-   (propertize
-    (concat
-     "This is the buffer where Emacs talks to intero. It's normally hidden,
-but a problem occcured.
-
-TROUBLESHOOTING
-
-It may be obvious if there is some text above this message
-indicating a problem.
-
-If you do not wish to use Intero for some projects, see
-https://github.com/commercialhaskell/intero#whitelistingblacklisting-projects
-
-The process ended. Here is the reason that Emacs gives us:
-
-"
-     "  " change
-     "\n"
-     "For troubleshooting purposes, here are the arguments used to launch intero:
-
-"
-     (format "  %s %s"
-             intero-stack-executable
-             (combine-and-quote-strings intero-arguments))
-
-     "
-
-It's worth checking that the correct stack executable is being
-found on your path, or has been set via
-`intero-stack-executable'.  The executable being used now is:
-
-  "
-     (executable-find intero-stack-executable)
-     "
-
-WHAT TO DO NEXT
-
-If you fixed the problem, just kill this buffer, Intero will make
-a fresh one and attempt to start the process automatically as
-soon as you start editing code again.
-
-If you are unable to fix the problem, just leave this buffer
-around in Emacs and Intero will not attempt to start the process
-anymore.
-
-You can always run M-x intero-restart to make it try again.
-
-")
-    'face 'compilation-error)))
-
-(defun intero-read-buffer ()
-  "In the process buffer, we read what's in it."
-  (let ((repeat t))
-    (while repeat
-      (setq repeat nil)
-      (goto-char (point-min))
-      (when (search-forward "\4" (point-max) t 1)
-        (let* ((next-callback (pop intero-callbacks))
-               (state (nth 0 next-callback))
-               (func (nth 1 next-callback)))
-          (let ((string (intero-strip-carriage-returns (buffer-substring (point-min) (1- (point))))))
-            (if next-callback
-                (progn (intero-with-temp-buffer
-                         (funcall func state string))
-                       (setq repeat t))
-              (when intero-debug
-                (intero--warn "Received output but no callback in `intero-callbacks': %S"
-                              string)))))
-        (delete-region (point-min) (point))))))
-
-(defun intero-strip-carriage-returns (string)
-  "Strip the \\r from Windows \\r\\n line endings in STRING."
-  (replace-regexp-in-string "\r" "" string))
-
-(defun intero-get-buffer-create (worker)
-  "Get or create the stack buffer for WORKER.
-Uses the directory of the current buffer for context."
-  (let* ((root (intero-extend-path-by-buffer-host (intero-project-root)))
-         (cabal-file (intero-cabal-find-file))
-         (package-name (if cabal-file
-                           (intero-package-name cabal-file)
-                         ""))
-         (initial-buffer (current-buffer))
-         (buffer-name (intero-buffer-name worker))
-         (default-directory (if cabal-file
-                                (file-name-directory cabal-file)
-                              root)))
-    (with-current-buffer
-        (get-buffer-create buffer-name)
-      (intero-inherit-local-variables initial-buffer)
-      (setq intero-package-name package-name)
-      (cd default-directory)
-      (current-buffer))))
-
-(defun intero-gave-up (worker)
-  "Return non-nil if starting WORKER or installing intero failed."
-  (and (intero-buffer-p worker)
-       (let ((buffer (get-buffer (intero-buffer-name worker))))
-         (buffer-local-value 'intero-give-up buffer))))
-
-(defun intero-buffer-p (worker)
-  "Return non-nil if a buffer exists for WORKER."
-  (get-buffer (intero-buffer-name worker)))
-
-(defun intero-buffer-name (worker)
-  "For a given WORKER, create a buffer name."
-  (let* ((root (intero-project-root))
-         (package-name (intero-package-name)))
-    (concat " intero:"
-            (format "%s" worker)
-            ":"
-            package-name
-            " "
-            root)))
-
-(defun intero-project-root ()
-  "Get the current stack config directory.
-This is the directory where the file specified in
-`intero-stack-yaml' is located, or if nil then the directory
-where stack.yaml is placed for this project, or the global one if
-no such project-specific config exists."
-  (if intero-project-root
-      intero-project-root
-    (let ((stack-yaml intero-stack-yaml))
-      (setq intero-project-root
-            (intero-with-temp-buffer
-              (cl-case (save-excursion
-                         (intero-call-stack nil (current-buffer) nil stack-yaml
-                                            "path"
-                                            "--project-root"
-                                            "--verbosity" "silent"))
-                (0 (buffer-substring (line-beginning-position) (line-end-position)))
-                (t (intero--warn "Couldn't get the Stack project root.
-
-This can be caused by a syntax error in your stack.yaml file. Check that out.
-
-If you do not wish to use Intero for some projects, see
-https://github.com/commercialhaskell/intero#whitelistingblacklisting-projects
-
-Otherwise, please report this as a bug!
-
-For debugging purposes, try running the following in your terminal:
-
-%s path --project-root" intero-stack-executable)
-                   nil)))))))
-
-(defun intero-ghc-version ()
-  "Get the GHC version used by the project, calls only once per backend."
-  (with-current-buffer (intero-buffer 'backend)
-    (or intero-ghc-version
-        (setq intero-ghc-version
-              (intero-ghc-version-raw)))))
-
-(defun intero-ghc-version-raw ()
-  "Get the GHC version used by the project."
-  (intero-with-temp-buffer
-    (cl-case (save-excursion
-               (intero-call-stack
-                nil (current-buffer) t intero-stack-yaml
-                "ghc" "--" "--numeric-version"))
-      (0
-       (buffer-substring (line-beginning-position) (line-end-position)))
-      (1 nil))))
-
-(defun intero-version>= (new0 old0)
-  "Is the version NEW >= OLD?"
-  (or (and (null new0) (null old0))
-      (let ((new (or new0 (list 0)))
-            (old (or old0 (list 0))))
-        (or (> (car new)
-               (car old))
-            (and (= (car new)
-                    (car old))
-                 (intero-version>= (cdr new)
-                                   (cdr old)))))))
-
-(defun intero-stack-version ()
-  "Get the version components of stack."
-  (let* ((str (intero-stack-version-raw))
-         (parts (mapcar #'string-to-number (split-string str "\\."))))
-    parts))
-
-(defun intero-stack-version-raw ()
-  "Get the Stack version in PATH."
-  (intero-with-temp-buffer
-    (cl-case (save-excursion
-               (intero-call-stack
-                nil (current-buffer) t intero-stack-yaml "--numeric-version"))
-      (0
-       (buffer-substring (line-beginning-position) (line-end-position)))
-      (1 nil))))
-
-(defun intero-get-targets ()
-  "Get all available targets."
-  (with-current-buffer (intero-buffer 'backend)
-    (intero-with-temp-buffer
-      (cl-case (intero-call-stack nil (current-buffer) t
-                                  intero-stack-yaml
-                                  "ide" "targets")
-        (0
-         (cl-remove-if-not
-          (lambda (line)
-            (string-match-p "^[A-Za-z0-9-:_]+$" line))
-          (split-string (buffer-string) "[\r\n]" t)))
-        (1 nil)))))
-
-(defun intero-package-name (&optional cabal-file)
-  "Get the current package name from a nearby .cabal file.
-If there is none, return an empty string.  If specified, use
-CABAL-FILE rather than trying to locate one."
-  (or intero-package-name
-      (setq intero-package-name
-            (let ((cabal-file (or cabal-file
-                                  (intero-cabal-find-file))))
-              (if cabal-file
-                  (replace-regexp-in-string
-                   ".cabal$" ""
-                   (file-name-nondirectory cabal-file))
-                "")))))
-
-(defun intero-cabal-find-file (&optional dir)
-  "Search for package description file upwards starting from DIR.
-If DIR is nil, `default-directory' is used as starting point for
-directory traversal.  Upward traversal is aborted if file owner
-changes.  Uses `intero-cabal-find-pkg-desc' internally."
-  (let ((use-dir (or dir default-directory)))
-    (while (and use-dir (not (file-directory-p use-dir)))
-      (setq use-dir (file-name-directory (directory-file-name use-dir))))
-    (when use-dir
-      (catch 'found
-        (let ((user (nth 2 (file-attributes use-dir)))
-              ;; Abbreviate, so as to stop when we cross ~/.
-              (root (abbreviate-file-name use-dir)))
-          ;; traverse current dir up to root as long as file owner doesn't change
-          (while (and root (equal user (nth 2 (file-attributes root))))
-            (let ((cabal-file (intero-cabal-find-pkg-desc root)))
-              (when cabal-file
-                (throw 'found cabal-file)))
-
-            (let ((proot (file-name-directory (directory-file-name root))))
-              (if (equal proot root) ;; fix-point reached?
-                  (throw 'found nil)
-                (setq root proot))))
-          nil)))))
-
-(defun intero-cabal-find-pkg-desc (dir &optional allow-multiple)
-  "Find a package description file in the directory DIR.
-Returns nil if none or multiple \".cabal\" files were found.  If
-ALLOW-MULTIPLE is non nil, in case of multiple \".cabal\" files,
-a list is returned instead of failing with a nil result."
-  ;; This is basically a port of Cabal's
-  ;; Distribution.Simple.Utils.findPackageDesc function
-  ;;  http://hackage.haskell.org/packages/archive/Cabal/1.16.0.3/doc/html/Distribution-Simple-Utils.html
-  ;; but without the exception throwing.
-  (let* ((cabal-files
-          (cl-remove-if (lambda (path)
-                          (or (file-directory-p path)
-                              (not (file-exists-p path))))
-                        (directory-files dir t ".\\.cabal\\'" t))))
-    (cond
-     ((= (length cabal-files) 1) (car cabal-files)) ;; exactly one candidate found
-     (allow-multiple cabal-files) ;; pass-thru multiple candidates
-     (t nil))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Multiselection
-
-(defvar intero-multiswitch-keymap
-  (let ((map (copy-keymap widget-keymap)))
-    (define-key map (kbd "C-c C-c") 'exit-recursive-edit)
-    (define-key map (kbd "C-c C-k") 'abort-recursive-edit)
-    (define-key map (kbd "C-g")     'abort-recursive-edit)
-    map))
-
-(defun intero-multiswitch (title options)
-  "Displaying TITLE, read multiple flags from a list of OPTIONS.
-Each option is a plist of (:key :default :title) wherein:
-
-  :key should be something comparable with EQUAL
-  :title should be a string
-  :default (boolean) specifies the default checkedness"
-  (let ((available-width (window-total-width)))
-    (save-window-excursion
-      (intero-with-temp-buffer
-        (rename-buffer (generate-new-buffer-name "multiswitch"))
-        (widget-insert (concat title "\n\n"))
-        (widget-insert (propertize "Select options with RET, hit " 'face 'font-lock-comment-face))
-        (widget-create 'push-button :notify
-                       (lambda (&rest ignore)
-                         (exit-recursive-edit))
-                       "C-c C-c")
-        (widget-insert (propertize " to apply these choices, or hit " 'face 'font-lock-comment-face))
-        (widget-create 'push-button :notify
-                       (lambda (&rest ignore)
-                         (abort-recursive-edit))
-                       "C-c C-k")
-        (widget-insert (propertize " to cancel.\n\n" 'face 'font-lock-comment-face))
-        (let* ((me (current-buffer))
-               (choices (mapcar (lambda (option)
-                                  (append option (list :value (plist-get option :default))))
-                                options)))
-          (cl-loop for option in choices
-                   do (widget-create
-                       'toggle
-                       :notify (lambda (widget &rest ignore)
-                                 (setq choices
-                                       (mapcar (lambda (choice)
-                                                 (if (equal (plist-get choice :key)
-                                                            (plist-get (cdr widget) :key))
-                                                     (plist-put choice :value (plist-get (cdr widget) :value))
-                                                   choice))
-                                               choices)))
-                       :on (concat "[x] " (plist-get option :title))
-                       :off (concat "[ ] " (plist-get option :title))
-                       :value (plist-get option :default)
-                       :key (plist-get option :key)))
-          (let ((lines (line-number-at-pos)))
-            (select-window (split-window-below))
-            (switch-to-buffer me)
-            (goto-char (point-min)))
-          (use-local-map intero-multiswitch-keymap)
-          (widget-setup)
-          (recursive-edit)
-          (kill-buffer me)
-          (mapcar (lambda (choice)
-                    (plist-get choice :key))
-                  (cl-remove-if-not (lambda (choice)
-                                      (plist-get choice :value))
-                                    choices)))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Hoogle
-
-(defun intero-hoogle-blocking-query (query)
-  "Make a request of QUERY using the local hoogle server.
-If running, otherwise returns nil.
-
-It is the responsibility of the caller to make sure the server is
-running; the user might not want to start the server
-automatically."
-  (let ((buffer (intero-hoogle-get-buffer)))
-    (when buffer
-      (let ((url (intero-hoogle-url buffer query)))
-        (with-current-buffer (url-retrieve-synchronously url t)
-          (search-forward "\n\n" nil t 1)
-          (json-read-from-string
-           (buffer-substring (line-beginning-position)
-                             (line-end-position))))))))
-
-(defun intero-hoogle-url (buffer query)
-  "Via hoogle server BUFFER make the HTTP URL for QUERY."
-  (format "http://127.0.0.1:%d/?hoogle=%s&mode=json"
-          (buffer-local-value 'intero-hoogle-port buffer)
-          (url-encode-url query)))
-
-(defun intero-hoogle-get-worker-create ()
-  "Get or create the hoogle worker."
-  (let* ((buffer (intero-hoogle-get-buffer-create)))
-    (if (get-buffer-process buffer)
-        buffer
-      (intero-start-hoogle-process-in-buffer buffer))))
-
-(defun intero-start-hoogle-process-in-buffer (buffer)
-  "Start the process in BUFFER, returning BUFFER."
-  (let* ((port (intero-free-port))
-         (process (with-current-buffer buffer
-                    (message "Booting up hoogle ...")
-                    (setq intero-hoogle-port port)
-                    (start-process "hoogle"
-                                   buffer
-                                   intero-stack-executable
-                                   "hoogle"
-                                   "server"
-                                   "--no-setup"
-                                   "--"
-                                   "--local"
-                                   "--port"
-                                   (number-to-string port)))))
-    (set-process-query-on-exit-flag process nil)
-    (set-process-sentinel process 'intero-hoogle-sentinel)
-    buffer))
-
-(defun intero-free-port ()
-  "Get the next free port to use."
-  (let ((proc (make-network-process
-               :name "port-check"
-               :family 'ipv4
-               :host "127.0.0.1"
-               :service t
-               :server t)))
-    (delete-process proc)
-    (process-contact proc :service)))
-
-(defun intero-hoogle-sentinel (process change)
-  "For the hoogle PROCESS there is a CHANGE to handle."
-  (message "Hoogle sentinel: %S %S" process change))
-
-(defun intero-hoogle-get-buffer-create ()
-  "Get or create the Hoogle buffer for the current stack project."
-  (let* ((root (intero-project-root))
-         (buffer-name (intero-hoogle-buffer-name root))
-         (buf (get-buffer buffer-name))
-         (initial-buffer (current-buffer))
-         (default-directory root))
-    (if buf
-        buf
-      (with-current-buffer (get-buffer-create buffer-name)
-        (intero-inherit-local-variables initial-buffer)
-        (cd default-directory)
-        (current-buffer)))))
-
-(defun intero-hoogle-get-buffer ()
-  "Get the Hoogle buffer for the current stack project."
-  (let* ((root (intero-project-root))
-         (buffer-name (intero-hoogle-buffer-name root)))
-    (get-buffer buffer-name)))
-
-(defun intero-hoogle-buffer-name (root)
-  "For a given worker, create a buffer name using ROOT."
-  (concat "*Hoogle:" root "*"))
-
-(defun intero-hoogle-ready-p ()
-  "Is hoogle ready to be started?"
-  (intero-with-temp-buffer
-    (cl-case (intero-call-stack nil (current-buffer) t intero-stack-yaml
-                                "hoogle" "--no-setup" "--verbosity" "silent")
-      (0 t))))
-
-(defun intero-hoogle-supported-p ()
-  "Is the stack hoogle command supported?"
-  (intero-with-temp-buffer
-    (cl-case (intero-call-stack nil (current-buffer) t
-                                intero-stack-yaml
-                                "hoogle" "--help")
-      (0 t))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Collecting information from compiler messages
-
-(defun intero-collect-compiler-messages (msgs)
-  "Collect information from compiler MSGS.
-
-This may update in-place the MSGS objects to hint that
-suggestions are available."
-  (setq intero-suggestions nil)
-  (let ((extension-regex (concat " " (regexp-opt (intero-extensions) t) "\\>"))
-        (quoted-symbol-regex "[‘`‛]\\([^ ]+\\)['’]"))
-    (cl-loop
-     for msg in msgs
-     do (let ((text (flycheck-error-message msg))
-              (note nil))
-          ;; Messages of this format:
-          ;;
-          ;;     • Constructor ‘Assert’ does not have the required strict field(s): assertName,
-          ;; assertDoc, assertExpression,
-          ;; assertSection
-          (let ((start 0))
-            (while (or
-                    (string-match "does not have the required strict field.*?:[\n\t\r ]" text start)
-                    (string-match "Fields of .*? not initialised:[\n\t\r ]" text start))
-              (let* ((match-end (match-end 0))
-                     (fields
-                      (let ((reached-end nil))
-                        (mapcar
-                         (lambda (field)
-                           (with-temp-buffer
-                             (insert field)
-                             (goto-char (point-min))
-                             (intero-ident-at-point)))
-                         (cl-remove-if
-                          (lambda (field)
-                            (or reached-end
-                                (when (string-match "[\r\n]" field)
-                                  (setq reached-end t)
-                                  nil)))
-                          (split-string
-                           (substring text match-end)
-                           "[\n\t\r ]*,[\n\t\r ]*" t))))))
-                (setq note t)
-                (add-to-list
-                 'intero-suggestions
-                 (list :type 'add-missing-fields
-                       :fields fields
-                       :line (flycheck-error-line msg)
-                       :column (flycheck-error-column msg)))
-                (setq start (min (length text) (1+ match-end))))))
-
-          ;; Messages of this format:
-          ;;
-          ;; Can't make a derived instance of ‘Functor X’:
-          ;;       You need DeriveFunctor to derive an instance for this class
-          ;;       Try GeneralizedNewtypeDeriving for GHC's newtype-deriving extension
-          ;;       In the newtype declaration for ‘X’
-          (let ((start 0))
-            (while (let ((case-fold-search nil))
-                     (string-match extension-regex text start))
-              (setq note t)
-              (add-to-list 'intero-suggestions
-                           (list :type 'add-extension
-                                 :extension (match-string 1 text)))
-              (setq start (min (length text) (1+ (match-end 0))))))
-          ;; Messages of this format:
-          ;;
-          ;; Could not find module ‘Language.Haskell.TH’
-          ;;     It is a member of the hidden package ‘template-haskell’.
-          ;;     Use -v to see a list of the files searched for....
-          (let ((start 0))
-            (while (string-match "It is a member of the hidden package [‘`‛]\\([^ ]+\\)['’]" text start)
-              (setq note t)
-              (add-to-list 'intero-suggestions
-                           (list :type 'add-package
-                                 :package (match-string 1 text)))
-              (setq start (min (length text) (1+ (match-end 0))))))
-          ;; Messages of this format:
-          ;; Expected type: String
-          ;; Actual type: Data.Text.Internal.Builder.Builder
-          (let ((start 0))
-            (while (or (string-match
-                        "Expected type: String" text start)
-                       (string-match
-                        "Actual type: String" text start)
-                       (string-match
-                        "Actual type: \\[Char\\]" text start)
-                       (string-match
-                        "Expected type: \\[Char\\]" text start))
-              (setq note t)
-              (add-to-list 'intero-suggestions
-                           (list :type 'add-extension
-                                 :extension "OverloadedStrings"))
-              (setq start (min (length text) (1+ (match-end 0))))))
-          ;; Messages of this format:
-          ;;
-          ;; Defaulting the following constraint(s) to type ‘Integer’
-          ;;   (Num a0) arising from the literal ‘1’
-          ;; In the expression: 2
-          ;; In an equation for ‘x'’: x' = 2
-          (let ((start 0))
-            (while (string-match
-                    " Defaulting the following constraint" text start)
-              (setq note t)
-              (add-to-list 'intero-suggestions
-                           (list :type 'add-ghc-option
-                                 :option "-fno-warn-type-defaults"))
-              (setq start (min (length text) (1+ (match-end 0))))))
-          ;; Messages of this format:
-          ;;
-          ;;     This binding for ‘x’ shadows the existing binding
-          (let ((start 0))
-            (while (string-match
-                    " This binding for ‘\\(.*\\)’ shadows the existing binding" text start)
-              (setq note t)
-              (add-to-list 'intero-suggestions
-                           (list :type 'add-ghc-option
-                                 :option "-fno-warn-name-shadowing"))
-              (setq start (min (length text) (1+ (match-end 0))))))
-          ;; Messages of this format:
-          ;; Perhaps you want to add ‘foo’ to the import list
-          ;; in the import of ‘Blah’
-          ;; (/path/to/thing:19
-          (when (string-match "Perhaps you want to add [‘`‛]\\([^ ]+\\)['’][\n ]+to[\n ]+the[\n ]+import[\n ]+list[\n ]+in[\n ]+the[\n ]+import[\n ]+of[\n ]+[‘`‛]\\([^ ]+\\)['’][\n ]+(\\([^ ]+\\):(?\\([0-9]+\\)[:,]"
-                              text)
-            (let ((ident (match-string 1 text))
-                  (module (match-string 2 text))
-                  (file (match-string 3 text))
-                  (line (string-to-number (match-string 4 text))))
-              (setq note t)
-              (add-to-list 'intero-suggestions
-                           (list :type 'add-to-import
-                                 :module module
-                                 :ident ident
-                                 :line line))))
-          ;; Messages of this format:
-          ;;
-          ;; The import of ‘Control.Monad’ is redundant
-          ;;   except perhaps to import instances from ‘Control.Monad’
-          ;; To import instances alone, use: import Control.Monad()... (intero)
-          (when (string-match
-                 " The \\(qualified \\)?import of[ ][‘`‛]\\([^ ]+\\)['’] is redundant"
-                 text)
-            (setq note t)
-            (add-to-list 'intero-suggestions
-                         (list :type 'remove-import
-                               :module (match-string 2 text)
-                               :line (flycheck-error-line msg))))
-          ;; Messages of this format:
-          ;;
-          ;; Not in scope: ‘putStrn’
-          ;; Perhaps you meant one of these:
-          ;;   ‘putStr’ (imported from Prelude),
-          ;;   ‘putStrLn’ (imported from Prelude)
-          ;;
-          ;; Or this format:
-          ;;
-          ;; error:
-          ;;    • Variable not in scope: lopSetup :: [Statement Exp']
-          ;;    • Perhaps you meant ‘loopSetup’ (line 437)
-          (when (string-match
-                 "[Nn]ot in scope: \\(data constructor \\|type constructor or class \\)?[‘`‛]?\\([^'’ ]+\\).*\n.*Perhaps you meant"
-                 text)
-            (let ((typo (match-string 2 text))
-                  (start (min (length text) (1+ (match-end 0)))))
-              (while (string-match quoted-symbol-regex text start)
-                (setq note t)
-                (add-to-list 'intero-suggestions
-                             (list :type 'fix-typo
-                                   :typo typo
-                                   :replacement (match-string 1 text)
-                                   :column (flycheck-error-column msg)
-                                   :line (flycheck-error-line msg)))
-                (setq start (min (length text) (1+ (match-end 0)))))))
-          ;; Messages of this format:
-          ;;
-          ;;     Top-level binding with no type signature: main :: IO ()
-          (when (string-match
-                 "Top-level binding with no type signature:"
-                 text)
-            (let ((start (min (length text) (match-end 0))))
-              (setq note t)
-              (add-to-list 'intero-suggestions
-                           (list :type 'add-signature
-                                 :signature (mapconcat #'identity (split-string (substring text start)) " ")
-                                 :line (flycheck-error-line msg)))))
-          ;; Messages of this format:
-          (when (string-match "The import of [‘`‛]\\(.+?\\)[’`'][\n ]+from[\n ]+module[\n ]+[‘`‛]\\(.+?\\)[’`'][\n ]+is[\n ]+redundant" text)
-            (let ((module (match-string 2 text))
-                  (idents (split-string (match-string 1 text) "," t "[ \n]+")))
-              (setq note t)
-              (add-to-list 'intero-suggestions
-                           (list :type 'redundant-import-item
-                                 :idents idents
-                                 :line (flycheck-error-line msg)
-                                 :module module))))
-          ;; Messages of this format:
-          ;;
-          ;;     Redundant constraints: (Arith var, Bitwise var)
-          ;; Or
-          ;;     Redundant constraint: Arith var
-          ;; Or
-          ;;     Redundant constraints: (Arith var,
-          ;;                             Bitwise var,
-          ;;                             Functor var,
-          ;;                             Applicative var,
-          ;;                             Monad var)
-          (when (string-match "Redundant constraints?: " text)
-            (let* ((redundant-start (match-end 0))
-                   (parts (intero-with-temp-buffer
-                            (insert (substring text redundant-start))
-                            (goto-char (point-min))
-                            ;; A lone unparenthesized constraint might
-                            ;; be multiple sexps.
-                            (while (not (eq (point) (point-at-eol)))
-                              (forward-sexp))
-                            (let ((redundant-end (point)))
-                              (search-forward-regexp ".*\n.*In the ")
-                              (cons (buffer-substring (point-min) redundant-end)
-                                    (buffer-substring (match-end 0) (point-max)))))))
-              (setq note t)
-              (add-to-list
-               'intero-suggestions
-               (let ((rest (cdr parts))
-                     (redundant (let ((raw (car parts)))
-                                  (if (eq (string-to-char raw) ?\()
-                                      (substring raw 1 (1- (length raw)))
-                                    raw))))
-                 (list :type 'redundant-constraint
-                       :redundancies (mapcar #'string-trim
-                                             (intero-parse-comma-list redundant))
-                       :signature (mapconcat #'identity (split-string rest) " ")
-                       :line (flycheck-error-line msg))))))
-          ;; Add a note if we found a suggestion to make
-          (when note
-            (setf (flycheck-error-message msg)
-                  (concat text
-                          "\n\n"
-                          (propertize "(Hit `C-c C-r' in the Haskell buffer to apply suggestions)"
-                                      'face 'font-lock-warning-face)))))))
-  (setq intero-lighter
-        (if (null intero-suggestions)
-            " Intero"
-          (format " Intero:%d" (length intero-suggestions)))))
-
-(defun intero-extensions ()
-  "Get extensions for the current project's GHC."
-  (with-current-buffer (intero-buffer 'backend)
-    (or intero-extensions
-        (setq intero-extensions
-              (cl-remove-if-not
-               (lambda (str) (let ((case-fold-search nil))
-                               (string-match "^[A-Z][A-Za-z0-9]+$" str)))
-               (split-string
-                (shell-command-to-string
-                 (concat intero-stack-executable
-                         (if intero-stack-yaml
-                             (concat "--stack-yaml " intero-stack-yaml)
-                           "")
-                         " exec --verbosity silent -- ghc --supported-extensions"))))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Auto actions
-
-(defun intero-parse-comma-list (text)
-  "Parse a list of comma-separated expressions in TEXT."
-  (cl-loop for tok in (split-string text "[[:space:]\n]*,[[:space:]\n]*")
-           with acc = nil
-           append (let* ((clist (string-to-list tok))
-                         (num-open (-count (lambda (c) (or (eq c ?\() (eq c ?\[)))
-                                           clist))
-                         (num-close (-count (lambda (c) (or (eq c ?\)) (eq c ?\])))
-                                            clist)))
-                    (cond
-                     ((> num-open num-close) (progn (add-to-list 'acc tok) nil))
-                     ((> num-close num-open) (let ((tmp (reverse (cons tok acc))))
-                                               (setq acc nil)
-                                               (list (string-join tmp ", "))))
-                     (t (list tok))))))
-
-(defun intero-apply-suggestions ()
-  "Prompt and apply the suggestions."
-  (interactive)
-  (if (null intero-suggestions)
-      (message "No suggestions to apply")
-    (let ((to-apply
-           (intero-multiswitch
-            (format "There are %d suggestions to apply:" (length intero-suggestions))
-            (cl-remove-if-not
-             #'identity
-             (mapcar
-              (lambda (suggestion)
-                (cl-case (plist-get suggestion :type)
-                  (add-to-import
-                   (list :key suggestion
-                         :title (format "Add ‘%s’ to import of ‘%s’"
-                                        (plist-get suggestion :ident)
-                                        (plist-get suggestion :module))
-                         :default t))
-                  (add-missing-fields
-                   (list :key suggestion
-                         :default t
-                         :title
-                         (format "Add missing fields to record: %s"
-                                 (mapconcat (lambda (ident)
-                                              (concat "‘" ident "’"))
-                                            (plist-get suggestion :fields)
-                                            ", "))))
-                  (redundant-import-item
-                   (list :key suggestion
-                         :title
-                         (format "Remove redundant imports %s from import of ‘%s’"
-                                 (mapconcat (lambda (ident)
-                                              (concat "‘" ident "’"))
-                                            (plist-get suggestion :idents) ", ")
-                                 (plist-get suggestion :module))
-                         :default t))
-                  (add-extension
-                   (list :key suggestion
-                         :title (concat "Add {-# LANGUAGE "
-                                        (plist-get suggestion :extension)
-                                        " #-}")
-                         :default (not (string= "OverloadedStrings" (plist-get suggestion :extension)))))
-                  (add-ghc-option
-                   (list :key suggestion
-                         :title (concat "Add {-# OPTIONS_GHC "
-                                        (plist-get suggestion :option)
-                                        " #-}")
-                         :default (not
-                                   (string=
-                                    (plist-get suggestion :option)
-                                    "-fno-warn-name-shadowing"))))
-                  (add-package
-                   (list :key suggestion
-                         :title (concat "Enable package: " (plist-get suggestion :package))
-                         :default t))
-                  (remove-import
-                   (list :key suggestion
-                         :title (concat "Remove: import "
-                                        (plist-get suggestion :module))
-                         :default t))
-                  (fix-typo
-                   (list :key suggestion
-                         :title (concat "Replace ‘"
-                                        (plist-get suggestion :typo)
-                                        "’ with ‘"
-                                        (plist-get suggestion :replacement)
-                                        "’")
-                         :default (null (cdr intero-suggestions))))
-                  (add-signature
-                   (list :key suggestion
-                         :title (concat "Add signature: "
-                                        (plist-get suggestion :signature))
-                         :default t))
-                  (redundant-constraint
-                   (list :key suggestion
-                         :title (concat
-                                 "Remove redundant constraints: "
-                                 (string-join (plist-get suggestion :redundancies)
-                                              ", ")
-                                 "\n    from the "
-                                 (plist-get suggestion :signature))
-                         :default nil))))
-              intero-suggestions)))))
-      (if (null to-apply)
-          (message "No changes selected to apply.")
-        (let ((sorted (sort to-apply
-                            (lambda (lt gt)
-                              (let ((lt-line   (or (plist-get lt :line)   0))
-                                    (lt-column (or (plist-get lt :column) 0))
-                                    (gt-line   (or (plist-get gt :line)   0))
-                                    (gt-column (or (plist-get gt :column) 0)))
-                                (or (> lt-line gt-line)
-                                    (and (= lt-line gt-line)
-                                         (> lt-column gt-column))))))))
-          ;; # Changes unrelated to the buffer
-          (cl-loop
-           for suggestion in sorted
-           do (cl-case (plist-get suggestion :type)
-                (add-package
-                 (intero-add-package (plist-get suggestion :package)))))
-          ;; # Changes that do not increase/decrease line numbers
-          ;;
-          ;; Update in-place suggestions
-          (cl-loop
-           for suggestion in sorted
-           do (cl-case (plist-get suggestion :type)
-                (add-to-import
-                 (save-excursion
-                   (goto-char (point-min))
-                   (forward-line (1- (plist-get suggestion :line)))
-                   (when (and (search-forward (plist-get suggestion :module) nil t 1)
-                              (search-forward "(" nil t 1))
-                     (insert (if (string-match-p "^[_a-zA-Z]" (plist-get suggestion :ident))
-                                 (plist-get suggestion :ident)
-                               (concat "(" (plist-get suggestion :ident) ")")))
-                     (unless (looking-at-p "[:space:]*)")
-                       (insert ", ")))))
-                (redundant-import-item
-                 (save-excursion
-                   (goto-char (point-min))
-                   (forward-line (1- (plist-get suggestion :line)))
-                   (let* ((case-fold-search nil)
-                          (start (search-forward "(" nil t 1))
-                          (end (or (save-excursion
-                                     (when (search-forward-regexp "\n[^ \t]" nil t 1)
-                                       (1- (point))))
-                                   (line-end-position)))
-                          (regex
-                           (concat
-                            "\\("
-                            (mapconcat
-                             (lambda (ident)
-                               (if (string-match-p "^[_a-zA-Z]" ident)
-                                   (concat "\\<" (regexp-quote ident) "\\> ?" "\\("(regexp-quote "(..)") "\\)?")
-                                 (concat "(" (regexp-quote ident) ")")))
-                             (plist-get suggestion :idents)
-                             "\\|")
-                            "\\)"))
-                          (string (buffer-substring start end)))
-                     (delete-region start end)
-                     (insert
-                      (replace-regexp-in-string
-                       ",[\n ]*)" ")"
-                       (replace-regexp-in-string
-                        "^[\n ,]*" ""
-                        (replace-regexp-in-string
-                         "[\n ,]*,[\n ,]*" ", "
-                         (replace-regexp-in-string
-                          ",[\n ]*)" ")"
-                          (replace-regexp-in-string
-                           regex ""
-                           string)))))
-                      (make-string (1- (length (split-string string "\n" t))) 10)))))
-                (fix-typo
-                 (save-excursion
-                   (goto-char (point-min))
-                   (forward-line (1- (plist-get suggestion :line)))
-                   (move-to-column (- (plist-get suggestion :column) 1))
-                   (delete-char (length (plist-get suggestion :typo)))
-                   (insert (plist-get suggestion :replacement))))
-                (add-missing-fields
-                 (save-excursion
-                   (goto-char (point-min))
-                   (forward-line (1- (plist-get suggestion :line)))
-                   (move-to-column (- (plist-get suggestion :column) 1))
-                   (search-forward "{")
-                   (unless (looking-at "}")
-                     (save-excursion (insert ", ")))
-                   (insert (mapconcat (lambda (field) (concat field " = _"))
-                                      (plist-get suggestion :fields)
-                                      ", "))))))
-          ;; # Changes that do increase/decrease line numbers
-          ;;
-          ;; Remove redundant constraints
-          (cl-loop
-           for suggestion in sorted
-           do (cl-case (plist-get suggestion :type)
-                (redundant-constraint
-                 (save-excursion
-                   (goto-char (point-min))
-                   (forward-line (1- (plist-get suggestion :line)))
-                   (search-forward-regexp "[[:alnum:][:space:]\n]*=>")
-                   (backward-sexp 2)
-                   (let ((start (1+ (point))))
-                     (forward-sexp)
-                     (let* ((end (1- (point)))
-                            (constraints (intero-parse-comma-list
-                                          (buffer-substring start end)))
-                            (nonredundant
-                             (cl-loop for r in (plist-get suggestion :redundancies)
-                                      with nonredundant = constraints
-                                      do (setq nonredundant (delete r nonredundant))
-                                      finally return nonredundant)))
-                       (goto-char start)
-                       (delete-char (- end start))
-                       (insert (string-join nonredundant ", "))))))))
-
-          ;; Add a type signature to a top-level binding.
-          (cl-loop
-           for suggestion in sorted
-           do (cl-case (plist-get suggestion :type)
-                (add-signature
-                 (save-excursion
-                   (goto-char (point-min))
-                   (forward-line (1- (plist-get suggestion :line)))
-                   (insert (plist-get suggestion :signature))
-                   (insert "\n")))))
-
-          ;; Remove import lines from the file. May remove more than one
-          ;; line per import.
-          (cl-loop
-           for suggestion in sorted
-           do (cl-case (plist-get suggestion :type)
-                (remove-import
-                 (save-excursion
-                   (goto-char (point-min))
-                   (forward-line (1- (plist-get suggestion :line)))
-                   (delete-region (line-beginning-position)
-                                  (or (when (search-forward-regexp "\n[^ \t]" nil t 1)
-                                        (1- (point)))
-                                      (line-end-position)))))))
-          ;; Add extensions to the top of the file
-          (cl-loop
-           for suggestion in sorted
-           do (cl-case (plist-get suggestion :type)
-                (add-extension
-                 (save-excursion
-                   (goto-char (point-min))
-                   (intero-skip-shebangs)
-                   (insert "{-# LANGUAGE "
-                           (plist-get suggestion :extension)
-                           " #-}\n")))
-                (add-ghc-option
-                 (save-excursion
-                   (goto-char (point-min))
-                   (intero-skip-shebangs)
-                   (insert "{-# OPTIONS_GHC "
-                           (plist-get suggestion :option)
-                           " #-}\n"))))))))))
-
-(defun intero-skip-shebangs ()
-  "Skip #! and -- shebangs used in Haskell scripts."
-  (when (looking-at-p "#!") (forward-line 1))
-  (when (looking-at-p "-- stack ") (forward-line 1)))
-
-(defun intero--warn (message &rest args)
-  "Display a warning message made from (format MESSAGE ARGS...).
-Equivalent to 'warn', but label the warning as coming from intero."
-  (display-warning 'intero (apply 'format message args) :warning))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Intero help buffer
-
-(defun intero-help-buffer ()
-  "Get the help buffer."
-  (with-current-buffer (get-buffer-create "*Intero-Help*")
-    (unless (eq major-mode 'intero-help-mode) (intero-help-mode))
-    (current-buffer)))
-
-(defvar-local intero-help-entries nil
-  "History for help entries.")
-
-(defun intero-help-pagination ()
-  "Insert pagination for the current help buffer."
-  (let ((buffer-read-only nil))
-    (when (> (length intero-help-entries) 1)
-      (insert-text-button
-       "[back]"
-       'buffer (current-buffer)
-       'action (lambda (&rest ignore)
-                 (let ((first (pop intero-help-entries)))
-                   (setcdr (last intero-help-entries) (cons first nil))
-                   (intero-help-refresh)))
-       'keymap (let ((map (make-sparse-keymap)))
-                 (define-key map [mouse-1] 'push-button)
-                 map))
-      (insert " ")
-      (insert-text-button
-       "[forward]"
-       'buffer (current-buffer)
-       'keymap (let ((map (make-sparse-keymap)))
-                 (define-key map [mouse-1] 'push-button)
-                 map)
-       'action (lambda (&rest ignore)
-                 (setq intero-help-entries
-                       (intero-bring-to-front intero-help-entries))
-                 (intero-help-refresh)))
-      (insert " ")
-      (insert-text-button
-       "[forget]"
-       'buffer (current-buffer)
-       'keymap (let ((map (make-sparse-keymap)))
-                 (define-key map [mouse-1] 'push-button)
-                 map)
-       'action (lambda (&rest ignore)
-                 (pop intero-help-entries)
-                 (intero-help-refresh)))
-      (insert "\n\n"))))
-
-(defun intero-help-refresh ()
-  "Refresh the help buffer with the current thing in the history."
-  (interactive)
-  (let ((buffer-read-only nil))
-    (erase-buffer)
-    (if (car intero-help-entries)
-        (progn
-          (intero-help-pagination)
-          (insert (cdr (car intero-help-entries)))
-          (goto-char (point-min)))
-      (insert "No help entries."))))
-
-(defun intero-bring-to-front (xs)
-  "Bring the last element of XS to the front."
-  (cons (car (last xs)) (butlast xs)))
-
-(defun intero-help-push-history (buffer item)
-  "Add (BUFFER . ITEM) to the history of help entries."
-  (push (cons buffer item) intero-help-entries))
-
-(defun intero-help-info (ident)
-  "Get the info of the thing with IDENT at point."
-  (interactive (list (intero-ident-at-point)))
-  (with-current-buffer (car (car intero-help-entries))
-    (intero-info ident)))
-
-(define-derived-mode intero-help-mode help-mode "Intero-Help"
-  "Help mode for intero."
-  (setq buffer-read-only t)
-  (setq intero-help-entries nil))
-
-(define-key intero-help-mode-map (kbd "g") 'intero-help-refresh)
-(define-key intero-help-mode-map (kbd "C-c C-i") 'intero-help-info)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Intero highlight uses mode
-
-(defvar intero-highlight-uses-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "n") 'intero-highlight-uses-mode-next)
-    (define-key map (kbd "TAB") 'intero-highlight-uses-mode-next)
-    (define-key map (kbd "p") 'intero-highlight-uses-mode-prev)
-    (define-key map (kbd "S-TAB") 'intero-highlight-uses-mode-prev)
-    (define-key map (kbd "<backtab>") 'intero-highlight-uses-mode-prev)
-    (define-key map (kbd "RET") 'intero-highlight-uses-mode-stop-here)
-    (define-key map (kbd "r") 'intero-highlight-uses-mode-replace)
-    (define-key map (kbd "q") 'intero-highlight-uses-mode)
-    map)
-  "Keymap for using `intero-highlight-uses-mode'.")
-
-(defvar-local intero-highlight-uses-mode-point nil)
-(defvar-local intero-highlight-uses-buffer-old-mode nil)
-
-;;;###autoload
-(define-minor-mode intero-highlight-uses-mode
-  "Minor mode for highlighting and jumping between uses."
-  :lighter " Uses"
-  :keymap intero-highlight-uses-mode-map
-  (if intero-highlight-uses-mode
-      (progn (setq intero-highlight-uses-buffer-old-mode buffer-read-only)
-             (setq buffer-read-only t)
-             (setq intero-highlight-uses-mode-point (point)))
-    (progn (setq buffer-read-only intero-highlight-uses-buffer-old-mode)
-           (when intero-highlight-uses-mode-point
-             (goto-char intero-highlight-uses-mode-point))))
-  (remove-overlays (point-min) (point-max) 'intero-highlight-uses-mode-highlight t))
-
-(defun intero-highlight-uses-mode-replace ()
-  "Replace all highlighted instances in the buffer with something else."
-  (interactive)
-  (save-excursion
-    (goto-char (point-min))
-    (let ((o (intero-highlight-uses-mode-next)))
-      (when o
-        (let ((replacement
-               (read-from-minibuffer
-                (format "Replace uses %s with: "
-                        (buffer-substring
-                         (overlay-start o)
-                         (overlay-end o))))))
-          (let ((inhibit-read-only t))
-            (while o
-              (goto-char (overlay-start o))
-              (delete-region (overlay-start o)
-                             (overlay-end o))
-              (insert replacement)
-              (setq o (intero-highlight-uses-mode-next))))))))
-  (intero-highlight-uses-mode -1))
-
-(defun intero-highlight-uses-mode-stop-here ()
-  "Stop at this point."
-  (interactive)
-  (setq intero-highlight-uses-mode-point (point))
-  (intero-highlight-uses-mode -1))
-
-(defun intero-highlight-uses-mode-next ()
-  "Jump to next result."
-  (interactive)
-  (let ((os (sort (cl-remove-if (lambda (o)
-                                  (or (<= (overlay-start o) (point))
-                                      (not (overlay-get o 'intero-highlight-uses-mode-highlight))))
-                                (overlays-in (point) (point-max)))
-                  (lambda (a b)
-                    (< (overlay-start a)
-                       (overlay-start b))))))
-    (when os
-      (mapc
-       (lambda (o)
-         (when (overlay-get o 'intero-highlight-uses-mode-highlight)
-           (overlay-put o 'face 'lazy-highlight)))
-       (overlays-in (line-beginning-position) (line-end-position)))
-      (goto-char (overlay-start (car os)))
-      (overlay-put (car os) 'face 'isearch)
-      (car os))))
-
-(defun intero-highlight-uses-mode-prev ()
-  "Jump to previous result."
-  (interactive)
-  (let ((os (sort (cl-remove-if (lambda (o)
-                                  (or (>= (overlay-end o) (point))
-                                      (not (overlay-get o 'intero-highlight-uses-mode-highlight))))
-                                (overlays-in (point-min) (point)))
-                  (lambda (a b)
-                    (> (overlay-start a)
-                       (overlay-start b))))))
-    (when os
-      (mapc
-       (lambda (o)
-         (when (overlay-get o 'intero-highlight-uses-mode-highlight)
-           (overlay-put o 'face 'lazy-highlight)))
-       (overlays-in (line-beginning-position) (line-end-position)))
-      (goto-char (overlay-start (car os)))
-      (overlay-put (car os) 'face 'isearch)
-      (car os))))
-
-(defun intero-highlight-uses-mode-highlight (start end current)
-  "Make a highlight overlay at the span from START to END.
-If CURRENT, highlight the span uniquely."
-  (let ((o (make-overlay start end)))
-    (overlay-put o 'priority 999)
-    (overlay-put o 'face
-                 (if current
-                     'isearch
-                   'lazy-highlight))
-    (overlay-put o 'intero-highlight-uses-mode-highlight t)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(provide 'intero)
-
-;;; intero.el ends here