;; -*- lexical-binding: t; -*-
(require 'syd/base)
(require 'syd/handle)

(defun syd-haskell-open-repl ()
  "Open a Haskell REPL."
  (interactive)
  (require 'inf-haskell)
  (run-haskell))

(defun syd-haskell-evil-open-above ()
  "Opens a line above the current, following Haskell-mode's indentation"
  (interactive)
  (evil-beginning-of-line)
  (haskell-indentation-newline-and-indent)
  (evil-previous-line)
  (haskell-indentation-indent-line)
  (evil-append-line nil))

(defun syd-haskell-evil-open-below ()
  "Opens a line below the current, following Haskell-mode's indentation"
  (interactive)
  (evil-append-line nil)
  (haskell-indentation-newline-and-indent))

(defun syd-haskell-hoogle-start-server ()
  (interactive)
  (require 'haskell-hoogle)
  (haskell-hoogle-start-server)
  (browse-url-xdg-open (format "http://localhost:%d"
                               haskell-hoogle-port-number))
  (message "Hoogle started on localhost:%d" haskell-hoogle-port-number))

(use-package haskell-mode
  :mode (("\\.l?hs'" . haskell-literate-mode)
         ("\\.hs'" . haskell-mode))
  :custom (; Show errors in REPL, not popup buffers.
           (haskell-interactive-popup-errors nil)
           (haskell-process-suggest-remove-import-line t)
           (haskell-process-auto-import-loaded-modules t))
  :general
  (:keymaps 'haskell-mode-map
   :states '(normal visual motion emacs insert)
   :major-modes t
   :prefix syd-localleader-key
   :non-normal-prefix syd-alt-localleader-key
   "c" #'haskell-cabal-visit-file
   "h s" #'syd-haskell-hoogle-start-server
   "h q" #'haskell-hoogle-kill-server)
  (:keymaps 'interactive-haskell-mode-map
   :states '(normal insert)
   "C-j" #'haskell-interactive-mode-history-next
   "C-k" #'haskell-interactive-mode-history-previous)
  (:keymaps 'haskell-mode-map
   :states 'normal
   [remap evil-open-above] #'syd-haskell-evil-open-above
   [remap evil-open-below] #'syd-haskell-evil-open-below)
  :config
  (add-to-list 'completion-ignored-extensions ".hi"))

(use-package lsp-haskell
  :defer t
  :custom ((lsp-haskell-server-path "haskell-language-server"))
  :init
  (add-hook 'haskell-mode-hook #'lsp-deferred 'append)
  (add-hook 'haskell-literate-mode-hook #'lsp-deferred 'append))

(provide 'syd/haskell)
