about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180913.348/haskell-interactive-mode.el
diff options
context:
space:
mode:
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180913.348/haskell-interactive-mode.el')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180913.348/haskell-interactive-mode.el1129
1 files changed, 0 insertions, 1129 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180913.348/haskell-interactive-mode.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180913.348/haskell-interactive-mode.el
deleted file mode 100644
index c218c6c3facb..000000000000
--- a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180913.348/haskell-interactive-mode.el
+++ /dev/null
@@ -1,1129 +0,0 @@
-;;; haskell-interactive-mode.el --- The interactive Haskell mode -*- lexical-binding: t -*-
-
-;; Copyright © 2011-2012  Chris Done
-;;             2016       Arthur Fayzrakhmanov
-
-;; Author: Chris Done <chrisdone@gmail.com>
-
-;; This file is not part of GNU Emacs.
-
-;; 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:
-
-;;; Todo:
-
-;;; Code:
-
-(require 'haskell-mode)
-(require 'haskell-compile)
-(require 'haskell-process)
-(require 'haskell-session)
-(require 'haskell-font-lock)
-(require 'haskell-presentation-mode)
-(require 'haskell-utils)
-(require 'haskell-string)
-(require 'ansi-color)
-(require 'cl-lib)
-(require 'etags)
-
-(defvar-local haskell-interactive-mode-history-index 0)
-
-(defvar-local haskell-interactive-mode-history (list))
-
-(defvar-local haskell-interactive-mode-old-prompt-start nil
-  "Mark used for the old beginning of the prompt.")
-
-(defun haskell-interactive-prompt-regex ()
-  "Generate a regex for searching for any occurence of the prompt\
-at the beginning of the line.  This should prevent any
-interference with prompts that look like haskell expressions."
-  (concat "^" (regexp-quote haskell-interactive-prompt)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Globals used internally
-
-(declare-function haskell-interactive-kill "haskell")
-
-(defvar haskell-interactive-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "RET") 'haskell-interactive-mode-return)
-    (define-key map (kbd "SPC") 'haskell-interactive-mode-space)
-    (define-key map (kbd "C-j") 'haskell-interactive-mode-newline-indent)
-    (define-key map (kbd "C-a") 'haskell-interactive-mode-beginning)
-    (define-key map (kbd "<home>") 'haskell-interactive-mode-beginning)
-    (define-key map (kbd "C-c C-k") 'haskell-interactive-mode-clear)
-    (define-key map (kbd "C-c C-c") 'haskell-process-interrupt)
-    (define-key map (kbd "C-c C-f") 'next-error-follow-minor-mode)
-    (define-key map (kbd "C-c C-z") 'haskell-interactive-switch-back)
-    (define-key map (kbd "M-p") 'haskell-interactive-mode-history-previous)
-    (define-key map (kbd "M-n") 'haskell-interactive-mode-history-next)
-    (define-key map (kbd "C-c C-p") 'haskell-interactive-mode-prompt-previous)
-    (define-key map (kbd "C-c C-n") 'haskell-interactive-mode-prompt-next)
-    (define-key map (kbd "C-<up>") 'haskell-interactive-mode-history-previous)
-    (define-key map (kbd "C-<down>") 'haskell-interactive-mode-history-next)
-    (define-key map (kbd "TAB") 'haskell-interactive-mode-tab)
-    (define-key map (kbd "<C-S-backspace>") 'haskell-interactive-mode-kill-whole-line)
-    map)
-  "Keymap used in `haskell-interactive-mode'.")
-
-(define-derived-mode haskell-interactive-mode fundamental-mode "Interactive-Haskell"
-  "Interactive mode for Haskell.
-
-Key bindings:
-\\{haskell-interactive-mode-map}"
-  :group 'haskell-interactive
-  :syntax-table haskell-mode-syntax-table
-
-  (setq haskell-interactive-mode-history (list))
-  (setq haskell-interactive-mode-history-index 0)
-
-  (setq next-error-function #'haskell-interactive-next-error-function)
-  (add-hook 'completion-at-point-functions
-            #'haskell-interactive-mode-completion-at-point-function nil t)
-  (add-hook 'kill-buffer-hook #'haskell-interactive-kill nil t)
-  (haskell-interactive-mode-prompt))
-
-(defvar haskell-interactive-mode-prompt-start
-  nil
-  "Mark used for the beginning of the prompt.")
-
-(defvar haskell-interactive-mode-result-end
-  nil
-  "Mark used to figure out where the end of the current result output is.
-Used to distinguish betwen user input.")
-
-(defvar-local haskell-interactive-previous-buffer nil
-  "Records the buffer to which `haskell-interactive-switch-back' should jump.
-This is set by `haskell-interactive-switch', and should otherwise
-be nil.")
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Hooks
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Mode
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Faces
-
-;;;###autoload
-(defface haskell-interactive-face-prompt
-  '((t :inherit font-lock-function-name-face))
-  "Face for the prompt."
-  :group 'haskell-interactive)
-
-;;;###autoload
-(defface haskell-interactive-face-prompt2
-  '((t :inherit font-lock-keyword-face))
-  "Face for the prompt2 in multi-line mode."
-  :group 'haskell-interactive)
-
-;;;###autoload
-(defface haskell-interactive-face-compile-error
-  '((t :inherit compilation-error))
-  "Face for compile errors."
-  :group 'haskell-interactive)
-
-;;;###autoload
-(defface haskell-interactive-face-compile-warning
-  '((t :inherit compilation-warning))
-  "Face for compiler warnings."
-  :group 'haskell-interactive)
-
-;;;###autoload
-(defface haskell-interactive-face-result
-  '((t :inherit font-lock-string-face))
-  "Face for the result."
-  :group 'haskell-interactive)
-
-;;;###autoload
-(defface haskell-interactive-face-garbage
-  '((t :inherit font-lock-string-face))
-  "Face for trailing garbage after a command has completed."
-  :group 'haskell-interactive)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Actions
-
-(defun haskell-interactive-mode-newline-indent ()
-  "Make newline and indent."
-  (interactive)
-  (newline)
-  (indent-to (length haskell-interactive-prompt))
-  (indent-relative))
-
-(defun haskell-interactive-mode-kill-whole-line ()
-  "Kill the whole REPL line."
-  (interactive)
-  (kill-region haskell-interactive-mode-prompt-start
-               (line-end-position)))
-
-(defun haskell-interactive-switch-back ()
-  "Switch back to the buffer from which this interactive buffer was reached."
-  (interactive)
-  (if haskell-interactive-previous-buffer
-      (switch-to-buffer-other-window haskell-interactive-previous-buffer)
-    (message "No previous buffer.")))
-
-(defun haskell-interactive-copy-to-prompt ()
-  "Copy the current line to the prompt, overwriting the current prompt."
-  (interactive)
-  (let ((l (buffer-substring-no-properties (line-beginning-position)
-                                           (line-end-position))))
-    ;; If it looks like the prompt is at the start of the line, chop
-    ;; it off.
-    (when (and (>= (length l) (length haskell-interactive-prompt))
-               (string= (substring l 0 (length haskell-interactive-prompt))
-                        haskell-interactive-prompt))
-      (setq l (substring l (length haskell-interactive-prompt))))
-
-    (haskell-interactive-mode-set-prompt l)))
-
-(defun haskell-interactive-mode-space (n)
-  "Handle the space key."
-  (interactive "p")
-  (if (and (bound-and-true-p god-local-mode)
-           (fboundp 'god-mode-self-insert))
-      (call-interactively 'god-mode-self-insert)
-    (if (haskell-interactive-at-compile-message)
-        (next-error-no-select 0)
-      (self-insert-command n))))
-
-(defun haskell-interactive-at-prompt (&optional end-line)
-  "If at prompt, return start position of user-input, otherwise return nil.
-If END-LINE is non-nil, then return non-nil when the end of line
-is at the prompt."
-  (if (>= (if end-line (line-end-position) (point))
-          haskell-interactive-mode-prompt-start)
-      haskell-interactive-mode-prompt-start
-    nil))
-
-(define-derived-mode haskell-error-mode
-  special-mode "Error"
-  "Major mode for viewing Haskell compile errors.")
-
-;; (define-key haskell-error-mode-map (kbd "q") 'quit-window)
-
-(defun haskell-interactive-mode-handle-h ()
-  "Handle ^H in output."
-  (let ((bound (point-min))
-        (inhibit-read-only t))
-    (save-excursion
-      (while (search-backward "\b" bound t 1)
-        (save-excursion
-          (forward-char)
-          (let ((end (point)))
-            (if (search-backward-regexp "[^\b]" bound t 1)
-                (forward-char)
-              (goto-char (point-min)))
-            (let ((start (point)))
-              (delete-region (max (- (point) (- end start))
-                                  (point-min))
-                             end))))))))
-
-(defun haskell-interactive-mode-multi-line (expr)
-  "If a multi-line expression EXPR has been entered, then reformat it to be:
-
-:{
-do the
-   multi-liner
-   expr
-:}"
-  (if (not (string-match-p "\n" expr))
-      expr
-    (let ((pre (format "^%s" (regexp-quote haskell-interactive-prompt)))
-          (lines (split-string expr "\n")))
-      (cl-loop for elt on (cdr lines) do
-               (setcar elt (replace-regexp-in-string pre "" (car elt))))
-      ;; Temporarily set prompt2 to be empty to avoid unwanted output
-      (concat ":set prompt2 \"\"\n"
-              ":{\n"
-              (mapconcat #'identity lines "\n")
-              "\n:}\n"
-              (format ":set prompt2 \"%s\"" haskell-interactive-prompt2)))))
-
-(defun haskell-interactive-mode-line-is-query (line)
-  "Is LINE actually a :t/:k/:i?"
-  (and (string-match "^:[itk] " line)
-       t))
-
-(defun haskell-interactive-mode-beginning ()
-  "Go to the start of the line."
-  (interactive)
-  (if (haskell-interactive-at-prompt)
-      (goto-char haskell-interactive-mode-prompt-start)
-    (move-beginning-of-line nil)))
-
-(defun haskell-interactive-mode-input-partial ()
-  "Get the interactive mode input up to point."
-  (let ((input-start (haskell-interactive-at-prompt)))
-    (unless input-start
-      (error "not at prompt"))
-    (buffer-substring-no-properties input-start (point))))
-
-(defun haskell-interactive-mode-input ()
-  "Get the interactive mode input."
-  (buffer-substring-no-properties
-   haskell-interactive-mode-prompt-start
-   (point-max)))
-
-(defun haskell-interactive-mode-prompt (&optional session)
-  "Show a prompt at the end of the REPL buffer.
-If SESSION is non-nil, use the REPL buffer associated with
-SESSION, otherwise operate on the current buffer."
-  (with-current-buffer (if session
-                           (haskell-session-interactive-buffer session)
-                         (current-buffer))
-    (save-excursion
-      (goto-char (point-max))
-      (let ((prompt (propertize haskell-interactive-prompt
-                                'font-lock-face 'haskell-interactive-face-prompt
-                                'prompt t
-                                'read-only haskell-interactive-prompt-read-only
-                                'rear-nonsticky t)))
-        ;; At the time of writing, front-stickying the first char gives an error
-        ;; Has unfortunate side-effect of being able to insert before the prompt
-        (insert (substring prompt 0 1)
-                (propertize (substring prompt 1)
-                            'front-sticky t)))
-      (let ((marker (setq-local haskell-interactive-mode-prompt-start (make-marker))))
-        (set-marker marker (point))))
-    (when (haskell-interactive-at-prompt t)
-      (haskell-interactive-mode-scroll-to-bottom))))
-
-(defun haskell-interactive-mode-eval-result (session text)
-  "Insert the result of an eval as plain text."
-  (with-current-buffer (haskell-session-interactive-buffer session)
-    (let ((at-end (eobp))
-          (prop-text (propertize text
-                                 'font-lock-face 'haskell-interactive-face-result
-                                 'front-sticky t
-                                 'prompt t
-                                 'read-only haskell-interactive-mode-read-only
-                                 'rear-nonsticky t
-                                 'result t)))
-      (save-excursion
-        (goto-char (point-max))
-        (when (string= text haskell-interactive-prompt2)
-          (setq prop-text
-                (propertize prop-text
-                            'font-lock-face 'haskell-interactive-face-prompt2
-                            'read-only haskell-interactive-prompt-read-only)))
-        (insert (ansi-color-apply prop-text))
-        (haskell-interactive-mode-handle-h)
-        (let ((marker (setq-local haskell-interactive-mode-result-end (make-marker))))
-          (set-marker marker (point))))
-      (when at-end
-        (haskell-interactive-mode-scroll-to-bottom)))))
-
-(defun haskell-interactive-mode-scroll-to-bottom ()
-  "Scroll to bottom."
-  (let ((w (get-buffer-window (current-buffer))))
-    (when w
-      (goto-char (point-max))
-      (set-window-point w (point)))))
-
-(defun haskell-interactive-mode-compile-error (session message)
-  "Echo an error."
-  (haskell-interactive-mode-compile-message
-   session message 'haskell-interactive-face-compile-error))
-
-(defun haskell-interactive-mode-compile-warning (session message)
-  "Warning message."
-  (haskell-interactive-mode-compile-message
-   session message 'haskell-interactive-face-compile-warning))
-
-(defun haskell-interactive-mode-compile-message (session message type)
-  "Echo a compiler warning."
-  (with-current-buffer (haskell-session-interactive-buffer session)
-    (setq next-error-last-buffer (current-buffer))
-    (save-excursion
-      (haskell-interactive-mode-goto-end-point)
-      (let ((lines (string-match "^\\(.*\\)\n\\([[:unibyte:][:nonascii:]]+\\)" message)))
-        (if lines
-            (progn
-              (insert (propertize (concat (match-string 1 message) " …\n")
-                                  'expandable t
-                                  'font-lock-face type
-                                  'front-sticky t
-                                  'read-only haskell-interactive-mode-read-only
-                                  'rear-nonsticky t))
-              (insert (propertize (concat (match-string 2 message) "\n")
-                                  'collapsible t
-                                  'font-lock-face type
-                                  'front-sticky t
-                                  'invisible haskell-interactive-mode-hide-multi-line-errors
-                                  'message-length (length (match-string 2 message))
-                                  'read-only haskell-interactive-mode-read-only
-                                  'rear-nonsticky t)))
-          (insert (propertize (concat message "\n")
-                              'font-lock-face type
-                              'front-sticky t
-                              'read-only haskell-interactive-mode-read-only
-                              'rear-nonsticky t)))))))
-
-(defun haskell-interactive-mode-insert (session message)
-  "Echo a read only piece of text before the prompt."
-  (with-current-buffer (haskell-session-interactive-buffer session)
-    (save-excursion
-      (haskell-interactive-mode-goto-end-point)
-      (insert (propertize message
-                          'front-sticky t
-                          'read-only t
-                          'rear-nonsticky t)))))
-
-(defun haskell-interactive-mode-goto-end-point ()
-  "Go to the 'end' of the buffer (before the prompt)."
-  (goto-char haskell-interactive-mode-prompt-start)
-  (goto-char (line-beginning-position)))
-
-(defun haskell-interactive-mode-history-add (input)
-  "Add INPUT to the history."
-  (setq haskell-interactive-mode-history
-        (cons ""
-              (cons input
-                    (cl-remove-if (lambda (i) (or (string= i input) (string= i "")))
-                                  haskell-interactive-mode-history))))
-  (setq haskell-interactive-mode-history-index
-        0))
-
-(defun haskell-interactive-mode-tab ()
-  "Do completion if at prompt or else try collapse/expand."
-  (interactive)
-  (cond
-   ((haskell-interactive-at-prompt)
-    (completion-at-point))
-   ((get-text-property (point) 'collapsible)
-    (let ((column (current-column)))
-      (search-backward-regexp "^[^ ]")
-      (haskell-interactive-mode-tab-expand)
-      (goto-char (+ column (line-beginning-position)))))
-   (t (haskell-interactive-mode-tab-expand))))
-
-(defun haskell-interactive-mode-tab-expand ()
-  "Expand the rest of the message."
-  (cond ((get-text-property (point) 'expandable)
-         (let* ((pos (1+ (line-end-position)))
-                (visibility (get-text-property pos 'invisible))
-                (length (1+ (get-text-property pos 'message-length))))
-           (let ((inhibit-read-only t))
-             (put-text-property pos
-                                (+ pos length)
-                                'invisible
-                                (not visibility)))))))
-
-(defconst haskell-interactive-mode-error-regexp
-  "^\\(\\(?:[A-Z]:\\)?[^ \r\n:][^\r\n:]*\\):\\([0-9()-:]+\\):?")
-
-(defun haskell-interactive-at-compile-message ()
-  "Am I on a compile message?"
-  (and (not (haskell-interactive-at-prompt))
-       (save-excursion
-         (goto-char (line-beginning-position))
-         (looking-at haskell-interactive-mode-error-regexp))))
-
-(defun haskell-interactive-mode-error-backward (&optional count)
-  "Go backward to the previous error."
-  (interactive)
-  (search-backward-regexp haskell-interactive-mode-error-regexp nil t count))
-
-(defun haskell-interactive-mode-error-forward (&optional count)
-  "Go forward to the next error, or return to the REPL."
-  (interactive)
-  (goto-char (line-end-position))
-  (if (search-forward-regexp haskell-interactive-mode-error-regexp nil t count)
-      (progn (goto-char (line-beginning-position))
-             t)
-    (progn (goto-char (point-max))
-           nil)))
-
-(defun haskell-interactive-mode-delete-compile-messages (session &optional file-name)
-  "Delete compile messages in REPL buffer.
-If FILE-NAME is non-nil, restrict to removing messages concerning
-FILE-NAME only."
-  (with-current-buffer (haskell-session-interactive-buffer session)
-    (save-excursion
-      (goto-char (point-min))
-      (when (search-forward-regexp "^Compilation failed.$" nil t 1)
-        (let ((inhibit-read-only t))
-          (delete-region (line-beginning-position)
-                         (1+ (line-end-position))))
-        (goto-char (point-min)))
-      (while (when (re-search-forward haskell-interactive-mode-error-regexp nil t)
-               (let ((msg-file-name (match-string-no-properties 1))
-                     (msg-startpos (line-beginning-position)))
-                 ;; skip over hanging continuation message lines
-                 (while (progn (forward-line) (looking-at "^[ ]+")))
-
-                 (when (or (not file-name) (string= file-name msg-file-name))
-                   (let ((inhibit-read-only t))
-                     (set-text-properties msg-startpos (point) nil))
-                   (delete-region msg-startpos (point))
-                   ))
-               t)))))
-
-;;;###autoload
-(defun haskell-interactive-mode-reset-error (session)
-  "Reset the error cursor position."
-  (interactive)
-  (with-current-buffer (haskell-session-interactive-buffer session)
-    (haskell-interactive-mode-goto-end-point)
-    (let ((mrk (point-marker)))
-      (haskell-session-set session 'next-error-locus nil)
-      (haskell-session-set session 'next-error-region (cons mrk (copy-marker mrk t))))
-    (goto-char (point-max))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Misc
-
-(declare-function haskell-interactive-switch "haskell")
-(declare-function haskell-session "haskell")
-
-(defun haskell-session-interactive-buffer (s)
-  "Get the session interactive buffer."
-  (let ((buffer (haskell-session-get s 'interactive-buffer)))
-    (if (and buffer (buffer-live-p buffer))
-        buffer
-      (let ((buffer-name (format "*%s*" (haskell-session-name s)))
-            (index 0))
-        (while (get-buffer buffer-name)
-          (setq buffer-name (format "*%s <%d>*" (haskell-session-name s) index))
-          (setq index (1+ index)))
-        (let ((buffer (get-buffer-create buffer-name)))
-          (haskell-session-set-interactive-buffer s buffer)
-          (with-current-buffer buffer
-            (haskell-interactive-mode)
-            (haskell-session-assign s))
-          (haskell-interactive-switch)
-          buffer)))))
-
-(defun haskell-interactive-buffer ()
-  "Get the interactive buffer of the session."
-  (haskell-session-interactive-buffer (haskell-session)))
-
-(defun haskell-process-cabal-live (state buffer)
-  "Do live updates for Cabal processes."
-  (haskell-interactive-mode-insert
-   (haskell-process-session (cadr state))
-   (replace-regexp-in-string
-    haskell-process-prompt-regex
-    ""
-    (substring buffer (cl-cadddr state))))
-  (setf (cl-cdddr state) (list (length buffer)))
-  nil)
-
-(defun haskell-process-parse-error (string)
-  "Parse the line number from the error string STRING."
-  (let ((span nil))
-    (cl-loop for regex
-             in haskell-compilation-error-regexp-alist
-             do (when (string-match (car regex) string)
-                  (setq span
-                        (list :file (match-string 1 string)
-                              :line (string-to-number (match-string 2 string))
-                              :col (string-to-number (match-string 4 string))
-                              :line2 (when (match-string 3 string)
-                                       (string-to-number (match-string 3 string)))
-                              :col2 (when (match-string 5 string)
-                                      (string-to-number (match-string 5 string)))))))
-    span))
-
-(defun haskell-process-suggest-add-package (session msg)
-  "Add the (matched) module to your cabal file.
-Cabal file is selected using SESSION's name, module matching is done in MSG."
-  (let* ((suggested-package (match-string 1 msg))
-         (package-name (replace-regexp-in-string "-[^-]+$" "" suggested-package))
-         (version (progn (string-match "\\([^-]+\\)$" suggested-package)
-                         (match-string 1 suggested-package)))
-         (cabal-file (concat (haskell-session-name session)
-                             ".cabal")))
-    (haskell-mode-toggle-interactive-prompt-state)
-    (unwind-protect
-        (when (y-or-n-p
-               (format "Add `%s' to %s?"
-                       package-name
-                       cabal-file))
-          (haskell-cabal-add-dependency package-name version nil t)
-          (when (y-or-n-p (format "Enable -package %s in the GHCi session?" package-name))
-            (haskell-process-queue-without-filters
-             (haskell-session-process session)
-             (format ":set -package %s" package-name))))
-      (haskell-mode-toggle-interactive-prompt-state t))))
-
-(defun haskell-process-suggest-remove-import (session file import line)
-  "Suggest removing or commenting out import statement.
-Asks user to handle redundant import statement using interactive
-SESSION in specified FILE to remove IMPORT on given LINE."
-  (let ((first t))
-    (haskell-mode-toggle-interactive-prompt-state)
-    (unwind-protect
-        (cl-case (read-event
-                  (propertize (format "%sThe import line `%s' is redundant. Remove? (y, n, c: comment out)  "
-                                      (if (not first)
-                                          "Please answer n, y or c: "
-                                        "")
-                                      import)
-                              'face
-                              'minibuffer-prompt))
-          (?y
-           (haskell-process-find-file session file)
-           (save-excursion
-             (goto-char (point-min))
-             (forward-line (1- line))
-             (goto-char (line-beginning-position))
-             (delete-region (line-beginning-position)
-                            (line-end-position))))
-          (?n
-           (message "Ignoring redundant import %s" import))
-          (?c
-           (haskell-process-find-file session file)
-           (save-excursion
-             (goto-char (point-min))
-             (forward-line (1- line))
-             (goto-char (line-beginning-position))
-             (insert "-- "))))
-      ;; unwind
-      (haskell-mode-toggle-interactive-prompt-state t))))
-
-(defun haskell-process-find-file (session file)
-  "Find the given file in the project."
-  (find-file (cond ((file-exists-p (concat (haskell-session-current-dir session) "/" file))
-                    (concat (haskell-session-current-dir session) "/" file))
-                   ((file-exists-p (concat (haskell-session-cabal-dir session) "/" file))
-                    (concat (haskell-session-cabal-dir session) "/" file))
-                   (t file))))
-
-(defun haskell-process-suggest-pragma (session pragma extension file)
-  "Suggest to add something to the top of the file.
-SESSION is used to search given file.  Adds PRAGMA and EXTENSION
-wrapped in compiler directive at the top of FILE."
-  (let ((string  (format "{-# %s %s #-}" pragma extension)))
-    (haskell-mode-toggle-interactive-prompt-state)
-    (unwind-protect
-        (when (y-or-n-p (format "Add %s to the top of the file? " string))
-          (haskell-process-find-file session file)
-          (save-excursion
-            (goto-char (point-min))
-            (insert (concat string "\n"))))
-      (haskell-mode-toggle-interactive-prompt-state t))))
-
-(defun haskell-interactive-mode-insert-error (response)
-  "Insert an error message."
-  (insert "\n"
-          (haskell-fontify-as-mode
-           response
-           'haskell-mode))
-  (haskell-interactive-mode-prompt))
-
-(defun haskell-interactive-popup-error (response)
-  "Popup an error."
-  (if haskell-interactive-popup-errors
-      (let ((buf (get-buffer-create "*HS-Error*")))
-        (pop-to-buffer buf nil t)
-        (with-current-buffer buf
-
-          (haskell-error-mode)
-          (let ((inhibit-read-only t))
-            (erase-buffer)
-            (insert (propertize response
-                                'font-lock-face
-                                'haskell-interactive-face-compile-error))
-            (goto-char (point-min))
-            (delete-blank-lines)
-            (insert (propertize "-- Hit `q' to close this window.\n\n"
-                                'font-lock-face 'font-lock-comment-face))
-            (save-excursion
-              (goto-char (point-max))
-              (insert (propertize "\n-- To disable popups, customize `haskell-interactive-popup-errors'.\n\n"
-                                  'font-lock-face 'font-lock-comment-face))))))
-    (haskell-interactive-mode-insert-error response)))
-
-(defun haskell-interactive-next-error-function (&optional n reset)
-  "See `next-error-function' for more information."
-
-  (let* ((session (haskell-interactive-session))
-         (next-error-region (haskell-session-get session 'next-error-region))
-         (next-error-locus (haskell-session-get session 'next-error-locus))
-         (reset-locus nil))
-
-    (when (and next-error-region (or reset (and (/= n 0) (not next-error-locus))))
-      (goto-char (car next-error-region))
-      (unless (looking-at haskell-interactive-mode-error-regexp)
-        (haskell-interactive-mode-error-forward))
-
-      (setq reset-locus t)
-      (unless (looking-at haskell-interactive-mode-error-regexp)
-        (error "no errors found")))
-
-    ;; move point if needed
-    (cond
-     (reset-locus nil)
-     ((> n 0) (unless (haskell-interactive-mode-error-forward n)
-                (error "no more errors")))
-
-     ((< n 0) (unless (haskell-interactive-mode-error-backward (- n))
-                (error "no more errors"))))
-
-    (let ((orig-line (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
-
-      (when (string-match haskell-interactive-mode-error-regexp orig-line)
-        (let* ((msgmrk (set-marker (make-marker) (line-beginning-position)))
-               (location (haskell-process-parse-error orig-line))
-               (file (plist-get location :file))
-               (line (plist-get location :line))
-               (col1 (plist-get location :col))
-               (col2 (plist-get location :col2))
-
-               (cabal-relative-file (expand-file-name file (haskell-session-cabal-dir session)))
-               (src-relative-file (expand-file-name file (haskell-session-current-dir session)))
-
-               (real-file (cond ((file-exists-p cabal-relative-file) cabal-relative-file)
-                                ((file-exists-p src-relative-file) src-relative-file))))
-
-          (haskell-session-set session 'next-error-locus msgmrk)
-
-          (if real-file
-              (let ((m1 (make-marker))
-                    (m2 (make-marker)))
-                (with-current-buffer (find-file-noselect real-file)
-                  (save-excursion
-                    (goto-char (point-min))
-                    (forward-line (1- line))
-                    (set-marker m1 (+ col1 (point) -1))
-
-                    (when col2
-                      (set-marker m2 (- (point) col2)))))
-                ;; ...finally select&hilight error locus
-                (compilation-goto-locus msgmrk m1 (and (marker-position m2) m2)))
-            (error "don't know where to find %S" file)))))))
-
-(defun haskell-interactive-session ()
-  "Get the `haskell-session', throw an error if it's not available."
-  (or (haskell-session-maybe)
-      (haskell-session-assign
-       (or (haskell-session-from-buffer)
-           (haskell-session-choose)
-           (error "No session associated with this buffer. Try M-x haskell-session-change or report this as a bug.")))))
-
-(defun haskell-interactive-process ()
-  "Get the Haskell session."
-  (or (haskell-session-process (haskell-interactive-session))
-      (error "No Haskell session/process associated with this
-      buffer. Maybe run M-x haskell-process-restart?")))
-
-(defun haskell-interactive-mode-do-presentation (expr)
-  "Present the given expression EXPR.
-Requires the `present' package to be installed.
-Will automatically import it qualified as Present."
-  (let ((p (haskell-interactive-process)))
-    ;; If Present.code isn't available, we probably need to run the
-    ;; setup.
-    (unless (string-match "^Present" (haskell-process-queue-sync-request p ":t Present.encode"))
-      (haskell-interactive-mode-setup-presentation p))
-    ;; Happily, let statements don't affect the `it' binding in any
-    ;; way, so we can fake it, no pun intended.
-    (let ((error (haskell-process-queue-sync-request
-                  p (concat "let it = Present.asData (" expr ")"))))
-      (if (not (string= "" error))
-          (haskell-interactive-mode-eval-result (haskell-interactive-session) (concat error "\n"))
-        (let ((hash (haskell-interactive-mode-presentation-hash)))
-          (haskell-process-queue-sync-request
-           p (format "let %s = Present.asData (%s)" hash expr))
-          (let* ((presentation (haskell-interactive-mode-present-id
-                                hash
-                                (list 0))))
-            (insert "\n")
-            (haskell-interactive-mode-insert-presentation hash presentation)
-            (haskell-interactive-mode-eval-result (haskell-interactive-session) "\n"))))
-      (haskell-interactive-mode-prompt (haskell-interactive-session)))))
-
-(defun haskell-interactive-mode-present-id (hash id)
-  "Generate a presentation for the current expression at ID."
-  ;; See below for commentary of this statement.
-  (let ((p (haskell-interactive-process)))
-    (haskell-process-queue-without-filters
-     p "let _it = it")
-    (let* ((text (haskell-process-queue-sync-request
-                  p
-                  (format "Present.putStr (Present.encode (Present.fromJust (Present.present (Present.fromJust (Present.fromList [%s])) %s)))"
-                          (mapconcat 'identity (mapcar 'number-to-string id) ",")
-                          hash)))
-           (reply
-            (if (string-match "^*** " text)
-                '((rep nil))
-              (read text))))
-      ;; Not necessary, but nice to restore it to the expression that
-      ;; the user actually typed in.
-      (haskell-process-queue-without-filters
-       p "let it = _it")
-      reply)))
-
-(defun haskell-presentation-present-slot (btn)
-  "The callback to evaluate the slot and present it in place of the button BTN."
-  (let ((id (button-get btn 'presentation-id))
-        (hash (button-get btn 'hash))
-        (parent-rep (button-get btn 'parent-rep))
-        (continuation (button-get btn 'continuation)))
-    (let ((point (point)))
-      (button-put btn 'invisible t)
-      (delete-region (button-start btn) (button-end btn))
-      (haskell-interactive-mode-insert-presentation
-       hash
-       (haskell-interactive-mode-present-id hash id)
-       parent-rep
-       continuation)
-      (when (> (point) point)
-        (goto-char (1+ point))))))
-
-(defun haskell-interactive-mode-presentation-slot (hash slot parent-rep &optional continuation)
-  "Make a slot at point, pointing to ID."
-  (let ((type (car slot))
-        (id (cadr slot)))
-    (if (member (intern type) '(Integer Char Int Float Double))
-        (haskell-interactive-mode-insert-presentation
-         hash
-         (haskell-interactive-mode-present-id hash id)
-         parent-rep
-         continuation)
-      (haskell-interactive-mode-presentation-slot-button slot parent-rep continuation hash))))
-
-(defun haskell-interactive-mode-presentation-slot-button (slot parent-rep continuation hash)
-  (let ((start (point))
-        (type (car slot))
-        (id (cadr slot)))
-    (insert (propertize type 'font-lock-face '(:height 0.8 :underline t :inherit font-lock-comment-face)))
-    (let ((button (make-text-button start (point)
-                                    :type 'haskell-presentation-slot-button)))
-      (button-put button 'hide-on-click t)
-      (button-put button 'presentation-id id)
-      (button-put button 'parent-rep parent-rep)
-      (button-put button 'continuation continuation)
-      (button-put button 'hash hash))))
-
-(defun haskell-interactive-mode-insert-presentation (hash presentation &optional parent-rep continuation)
-  "Insert the presentation, hooking up buttons for each slot."
-  (let* ((rep (cadr (assoc 'rep presentation)))
-         (text (cadr (assoc 'text presentation)))
-         (slots (cadr (assoc 'slots presentation)))
-         (nullary (null slots)))
-    (cond
-     ((string= "integer" rep)
-      (insert (propertize text 'font-lock-face 'font-lock-constant)))
-     ((string= "floating" rep)
-      (insert (propertize text 'font-lock-face 'font-lock-constant)))
-     ((string= "char" rep)
-      (insert (propertize
-               (if (string= "string" parent-rep)
-                   (replace-regexp-in-string "^'\\(.+\\)'$" "\\1" text)
-                 text)
-               'font-lock-face 'font-lock-string-face)))
-     ((string= "tuple" rep)
-      (insert "(")
-      (let ((first t))
-        (cl-loop for slot in slots
-                 do (unless first (insert ","))
-                 do (haskell-interactive-mode-presentation-slot hash slot rep)
-                 do (setq first nil)))
-      (insert ")"))
-     ((string= "list" rep)
-      (if (null slots)
-          (if continuation
-              (progn (delete-char -1)
-                     (delete-indentation))
-            (insert "[]"))
-        (let ((i 0))
-          (unless continuation
-            (insert "["))
-          (let ((start-column (current-column)))
-            (cl-loop for slot in slots
-                     do (haskell-interactive-mode-presentation-slot
-                         hash
-                         slot
-                         rep
-                         (= i (1- (length slots))))
-                     do (when (not (= i (1- (length slots))))
-                          (insert "\n")
-                          (indent-to (1- start-column))
-                          (insert ","))
-                     do (setq i (1+ i))))
-          (unless continuation
-            (insert "]")))))
-     ((string= "string" rep)
-      (unless (string= "string" parent-rep)
-        (insert (propertize "\"" 'font-lock-face 'font-lock-string-face)))
-      (cl-loop for slot in slots
-               do (haskell-interactive-mode-presentation-slot hash slot rep))
-      (unless (string= "string" parent-rep)
-        (insert (propertize "\"" 'font-lock-face 'font-lock-string-face))))
-     ((string= "alg" rep)
-      (when (and parent-rep
-                 (not nullary)
-                 (not (string= "list" parent-rep)))
-        (insert "("))
-      (let ((start-column (current-column)))
-        (insert (propertize text 'font-lock-face 'font-lock-type-face))
-        (cl-loop for slot in slots
-                 do (insert "\n")
-                 do (indent-to (+ 2 start-column))
-                 do (haskell-interactive-mode-presentation-slot hash slot rep)))
-      (when (and parent-rep
-                 (not nullary)
-                 (not (string= "list" parent-rep)))
-        (insert ")")))
-     ((string= "record" rep)
-      (let ((start-column (current-column)))
-        (insert (propertize text 'font-lock-face 'font-lock-type-face)
-                " { ")
-        (cl-loop for field in slots
-                 do (insert "\n")
-                 do (indent-to (+ 2 start-column))
-                 do (let ((name (nth 0 field))
-                          (slot (nth 1 field)))
-                      (insert name " = ")
-                      (haskell-interactive-mode-presentation-slot hash slot rep)))
-        (insert "\n")
-        (indent-to start-column)
-        (insert "}")))
-     ((eq rep nil)
-      (insert (propertize "?" 'font-lock-face 'font-lock-warning)))
-     (t
-      (let ((err "Unable to present! This very likely means Emacs
-is out of sync with the `present' package. You should make sure
-they're both up to date, or report a bug."))
-        (insert err)
-        (error err))))))
-
-(defun haskell-interactive-mode-setup-presentation (p)
-  "Setup the GHCi REPL for using presentations.
-
-Using asynchronous queued commands as opposed to sync at this
-stage, as sync would freeze up the UI a bit, and we actually
-don't care when the thing completes as long as it's soonish."
-  ;; Import dependencies under Present.* namespace
-  (haskell-process-queue-without-filters p "import qualified Data.Maybe as Present")
-  (haskell-process-queue-without-filters p "import qualified Data.ByteString.Lazy as Present")
-  (haskell-process-queue-without-filters p "import qualified Data.AttoLisp as Present")
-  (haskell-process-queue-without-filters p "import qualified Present.ID as Present")
-  (haskell-process-queue-without-filters p "import qualified Present as Present")
-  ;; Make a dummy expression to avoid "Loading package" nonsense
-  (haskell-process-queue-without-filters
-   p "Present.present (Present.fromJust (Present.fromList [0])) ()"))
-
-(defvar haskell-interactive-mode-presentation-hash 0
-  "Counter for the hash.")
-
-(defun haskell-interactive-mode-presentation-hash ()
-  "Generate a presentation hash."
-  (format "_present_%s"
-          (setq haskell-interactive-mode-presentation-hash
-                (1+ haskell-interactive-mode-presentation-hash))))
-
-(define-button-type 'haskell-presentation-slot-button
-  'action 'haskell-presentation-present-slot
-  'follow-link t
-  'help-echo "Click to expand…")
-
-(defun haskell-interactive-mode-history-toggle (n)
-  "Toggle the history N items up or down."
-  (unless (null haskell-interactive-mode-history)
-    (setq haskell-interactive-mode-history-index
-          (mod (+ haskell-interactive-mode-history-index n)
-               (length haskell-interactive-mode-history)))
-    (unless (zerop haskell-interactive-mode-history-index)
-      (message "History item: %d" haskell-interactive-mode-history-index))
-    (haskell-interactive-mode-set-prompt
-     (nth haskell-interactive-mode-history-index
-          haskell-interactive-mode-history))))
-
-(defun haskell-interactive-mode-set-prompt (p)
-  "Set (and overwrite) the current prompt."
-  (with-current-buffer (haskell-session-interactive-buffer (haskell-interactive-session))
-    (goto-char haskell-interactive-mode-prompt-start)
-    (delete-region (point) (point-max))
-    (insert p)))
-
-(defun haskell-interactive-mode-history-previous (arg)
-  "Cycle backwards through input history."
-  (interactive "*p")
-  (when (haskell-interactive-at-prompt)
-    (if (not (zerop arg))
-        (haskell-interactive-mode-history-toggle arg)
-      (setq haskell-interactive-mode-history-index 0)
-      (haskell-interactive-mode-history-toggle 1))))
-
-(defun haskell-interactive-mode-history-next (arg)
-  "Cycle forward through input history."
-  (interactive "*p")
-  (when (haskell-interactive-at-prompt)
-    (if (not (zerop arg))
-        (haskell-interactive-mode-history-toggle (- arg))
-      (setq haskell-interactive-mode-history-index 0)
-      (haskell-interactive-mode-history-toggle -1))))
-
-(defun haskell-interactive-mode-prompt-previous ()
-  "Jump to the previous prompt."
-  (interactive)
-  (let ((prev-prompt-pos
-         (save-excursion
-           (beginning-of-line) ;; otherwise prompt at current line matches
-           (and (search-backward-regexp (haskell-interactive-prompt-regex) nil t)
-                (match-end 0)))))
-    (when prev-prompt-pos (goto-char prev-prompt-pos))))
-
-(defun haskell-interactive-mode-prompt-next ()
-  "Jump to the next prompt."
-  (interactive)
-  (search-forward-regexp (haskell-interactive-prompt-regex) nil t))
-
-(defun haskell-interactive-mode-clear ()
-  "Clear the screen and put any current input into the history."
-  (interactive)
-  (let ((session (haskell-interactive-session)))
-    (with-current-buffer (haskell-session-interactive-buffer session)
-      (let ((inhibit-read-only t))
-        (set-text-properties (point-min) (point-max) nil))
-      (delete-region (point-min) (point-max))
-      (remove-overlays)
-      (haskell-interactive-mode-prompt session)
-      (haskell-session-set session 'next-error-region nil)
-      (haskell-session-set session 'next-error-locus nil))
-    (with-current-buffer (get-buffer-create "*haskell-process-log*")
-      (let ((inhibit-read-only t))
-        (delete-region (point-min) (point-max)))
-      (remove-overlays))))
-
-(defun haskell-interactive-mode-completion-at-point-function ()
-  "Offer completions for partial expression between prompt and point.
-This completion function is used in interactive REPL buffer itself."
-  (when (haskell-interactive-at-prompt)
-    (let* ((process (haskell-interactive-process))
-           (inp (haskell-interactive-mode-input-partial))
-           (resp2 (haskell-process-get-repl-completions process inp))
-           (rlen (-  (length inp) (length (car resp2))))
-           (coll (append (if (string-prefix-p inp "import") '("import"))
-                         (if (string-prefix-p inp "let") '("let"))
-                         (cdr resp2))))
-      (list (- (point) rlen) (point) coll))))
-
-(defun haskell-interactive-mode-trigger-compile-error (state response)
-  "Look for an <interactive> compile error.
-If there is one, pop that up in a buffer, similar to `debug-on-error'."
-  (when (and haskell-interactive-types-for-show-ambiguous
-             (string-match "^\n<interactive>:[-0-9]+:[-0-9]+:" response)
-             (not (string-match "^\n<interactive>:[-0-9]+:[-0-9]+:[\n ]+[Ww]arning:" response)))
-    (let ((inhibit-read-only t))
-      (delete-region haskell-interactive-mode-prompt-start (point))
-      (set-marker haskell-interactive-mode-prompt-start
-                  haskell-interactive-mode-old-prompt-start)
-      (goto-char (point-max)))
-    (cond
-     ((and (not (haskell-interactive-mode-line-is-query (elt state 2)))
-           (or (string-match "No instance for (?Show[ \n]" response)
-               (string-match "Ambiguous type variable " response)))
-      (haskell-process-reset (haskell-interactive-process))
-      (let ((resp (haskell-process-queue-sync-request
-                   (haskell-interactive-process)
-                   (concat ":t "
-                           (buffer-substring-no-properties
-                            haskell-interactive-mode-prompt-start
-                            (point-max))))))
-        (cond
-         ((not (string-match "<interactive>:" resp))
-          (haskell-interactive-mode-insert-error resp))
-         (t (haskell-interactive-popup-error response)))))
-     (t (haskell-interactive-popup-error response)
-        t))
-    t))
-
-;;;###autoload
-(defun haskell-interactive-mode-echo (session message &optional mode)
-  "Echo a read only piece of text before the prompt."
-  (with-current-buffer (haskell-session-interactive-buffer session)
-    (save-excursion
-      (haskell-interactive-mode-goto-end-point)
-      (insert (if mode
-                  (haskell-fontify-as-mode
-                   (concat message "\n")
-                   mode)
-                (propertize (concat message "\n")
-                            'front-sticky t
-                            'read-only t
-                            'rear-nonsticky t))))))
-
-(defun haskell-interactive-mode-splices-buffer (session)
-  "Get the splices buffer for the current SESSION."
-  (get-buffer-create (haskell-interactive-mode-splices-buffer-name session)))
-
-(defun haskell-interactive-mode-splices-buffer-name (session)
-  (format "*%s:splices*" (haskell-session-name session)))
-
-(defun haskell-interactive-mode-compile-splice (session message)
-  "Echo a compiler splice."
-  (with-current-buffer (haskell-interactive-mode-splices-buffer session)
-    (unless (eq major-mode 'haskell-mode)
-      (haskell-mode))
-    (let* ((parts (split-string message "\n  ======>\n"))
-           (file-and-decl-lines (split-string (nth 0 parts) "\n"))
-           (file (nth 0 file-and-decl-lines))
-           (decl (mapconcat #'identity (cdr file-and-decl-lines) "\n"))
-           (output (nth 1 parts)))
-      (insert "-- " file "\n")
-      (let ((start (point)))
-        (insert decl "\n")
-        (indent-rigidly start (point) -4))
-      (insert "-- =>\n")
-      (let ((start (point)))
-        (insert output "\n")
-        (indent-rigidly start (point) -4)))))
-
-(defun haskell-interactive-mode-insert-garbage (session message)
-  "Echo a read only piece of text before the prompt."
-  (with-current-buffer (haskell-session-interactive-buffer session)
-    (save-excursion
-      (haskell-interactive-mode-goto-end-point)
-      (insert (propertize message
-                          'front-sticky t
-                          'font-lock-face 'haskell-interactive-face-garbage
-                          'read-only t
-                          'rear-nonsticky t)))))
-
-;;;###autoload
-(defun haskell-process-show-repl-response (line)
-  "Send LINE to the GHCi process and echo the result in some fashion.
-Result will be printed in the minibuffer or presented using
-function `haskell-presentation-present', depending on variable
-`haskell-process-use-presentation-mode'."
-  (let ((process (haskell-interactive-process)))
-    (haskell-process-queue-command
-     process
-     (make-haskell-command
-      :state (cons process line)
-      :go (lambda (state)
-            (haskell-process-send-string (car state) (cdr state)))
-      :complete (lambda (state response)
-                  (if haskell-process-use-presentation-mode
-                      (haskell-presentation-present
-                       (haskell-process-session (car state))
-                       response)
-                    (haskell-mode-message-line response)))))))
-
-(provide 'haskell-interactive-mode)
-
-;;; haskell-interactive-mode.el ends here