Disabled default haskell flycheckers and removed stack code.
authorLuke Hoersten <luke@hoersten.org>
Mon, 21 Sep 2015 13:35:54 -0500
changeset 83 ab9ebd922ccb
parent 82 12cf67bc486c
child 84 2ad7a42a31f7
Disabled default haskell flycheckers and removed stack code.
elisp/haskell-init.el
elisp/stack-mode/LICENSE
elisp/stack-mode/README.md
elisp/stack-mode/checklist.el
elisp/stack-mode/fifo.el
elisp/stack-mode/stack-mode.el
--- a/elisp/haskell-init.el	Fri Sep 18 17:39:07 2015 -0500
+++ b/elisp/haskell-init.el	Mon Sep 21 13:35:54 2015 -0500
@@ -39,18 +39,21 @@
 (add-hook
  'haskell-mode-hook
  (lambda ()
+   (flycheck-mode t)
+   (flycheck-disable-checker 'haskell-ghc)
+   (flycheck-disable-checker 'haskell-stack-ghc)
+   (flycheck-clear t)
    ;; (imenu-add-menubar-index)
    ;; (haskell-indentation-mode t)
-   (stack-mode)
-   ;; (flycheck-mode)
-   (subword-mode)
+   (stack-mode t)
+   (subword-mode t)
+   (capitalized-words-mode t)
    (electric-indent-mode nil)
    (structured-haskell-mode t)
    (set-face-background 'shm-quarantine-face "lemonchiffon")
    (interactive-haskell-mode t)
 
    (setq
-    capitalized-words-mode t
     haskell-stylish-on-save t
     haskell-indentation-layout-offset 4
     haskell-indentation-left-offset 4
--- a/elisp/stack-mode/LICENSE	Fri Sep 18 17:39:07 2015 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
--- a/elisp/stack-mode/README.md	Fri Sep 18 17:39:07 2015 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-# stack-mode
--- a/elisp/stack-mode/checklist.el	Fri Sep 18 17:39:07 2015 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-;;; checklist.el --- Simple checklist UI functionality
-
-;; Copyright (c) 2015 Chris Done. All rights reserved.
-
-;; 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 this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Code:
-
-(defvar checklist-read-checklist-result nil)
-(make-variable-buffer-local 'checklist-read-checklist-result)
-
-(defun checklist-read-checklist (prompt choices)
-  "Prompt with PROMPT to choose one or more from the list of CHOICES."
-  (switch-to-buffer (generate-new-buffer-name "checklist"))
-  (let ((inhibit-read-only t))
-    (special-mode)
-    (setq buffer-read-only t)
-    (setq cursor-type 'box)
-    (insert (concat prompt "\n\n"))
-    (use-local-map (copy-keymap special-mode-map))
-    (local-set-key "n" 'next-line)
-    (local-set-key "p" 'previous-line)
-    (local-set-key (kbd "RET") 'checklist-checklist-choose)
-    (local-set-key (kbd "SPC") 'checklist-checklist-choose)
-    (local-set-key (kbd "C-c C-c") 'checklist-checklist-done)
-    (save-excursion
-      (cl-loop for choice in choices
-               do (insert (propertize (concat "[ ] " (cdr choice) "\n")
-                                      'checklist-check-item (car choice))))
-      (insert "\n")
-      (insert "Hit " (propertize "C-c C-c" 'face 'bold) " to finish."))
-    (add-hook 'post-command-hook #'checklist-highlight-section t t)
-    (setq checklist-read-checklist-result nil)
-    (recursive-edit)
-    (let ((result  checklist-read-checklist-result)
-          (kill-buffer-query-functions nil))
-      (kill-buffer (current-buffer))
-      result)))
-
-(defun checklist-checklist-done ()
-  "Done with the checklist, return the result."
-  (interactive)
-  (throw 'exit nil))
-
-(defun checklist-highlight-section ()
-  "Highlight the item at point."
-  (remove-overlays)
-  (when (get-text-property (point) 'checklist-check-item)
-    (let ((o (make-overlay (line-beginning-position)
-                           (1+ (line-end-position)))))
-      (overlay-put o 'face 'secondary-selection))))
-
-(defun checklist-checklist-choose ()
-  "Choose the current item at point."
-  (interactive)
-  (let ((inhibit-read-only t)
-        (checked (get-text-property (point) 'checklist-item-checked)))
-    (when (get-text-property (point) 'checklist-check-item)
-      (if checked
-          (setq checklist-read-checklist-result
-                (delete (get-text-property (point) 'checklist-check-item)
-                        checklist-read-checklist-result))
-          (add-to-list 'checklist-read-checklist-result
-                       (get-text-property (point) 'checklist-check-item)
-                       t))
-      (save-excursion (goto-char (line-beginning-position))
-                      (delete-region (line-beginning-position)
-                                     (+ (line-beginning-position) (length "[ ]")))
-                      (if checked
-                          (insert "[ ]")
-                        (insert "[x]")))
-      (put-text-property (line-beginning-position)
-                         (1+ (line-end-position))
-                         'checklist-item-checked (not checked))
-      (put-text-property (line-beginning-position)
-                         (1+ (line-end-position))
-                         'face (if checked nil 'bold))
-      (put-text-property (line-beginning-position)
-                         (1+ (line-end-position))
-                         'checklist-check-item t)
-      (checklist-highlight-section))))
-
-(provide 'checklist)
--- a/elisp/stack-mode/fifo.el	Fri Sep 18 17:39:07 2015 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-;;; fifo.el --- FIFO queue.
-
-;; Copyright (c) 2015 Chris Done.
-
-;; 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 this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Code:
-
-(require 'cl-lib)
-
-(defun fifo-make ()
-  "Make a fifo queue."
-  (cons 0 nil))
-
-(defun fifo-push (q a)
-  "Push a new item onto the queue."
-  (cl-assert (consp q) nil "Must be a queue.")
-  (setcar q (1+ (car q)))
-  (let ((next q)
-        (continue t))
-    (while (not (null (cdr next)))
-      (setq next (cdr next)))
-    (setcdr next (cons a nil)))
-  q)
-
-(defun fifo-pop (q)
-  "Pop the next item on the queue."
-  (cl-assert (consp q) nil "Must be a queue.")
-  (cl-assert (consp (cdr q)) nil "No items to pop from queue.")
-  (setcar q (1- (car q)))
-  (let ((a (car (cdr q))))
-    (setcdr q (cdr (cdr q)))
-    a))
-
-(defun fifo-size (q)
-  "Get the size of the queue."
-  (cl-assert (consp q) nil "Must be a queue.")
-  (car q))
-
-(defun fifo-null-p (q)
-  "Is the queue empty?"
-  (= (fifo-size q) 0))
-
-(provide 'fifo)
--- a/elisp/stack-mode/stack-mode.el	Fri Sep 18 17:39:07 2015 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,929 +0,0 @@
-;;; stack-mode.el --- A minor mode enabling various features based on
-;;; stack-ide.
-
-;; Copyright (c) 2015 Chris Done.
-
-;; 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 this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Code:
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Imports
-
-(require 'haskell-mode)
-(require 'haskell-cabal)
-(require 'cl-lib)
-(require 'fifo)
-(require 'flycheck)
-(require 'json)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Modes
-
-(define-minor-mode stack-mode
-  "A minor mode enabling various features based on stack-ide.
-
-Automatically starts and stops flycheck-mode when you
-enable/disable it. It makes this assumption in the interest of
-easier user experience. Disable with `stack-mode-manage-flycheck'."
-  :lighter " Stack"
-  :keymap (let ((map (make-sparse-keymap)))
-            (define-key map (kbd "M-.") 'stack-mode-goto)
-            (define-key map (kbd "C-c C-k") 'stack-mode-clear)
-            (define-key map (kbd "C-c C-t") 'stack-mode-type)
-            (define-key map (kbd "C-c C-i") 'stack-mode-info)
-            (define-key map (kbd "C-c C-l") 'stack-mode-load)
-            map)
-  (when (buffer-file-name)
-    (if stack-mode
-        (progn (when (bound-and-true-p interactive-haskell-mode)
-                 (when (y-or-n-p "interactive-haskell-mode is enabled. Disable it?")
-                   (interactive-haskell-mode -1)))
-               (when stack-mode-manage-flycheck
-                 (flycheck-mode 1)
-                 (flycheck-disable-checker 'haskell-ghc)
-                 (flycheck-select-checker 'stack-ide)
-                 (flycheck-buffer)))
-      (when stack-mode-manage-flycheck
-        (flycheck-mode -1)))))
-
-(define-derived-mode inferior-stack-mode fundamental-mode "Inferior-Stack-IDE"
-  "Major mode for interacting with an inferior stack-ide process.")
-
-(define-key inferior-stack-mode-map (kbd "C-c C-c") 'stack-mode-stop)
-(define-key inferior-stack-mode-map (kbd "C-c C-k") 'stack-mode-clear)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Customization
-
-(defgroup stack-mode nil
-  "IDE backend support for Haskell."
-  :group 'haskell)
-
-(defcustom stack-mode-proc-path
-  "stack"
-  "Path to the stack executable."
-  :type 'string
-  :group 'stack-mode)
-
-(defcustom stack-mode-manage-flycheck
-  t
-  "Automatically start and stop flycheck when the minor mode is
-enabled/disabled."
-  :type 'boolean
-  :group 'stack-mode)
-
-(defcustom stack-mode-print-error-messages
-  nil
-  "Print error messages after loading the project?"
-  :type 'boolean
-  :group 'stack-mode)
-
-(defcustom stack-mode-show-popup
-  nil
-  "Show type and info messages in a popup?"
-  :type 'boolean
-  :group 'stack-mode)
-
-(defvar stack-mode-queue nil)
-(make-variable-buffer-local 'stack-mode-queue)
-
-(defvar stack-mode-back-queue nil)
-(make-variable-buffer-local 'stack-mode-back-queue)
-
-(defvar stack-mode-buffer nil)
-(make-variable-buffer-local 'stack-mode-buffer)
-
-(defvar stack-mode-name nil)
-(make-variable-buffer-local 'stack-mode-name)
-
-(defvar stack-mode-tried-to-start nil)
-(make-variable-buffer-local 'stack-mode-tried-to-start)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Interactive functions
-
-(defun stack-mode-status ()
-  "Print the status of the current stack process."
-  (interactive)
-  (if (stack-mode-buffer)
-      (if (stack-mode-process)
-          (if (process-live-p (stack-mode-process))
-              (message "The process is live.")
-            (message "There is a Stack process, but it's dead."))
-        (message "There is a stack buffer, but no Stack process."))
-    (message "There is no Stack buffer.")))
-
-(defun stack-mode-start ()
-  "Start an inferior process and buffer."
-  (interactive)
-  (if (stack-mode-live-p)
-      (switch-to-buffer (stack-mode-buffer))
-    (with-current-buffer (stack-mode-buffer)
-      (setq buffer-read-only t)
-      (inferior-stack-mode)
-      (stack-mode-set-initial-command)
-      (setq stack-mode-buffer "")
-      (let* ((project-name (stack-mode-name))
-             (name (stack-mode-process-name project-name))
-             (args (append (list name
-                                 nil
-                                 stack-mode-proc-path
-                                 "ide"
-                                 "start")
-                           (list project-name)))
-             (process (or (get-process name)
-                          (progn (stack-mode-log "Starting: %S" args)
-                                 (apply #'start-process
-                                        args)))))
-        (set-process-sentinel process 'stack-mode-sentinel)
-        (set-process-filter process 'stack-mode-filter)))))
-
-(defun stack-mode-set-initial-command ()
-  "Set the initial command callback. The `stack ide` command will
-reload targets on start-up, so that's the default command we'll
-start with."
-  (setq stack-mode-current-command
-        (list :json nil
-              :data nil
-              :cont 'stack-mode-loading-callback
-              :label nil))
-  (setq stack-mode-queue (fifo-make))
-  (stack-mode-log "Set initial command."))
-
-(defun stack-mode-stop ()
-  "Stop the process."
-  (interactive)
-  (with-current-buffer (stack-mode-buffer)
-    (when (stack-mode-process)
-      (setq stack-mode-current-command nil)
-      (setq stack-mode-buffer "")
-      (kill-process (stack-mode-process))
-      (delete-process (stack-mode-process)))))
-
-(defun stack-mode-reset ()
-  "Reset the process."
-  (interactive)
-  (with-current-buffer (stack-mode-buffer)
-    (when (stack-mode-process)
-      (setq stack-mode-current-command nil)
-      (setq stack-mode-buffer "")
-      (setq stack-mode-queue (fifo-make)))))
-
-(defun stack-mode-restart ()
-  "Restart the process with a fresh command queue."
-  (interactive)
-  (stack-mode-stop)
-  (stack-mode-start))
-
-(defun stack-mode-live-p ()
-  "Is the process alive?"
-  (and (stack-mode-process)
-       (process-live-p (stack-mode-process))))
-
-(defun stack-mode-clear ()
-  "Clear the interaction buffer."
-  (interactive)
-  (with-current-buffer (stack-mode-buffer)
-    (let ((inhibit-read-only t))
-      (erase-buffer))))
-
-(defun stack-mode-load ()
-  "Load the current buffer's file."
-  (interactive)
-  (save-buffer)
-  (with-current-buffer (stack-mode-buffer)
-    (stack-mode-reload)))
-
-(defun stack-mode-goto ()
-  "Go to definition of thing at point."
-  (interactive)
-  (let ((filename (buffer-file-name))
-        (module-name (haskell-guess-module-name))
-        (span (stack-mode-span)))
-    (let* ((span-info
-            (stack-mode-get-span-info
-             module-name
-             (with-current-buffer (stack-mode-buffer)
-               (file-relative-name filename default-directory))
-             span))
-           (infos
-            (stack-contents
-             span-info))
-           (_ (when (and (vectorp infos) (= 0 (length infos)))
-                (error "Couldn't find location for this. Is the module loaded in the backend?
-Run `M-x stack-mode-list-loaded-modules' to see what's loaded.")))
-           (parts (mapcar #'identity (elt infos 0)))
-           (info (stack-contents (elt parts 0)))
-           (span (elt parts 1))
-           (scope (stack-lookup 'tag (stack-lookup 'idScope info)))
-           (def-span (stack-lookup-contents
-                      'idDefSpan
-                      (stack-lookup 'idProp info))))
-      (cond
-       ((listp def-span)
-        (stack-mode-goto-span def-span))
-       (t
-        (let* ((imported-from
-                (stack-lookup
-                 'idImportedFrom
-                 (stack-lookup 'idScope info)))
-               (imported-module (stack-lookup 'moduleName imported-from))
-               (defined-in (stack-lookup
-                            'idDefinedIn
-                            (stack-lookup 'idProp info)))
-               (package (stack-lookup 'modulePackage defined-in))
-               (package-name (stack-lookup 'packageName package))
-               (package-ver (stack-lookup 'packageVersion package))
-               (module (stack-lookup 'moduleName defined-in)))
-          (message "Imported via %s, defined in %s (%s-%s)"
-                   (haskell-fontify-as-mode imported-module 'haskell-mode)
-                   (haskell-fontify-as-mode module 'haskell-mode)
-                   package-name
-                   package-ver)))))))
-
-(defun stack-mode-list-loaded-modules ()
-  "List the loaded modules in the backend."
-  (interactive)
-  (let ((modules
-         (stack-contents
-          (with-current-buffer (stack-mode-buffer)
-            (stack-mode-call
-             `((tag . "RequestGetLoadedModules")
-               (contents
-                . [])))))))
-    (pop-to-buffer (stack-mode-buffer))
-    (stack-mode-log "Loaded modules: %s"
-                    (mapconcat #'identity
-                               (sort (mapcar #'identity modules) #'string<)
-                               "\n"))))
-
-(defun stack-mode-info ()
-  "Display the info of the thing at point."
-  (interactive)
-  (let* ((filename (buffer-file-name))
-         (module-name (haskell-guess-module-name))
-         (points (stack-mode-points))
-         (orig (point))
-         (span (stack-mode-span-from-points (car points)
-                                            (cdr points)))
-         (info (stack-mode-get-span-info
-                module-name
-                (with-current-buffer (stack-mode-buffer)
-                  (file-relative-name filename default-directory))
-                span))
-         (info-contents (stack-contents (elt (elt (stack-contents info) 0) 0)))
-         (scope (stack-lookup 'idScope info-contents))
-         (prop (stack-lookup 'idProp info-contents))
-         (qual (stack-lookup 'idImportQual scope))
-         (from (stack-lookup 'idImportedFrom scope))
-         (span (stack-lookup 'idImportSpan scope))
-
-         (space (stack-lookup 'idSpace prop))
-         (idDefSpan (stack-lookup 'idDefSpan prop))
-         (idDefinedIn (stack-lookup 'idDefinedIn prop))
-         (modulePackage (stack-lookup 'modulePackage idDefinedIn))
-         (moduleName (stack-lookup 'moduleName idDefinedIn))
-         (packageVersion (stack-lookup 'packageVersion modulePackage))
-         (packageKey (stack-lookup 'packageKey modulePackage))
-         (packageName (stack-lookup 'packageKey modulePackage))
-         (idType (stack-lookup 'idType prop))
-         (idName (stack-lookup 'idName prop)))
-    (let ((info-string (concat
-                        "Identifier: " (haskell-fontify-as-mode idName 'haskell-mode) "\n"
-                        "Type: " (haskell-fontify-as-mode idType 'haskell-mode) "\n"
-                        "Module: " (haskell-fontify-as-mode moduleName 'haskell-mode) "\n"
-                        "Package: "  (if (string= "main" packageName)
-                                         "(this one)"
-                                       packageName))))
-      (cond (stack-mode-show-popup
-             (when (boundp popup-tip)
-               (popup-tip info-string)))
-            (t (message info-string))))))
-
-(defun stack-mode-type (&optional insert-value)
-  "Display type info of thing at point."
-  (interactive "P")
-  (let* ((filename (buffer-file-name))
-         (module-name (haskell-guess-module-name))
-         (points (stack-mode-points))
-         (orig (point))
-         (span (stack-mode-span-from-points (car points)
-                                            (cdr points))))
-    (let* ((types (stack-contents
-                   (stack-mode-get-exp-types
-                    module-name
-                    (with-current-buffer (stack-mode-buffer)
-                      (file-relative-name filename default-directory))
-                    span)))
-           (types (mapcar #'identity types))
-           (code (buffer-substring-no-properties
-                  (car points)
-                  (cdr points)))
-           (type (stack-contents (car types)))
-           (ty (stack-lookup 'text type)))
-      (if insert-value
-          (let ((ident-pos (haskell-ident-pos-at-point)))
-            (cond
-             ((region-active-p)
-              (delete-region (region-beginning)
-                             (region-end))
-              (insert "(" code " :: " ty ")")
-              (goto-char (1+ orig)))
-             ((= (line-beginning-position) (car ident-pos))
-              (goto-char (line-beginning-position))
-              (insert code " :: " (haskell-fontify-as-mode ty 'haskell-mode)
-                      "\n"))
-             (t
-              (save-excursion
-                (goto-char (car ident-pos))
-                (let ((col (current-column)))
-                  (save-excursion (insert "\n")
-                                  (indent-to col))
-                  (insert code " :: " (haskell-fontify-as-mode ty 'haskell-mode)))))))
-        (unless (null types)
-          (let ((type-string (format "%s"
-                                     (mapconcat (lambda (type)
-                                                  (haskell-fontify-as-mode
-                                                   (concat
-                                                    code
-                                                    " :: "
-                                                    (elt type 0))
-                                                   'haskell-mode))
-                                                (cl-subseq types 0 1)
-                                                "\n"))))
-            (cond (stack-mode-show-popup (popup-tip type-string))
-                  (t (message type-string)))))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Process filters and sentinel
-
-(defun stack-mode-filter (process response)
-  (with-current-buffer (stack-mode-buffer (stack-mode-name-from-process process))
-    (if stack-mode-current-command
-        (let* ((lines (split-string (concat stack-mode-buffer response) "\n")))
-          (setq stack-mode-buffer (car (last lines)))
-          (setq lines (butlast lines))
-          (let ((data (plist-get stack-mode-current-command :data))
-                (cont (plist-get stack-mode-current-command :cont)))
-            (while lines
-              (let ((line (pop lines)))
-                (stack-mode-log
-                 "%s <- %s"
-                 (if (plist-get stack-mode-current-command :label)
-                     (format "[%s]" (plist-get stack-mode-current-command :label))
-                   "")
-                 (haskell-fontify-as-mode line 'javascript-mode))
-                (when (let* ((error-msg nil)
-                             (json (condition-case e
-                                       (json-read-from-string line)
-                                     (error "Problem reading JSON from server, probably an error message:\n%s" line)))
-                             (ret (condition-case e
-                                      (funcall cont data json)
-                                    (error (setq error-msg e)
-                                           :error))))
-                        (cl-ecase ret
-                          (:done t)
-                          (:continue nil)
-                          (:error
-                           (setq stack-mode-buffer "")
-                           (setq stack-mode-current-command nil)
-                           (setq stack-mode-queue nil)
-                           (error "Command handler error: %S\n\nThe command queue has been cleared."
-                                  error-msg))
-                          (t
-                           (error "A command handler must return either :done or :continue,
-but it returned: %S
-command was: %S" ret stack-mode-current-command))))
-                  (cl-loop for line in lines
-                           do (stack-mode-log
-                               "Extraneous lines after command completed: %s"
-                               (haskell-fontify-as-mode line 'javascript-mode)))
-                  (setq stack-mode-current-command nil)
-                  (setq lines nil)
-                  (stack-mode-queue-trigger))))))
-      (stack-mode-log "Ignoring: %s"
-                      (haskell-fontify-as-mode response 'javascript-mode)))))
-
-(defun stack-mode-sentinel (process event)
-  (with-current-buffer (stack-mode-buffer (stack-mode-name-from-process process))
-    (stack-mode-log "Process event: %s" event)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Command queue
-
-(defvar stack-mode-current-command nil
-  "Current command handler.")
-(make-variable-buffer-local 'stack-mode-current-command)
-
-(defvar stack-mode-buffer ""
-  "A buffer for the process.")
-(make-variable-buffer-local 'stack-mode-buffer)
-
-(defvar stack-mode-queue nil
-  "Command queue.")
-(make-variable-buffer-local 'stack-mode-queue)
-
-(defun stack-mode-queue ()
-  "Get the FIFO queue of this process."
-  (or stack-mode-queue
-      (setq stack-mode-queue (fifo-make))))
-
-(defun stack-mode-back-queue ()
-  "Get the FIFO back queue of this process."
-  (or stack-mode-back-queue
-      (setq stack-mode-back-queue (fifo-make))))
-
-(defun stack-mode-enqueue-front (json data cont &optional label)
-  "Enqueue a JSON command to the command queue, calling (CONT
-DATA line) for each response line until CONT returns nil. This is
-the first priority queue, anything pushed to this queue will be
-run before anything in the back queue."
-  (cond
-   ((stack-mode-live-p)
-    (stack-mode-log "[%s] => %s" label (haskell-fontify-as-mode (json-encode json) 'javascript-mode))
-    (fifo-push (stack-mode-queue)
-               (list :json json :data data :cont cont :label label))
-    (stack-mode-queue-trigger))
-   (t (stack-mode-try-start))))
-
-(defun stack-mode-enqueue (json data cont &optional label)
-  "Same as `stack-mode-front', but puts it on the back
-queue. Items are only moved onto the front queue when the front
-queue is empty. This lets a command which consists of a few back
-and forth steps to continue its processing uninterrupted."
-  (cond
-   ((stack-mode-live-p)
-    (stack-mode-log "[%s] ~> %s" label (haskell-fontify-as-mode (json-encode json) 'javascript-mode))
-    (fifo-push (stack-mode-back-queue)
-               (list :json json :data data :cont cont :label label))
-    (stack-mode-queue-trigger))
-   (t (stack-mode-try-start))))
-
-(defun stack-mode-try-start ()
-  "Try to start, but only try once."
-  (cond
-   ((not stack-mode-tried-to-start)
-    (setq stack-mode-tried-to-start t)
-    (message "Starting a Stack IDE backend process for this project: %s, stack directory: %s"
-             (stack-mode-cabal-name)
-             (stack-mode-dir))
-    (stack-mode-start))
-   (t (message "Attempted to run a Stack IDE command, but the server isn't started. We already tried once this session. Run `M-x stack-mode-restart` to confirm that you want to start it."))))
-
-(defun stack-mode-call (json)
-  "Call a JSON command. Wait for any existing queued commands to
-complete, then sends the request, blocking on the
-response. Returns the response."
-  (let ((data (list nil)))
-    (stack-mode-enqueue
-     json data
-     (lambda (data reply)
-       (setcar data reply)
-       :done))
-    (stack-mode-queue-flush)
-    (car-safe data)))
-
-(defun stack-mode-queue-processed-p ()
-  "Return t if command queue has been completely processed."
-  (and (fifo-null-p stack-mode-queue)
-       (null stack-mode-current-command)))
-
-(defun stack-mode-queue-flush ()
-  "Block till PROCESS's command queue has been completely processed.
-This uses `accept-process-output' internally."
-  (let ((proc (stack-mode-process)))
-    (while (not (stack-mode-queue-processed-p))
-      (stack-mode-queue-trigger)
-      (accept-process-output proc 1))))
-
-(defun stack-mode-queue-trigger ()
-  "Trigger the next command in the queue if there is no current
-command."
-  (if stack-mode-current-command
-      (unless (fifo-null-p (stack-mode-queue))
-        (stack-mode-log "Stack command queue is currently active, waiting ..."))
-    (when (fifo-null-p (stack-mode-queue))
-      (stack-mode-log "Command queue is now empty.")
-      (unless (fifo-null-p (stack-mode-back-queue))
-        (stack-mode-log "Pushing next item from back queue to front queue ...")
-        (fifo-push (stack-mode-queue)
-                   (fifo-pop (stack-mode-back-queue)))))
-    (unless (fifo-null-p (stack-mode-queue))
-      (setq stack-mode-current-command
-            (fifo-pop (stack-mode-queue)))
-      (stack-mode-log
-       "[%S] -> %s"
-       (plist-get stack-mode-current-command :label)
-       (haskell-fontify-as-mode
-        (json-encode (plist-get stack-mode-current-command :json))
-        'javascript-mode))
-      (process-send-string
-       (stack-mode-process)
-       (concat (json-encode (plist-get stack-mode-current-command :json))
-               "\n")))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Project functions
-
-(defun stack-mode-packages ()
-  "Get packages for the Stack configuration."
-  (split-string (shell-command-to-string "stack ide packages") "\n" t))
-
-(defun stack-mode-process ()
-  "Get the current process."
-  (get-process (stack-mode-process-name (stack-mode-name))))
-
-(defun stack-mode-buffer (&optional name)
-  "The inferior buffer."
-  (let ((default-directory (stack-mode-dir)))
-    (get-buffer-create
-     (stack-mode-buffer-name
-      (or name
-          (stack-mode-name))))))
-
-(defun stack-mode-name-from-process (proc)
-  "Get the name of the project from the process."
-  (substring (process-name proc) (length "stack:")))
-
-(defun stack-mode-process-name (name)
-  "Name for the inferior process."
-  (format "stack:%s"
-          name))
-
-(defun stack-mode-buffer-name (name)
-  "Name for the inferior buffer."
-  (format "*stack:%s*"
-          name))
-
-(defun stack-mode-dir ()
-  "The directory for the project."
-  (file-name-directory (haskell-cabal-find-file)))
-
-(defun stack-mode-name ()
-  "The name for the current project based on the current
-directory."
-  (or stack-mode-name
-      (setq stack-mode-name
-            (stack-mode-cabal-name))))
-
-(defun stack-mode-cabal-name ()
-  "Get the name of the session to use, based on the cabal file."
-  (let ((cabal-file (haskell-cabal-find-file)))
-    (if (string-match "\\([^\\/]+\\)\\.cabal$" cabal-file)
-        (let ((name (match-string 1 cabal-file)))
-          (when (not (member name (stack-mode-packages)))
-            (message "This cabal project ā€œ%sā€ isn't in your stack.yaml configuration." name))
-          name)
-      (progn (message "Couldn't figure out cabal file, assuming no project.")
-             nil))))
-
-(defun stack-mode-log (&rest args)
-  "Log a string to the inferior buffer."
-  (with-current-buffer (stack-mode-buffer)
-    (goto-char (point-max))
-    (let ((inhibit-read-only t))
-      (insert (apply #'format args)
-              "\n"))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Commands
-
-(defun stack-mode-reload ()
-  "Compile the code and fetch compile errors."
-  (with-current-buffer (stack-mode-buffer)
-    (stack-mode-enqueue
-     `((tag . "RequestUpdateSession")
-       (contents . []))
-     nil
-     'stack-mode-loading-callback)))
-
-;; (defun stack-mode-load-buffer ()
-;;   "Compile the code and fetch compile errors."
-;;   (interactive)
-;;   (with-current-buffer (stack-mode-buffer)
-;;     (stack-mode-enqueue
-;;      `((tag . "RequestUpdateSession")
-;;        (contents . [((tag . "RequestUpdateTargets")
-;;                      (contents . ((tag . "TargetsInclude")
-;;                                   (contents . ["src/Stack/Package.hs"]))))]))
-;;      nil
-;;      'stack-mode-loading-callback)))
-
-(defun stack-mode-get-span-info (module file span)
-  "Get the span info of the given location."
-  (with-current-buffer (stack-mode-buffer)
-    (stack-mode-call
-     `((tag . "RequestGetSpanInfo")
-       (contents
-        . ((spanFilePath   . ,file)
-           (spanFromLine   . ,(plist-get span :sl))
-           (spanFromColumn . ,(plist-get span :sc))
-           (spanToLine     . ,(plist-get span :el))
-           (spanToColumn   . ,(plist-get span :ec))))))))
-
-(defun stack-mode-get-exp-types (module file span)
-  "Get the type info of the given location."
-  (with-current-buffer (stack-mode-buffer)
-    (stack-mode-call
-     `((tag . "RequestGetExpTypes")
-       (contents
-        . ((spanFilePath   . ,file)
-           (spanFromLine   . ,(plist-get span :sl))
-           (spanFromColumn . ,(plist-get span :sc))
-           (spanToLine     . ,(plist-get span :el))
-           (spanToColumn   . ,(plist-get span :ec))))))))
-
-(defun stack-mode-get-use-sites (module file span)
-  "Get all uses of an identifier."
-  )
-
-(defun stack-mode-get-completions (module string)
-  "Get all uses of an identifier."
-  )
-
-(defun stack-mode-loading-callback (_ reply)
-  "Callback for when loading modules."
-  (let ((tag (stack-tag reply)))
-    (cond
-     ((string= tag "ResponseUpdateSession")
-      (let* ((contents (stack-contents reply))
-             (tag (stack-tag contents)))
-        (cond
-         ((string= tag "UpdateStatusProgress")
-          (stack-mode-progress-callback _ reply)
-          :continue)
-         ((string= tag "UpdateStatusDone")
-          (stack-mode-enqueue-front
-           `((tag . "RequestGetSourceErrors")
-             (contents . []))
-           nil
-           'stack-mode-get-source-errors-callback)
-          :done)
-         (t :continue))))
-     (t
-      :continue))))
-
-(defun stack-mode-progress-callback (_ reply)
-  "Callback for status reports. Utilized in multiple places."
-  (let* ((contents (stack-contents reply))
-         (update (stack-contents contents))
-         (step (stack-lookup 'progressStep update))
-         (total (stack-lookup 'progressNumSteps update))
-         (msg (stack-lookup 'progressParsedMsg update)))
-    (message "[%s/%s] %s"
-             (propertize (number-to-string step) 'face 'compilation-line-number)
-             (propertize (number-to-string total) 'face 'compilation-line-number)
-             msg)))
-
-(defun stack-mode-get-source-errors-callback (_ reply)
-  "Handle the reply from getting source errors."
-  (let ((tag (stack-tag reply)))
-    (cond
-     ((string= tag "ResponseGetSourceErrors")
-      (let ((any-errors nil)
-            (warnings 0))
-        (cl-loop
-         for item in (mapcar #'identity (stack-contents reply))
-         do (let* ((kind (stack-lookup 'errorKind item))
-                   (span (stack-contents (stack-lookup 'errorSpan item)))
-                   (msg (stack-lookup 'errorMsg item))
-                   (fp (stack-lookup 'spanFilePath span))
-                   (sl (stack-lookup 'spanFromLine span))
-                   (sc (stack-lookup 'spanFromColumn span))
-                   (el (stack-lookup 'spanToLine span))
-                   (ec (stack-lookup 'spanToColumn span)))
-              (cond ((string= kind "KindError")
-                     (setq any-errors t))
-                    ((string= kind "KindWarning")
-                     (setq warnings (1+ warnings))))
-              (when
-                  stack-mode-print-error-messages
-                (message "%s"
-                         (propertize
-                          (format "%s:(%d,%d)-(%d,%d): \n%s"
-                                  fp sl sc el ec msg)
-                          'face
-                          (cond
-                           ((string= kind "KindWarning")
-                            'compilation-warning)
-                           ((string= kind "KindError")
-                            'compilation-error)))))))
-        (unless any-errors
-          (if (= 0 warnings)
-              (message "OK.")
-            (message (propertize "OK (%d warning%s)." 'face 'compilation-warning)
-                     warnings
-                     (if (= 1 warnings) "" "s")))))
-      :done)
-     (t :done))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Span functions
-
-(defun stack-mode-points ()
-  "Get the current points; either a selected region or an
-identifier's points."
-  (if (region-active-p)
-      (cons (region-beginning) (region-end))
-    (let ((ident (haskell-ident-pos-at-point)))
-      (cons (car ident)
-            (cdr ident)))))
-
-(defun stack-mode-span-from-points (beg end)
-  "Get the span representation for the span from BEG to END."
-  (save-excursion
-    (list :sl (progn (goto-char beg)
-                     (line-number-at-pos))
-          :sc (1+ (current-column))
-          :el (progn (goto-char end)
-                     (line-number-at-pos))
-          :ec (1+ (current-column)))))
-
-(defun stack-mode-span ()
-  "Get the span from the haskell points."
-  (let ((points (or (haskell-spanable-pos-at-point)
-                    (haskell-ident-pos-at-point)
-                    (stack-mode-loose-ident-at-point))))
-    (if points
-        (stack-mode-span-from-points (car points) (cdr points))
-      (error "No identifier at point."))))
-
-(defun stack-mode-goto-span (span)
-  "Get buffer points from a span."
-  (with-current-buffer (stack-mode-buffer)
-    (find-file (stack-lookup 'spanFilePath span))
-    (goto-char (point-min))
-    (let ((beg (point)))
-      (goto-char (point-min))
-      (forward-line (1- (stack-lookup 'spanFromLine span)))
-      (goto-char (line-beginning-position))
-      (forward-char (1- (stack-lookup 'spanFromColumn span))))))
-
-(defun stack-mode-loose-ident-at-point ()
-  "Get the loose ident at point."
-  nil)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; JSON helpers
-
-(defun stack-mode-list->hashtable (xs)
-  "Convert a list to a hashtable."
-  (let ((h (make-hash-table)))
-    (cl-loop for (key . val)
-             in xs
-             do (puthash key val h))
-    h))
-
-(defun stack-lookup (key object)
-  "Get from a JSON object."
-  (cdr (assoc key (mapcar #'identity object))))
-
-(defun stack-contents (object)
-  "Get from a JSON object."
-  (stack-lookup 'contents object))
-
-(defun stack-tag (object)
-  "Get the tag of an object."
-  (stack-lookup 'tag object))
-
-(defun stack-lookup-contents (key object)
-  "Get from a JSON object."
-  (stack-contents (stack-lookup key object)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Flycheck integration
-
-(defun stack-mode-flycheck-start (checker flycheck-callback &optional buffer attempt-count)
-  "Run a compile on demand, triggered by Flycheck."
-  (when buffer (set-buffer buffer))
-  (let ((max-attempts 2))
-    (if (not (stack-mode-live-p))
-        (if (> (or attempt-count 0) max-attempts)
-            (stack-mode-log "Stack backend isn't ready for Flycheck use. Giving up (waited %d seconds)."
-                            max-attempts)
-          (stack-mode-log "Stack backend isn't ready. Waiting (%d attempts) ..."
-                          (or attempt-count 0))
-          (progn (stack-mode-log "Flycheck tried to use the Stack backend, but the Stack backend isn't started yet. Starting it ...")
-                 (stack-mode-try-start)
-                 (run-with-idle-timer 1 nil 'stack-mode-flycheck-start checker flycheck-callback
-                                      (current-buffer)
-                                      (1+ (or attempt-count 0)))))
-      (progn (stack-mode-log "Running Flycheck with Stack backend ...")
-             (write-region (point-min) (point-max) (buffer-file-name))
-             (clear-visited-file-modtime)
-             (let ((source-buffer (current-buffer))
-                   (label (format "flycheck %s" (buffer-name (current-buffer)))))
-               (with-current-buffer (stack-mode-buffer)
-                 (stack-mode-enqueue
-                  `((tag . "RequestUpdateSession")
-                    (contents . []))
-                  (list :flycheck-callback flycheck-callback
-                        :stack-buffer (current-buffer)
-                        :source-buffer source-buffer
-                        :label label)
-                  'stack-mode-flycheck-callback
-                  label)))))))
-
-(defun stack-mode-flycheck-callback (state reply)
-  "Callback for the flycheck loading. Once done, it will report
-  errors/warnings to CALLBACK."
-  (let ((tag (stack-tag reply)))
-    (cond
-     ((string= tag "ResponseUpdateSession")
-      (let* ((contents (stack-contents reply))
-             (tag (stack-tag contents)))
-        (cond
-         ((string= tag "UpdateStatusProgress")
-          (stack-mode-progress-callback nil reply)
-          :continue)
-         ((string= tag "UpdateStatusDone")
-          (stack-mode-enqueue-front
-           `((tag . "RequestGetSourceErrors")
-             (contents . []))
-           state
-           'stack-mode-flycheck-errors-callback
-           (plist-get state :label))
-          :done)
-         (t :continue))))
-     (t
-      :continue))))
-
-(defun stack-mode-flycheck-errors-callback (state reply)
-  "Collect error messages and pass them to FLYCHECK-CALLBACK."
-  (let ((tag (stack-tag reply)))
-    (cond
-     ((string= tag "ResponseGetSourceErrors")
-      (let ((messages (list)))
-        (cl-loop
-         for item in (mapcar #'identity (stack-contents reply))
-         do (let* ((kind (stack-lookup 'errorKind item))
-                   (span (stack-contents (stack-lookup 'errorSpan item)))
-                   (msg (stack-lookup 'errorMsg item))
-                   (filename (stack-lookup 'spanFilePath span))
-                   (sl (stack-lookup 'spanFromLine span))
-                   (sc (stack-lookup 'spanFromColumn span))
-                   (el (stack-lookup 'spanToLine span))
-                   (ec (stack-lookup 'spanToColumn span)))
-              (let ((orig (current-buffer))
-                    (buffer
-                     (with-current-buffer (plist-get state :stack-buffer)
-                       (let ((value (get-file-buffer filename)))
-                             (if (listp value)
-                                 (car value)
-                               value)))))
-                (if (not (null buffer))
-                 (add-to-list
-                  'messages
-                  (flycheck-error-new-at
-                   sl sc
-                   (cond
-                    ((string= kind "KindWarning") 'warning)
-                    ((string= kind "KindError") 'error)
-                    (t (message "kind: %s" kind)'error))
-                   msg
-                   :checker 'stack-ide
-                   :buffer buffer)
-                  t))
-                (set-buffer orig))))
-        ;; Calling it asynchronously is necessary for flycheck to
-        ;; work properly. See
-        ;; <https://github.com/flycheck/flycheck/pull/524#issuecomment-64947118>
-        ;;
-        ;; Also, the `stack-mode-call-in-buffer' utility is also
-        ;; needed because the reply needs to be called in the same
-        ;; buffer.
-        (run-with-idle-timer 0
-                             nil
-                             'stack-mode-call-in-buffer
-                             (plist-get state :source-buffer)
-                             (plist-get state :flycheck-callback)
-                             'finished
-                             messages)
-        (message "Flycheck done."))
-      :done)
-     (t :done))))
-
-(defun stack-mode-call-in-buffer (buffer func &rest args)
-  "Utility function which calls FUNC in BUFFER with ARGS."
-  (with-current-buffer buffer
-    (apply func args)))
-
-(flycheck-define-generic-checker 'stack-ide
-  "A syntax and type checker for Haskell using Stack's IDE support."
-  :start 'stack-mode-flycheck-start
-  :modes '(haskell-mode)
-  :next-checkers '((warning . haskell-hlint)))
-
-(provide 'stack-mode)