;;; -*- lexical-binding: t; -*-

(require 'syd/base)
(require 'syd/popups)
(require 'syd/leader)

(use-package clojure-mode
  :mode (("\\.\\(clj\\|cljd\\|dtm\\|edn\\|lpy\\)\\'" . clojure-mode)
         ("\\.cljc\\'" . clojurec-mode)
         ("\\.cljs\\'" . clojurescript-mode)
         ("\\(?:build\\|profile\\)\\.boot\\'" . clojure-mode))
  :interpreter (("bb" . clojure-mode)
                ("nbb" . clojurescript-mode))
  :config
  (add-hook 'clojure-mode-hook #'syd-lisp-mode)
  ;; Correctly indent some popular macros.
  (put-clojure-indent 'for-all 1)
  (put-clojure-indent 'match 1))

(use-package cider
  :after clojure-mode
  :config
  (defun syd-clojure-doc (arg)
    (interactive "P")
    (cider-doc arg)
    cider-doc-buffer)
  (syd-handle '(cider-mode cider-repl-mode)
    :docs #'cider-doc)
  (syd-push shackle-rules
	    `("*cider-doc*" ,@syd-help-popup-options)
	    '("*cider-test-report*")
	    '("*cider-error*")))

(use-package cider-mode
  :straight nil ; Part of `cider'.
  :hook (clojure-mode-local-vars . cider-mode)
  :custom ((cider-show-error-buffer nil)
	   ;; Download Java source archives for local Javadoc and jump-to-def
	   ;; functionality.
	   (cider-download-java-sources t))
  :general
  ;; DEPRECATED: Remove once a `map!' equivalent is implemented.
  (:keymaps 'cider-repl-mode-map
	    :states '(normal insert)
	    "C-k" #'cider-repl-backward-input
	    "C-j" #'cider-repl-forward-input
	    "C-s" #'consult-history)
  ;; DEPRECATED: Remove once a `map!' equivalent is implemented.
  (:keymaps '(cider-repl-mode-map clojure-mode-map)
	    :states '(normal visual motion emacs insert)
	    :major-modes t
	    :prefix syd-localleader-key
	    :non-normal-prefix syd-alt-localleader-key
	    "\"" #'cider-jack-in-cljs
	    "'" #'cider-jack-in-clj
	    "c" #'cider-connect-clj
	    "C" #'cider-connect-cljs
	    "r l" #'cider-load-buffer
	    "r n" #'cider-repl-set-ns
	    "r r" #'cider-ns-refresh
	    "r R" #'cider-restart
	    "r q" #'cider-quit
	    "d d" #'cider-debug-defun-at-point
	    "M-:" #'cider-read-and-eval
	    "h d" #'cider-doc
	    "h c" #'cider-cheatsheet
	    "h j" #'cider-javadoc
	    "h n" #'cider-browse-ns
	    "T n" #'cider-test-run-ns-tests
	    "T r" #'cider-test-rerun-failed-tests
	    "T R" #'cider-test-rerun-test
	    "x" #'cider-scratch)
  (:keymaps 'cider-repl-mode-map
	    :states 'insert
	    "S-<return>" #'cider-repl-newline-and-indent)
  :config
  (add-hook 'cider-mode-hook #'eldoc-mode)
  (with-eval-after-load 'consult
    (add-to-list
     'consult-mode-histories
     '(cider-repl-mode cider-repl-input-history nil cider-repl-bol-mark)))
  
  ;; Lines of the form "!!!graph:/path/to/file.svg" are be displayed
  ;; in-buffer by this hook.
  (syd-add-hook 'cider-repl-preoutput-hook
    (defun syd-clojure--render-graphviz-h (s)
      (if (string-match (rx bol "!!!graph:"
			    (group (* anychar) ".svg"))
			s)
	  (let ((beg (match-beginning 0))
		(end (match-end 0))
		(file (match-string 1 s)))
	    (message "%d %d %s" beg end file)
	    (add-display-text-property
	     beg end
	     'display
	     `(image :type svg
		     :file ,file)
	     s)
	    s)
	s))))

(provide 'syd/clojure)
