#-*- mode: org -*-
#+TITLE: Emacs Setup for the Clojure Programming Language
#+AUTHOR: Volker Edelmann
#+EMAIL:  vedelmann@gmx.de
#+STARTUP: indent
#+OPTIONS:  toc:nil
#+OPTIONS:   ^:{}

#+begin_src emacs-lisp
  ;; -*- coding: utf-8; lexical-binding: t -*-
#+end_src

Clojure belongs to the LISP family, therefore a Tree-sitter-grammar is obsolete.
Editing is done using LISP centered editing.
Development workflow is REPL driven development.

Environment setup:

#+begin_src emacs-lisp
    (env-setup "clojure")
#+end_src
 
* Tree-sitter
#+begin_src emacs-lisp
  (require 'clojure-ts-mode)
  (push '(clojure-mode . clojure-ts-mode) major-mode-remap-alist)
#+end_src

* Editing
#+begin_src emacs-lisp
  (use-package smartparens
)
#+end_src


#+begin_src emacs-lisp
  (use-package rainbow-delimiters
    )
#+end_src
 
* Folding
 
* Linting
Linters: joker, clj-kondo

#+begin_src emacs-lisp
#+end_src

  (use-package flymake-joker)
Joker not tried.

#+begin_src emacs-lisp
    (use-package flycheck-clj-kondo)
 #+end_src

* Language Server
CIDER provides all I need.

Links from people using clojure language server:
- https://manueluberti.eu/posts/2023-03-25-clojure-lsp/
- https://emacs-lsp.github.io/lsp-mode/tutorials/clojure-guide/
- https://metaredux.com/posts/2023/12/23/cider-clojure-lsp-sitting-on-a-tree.html

* Major Mode

#+begin_src emacs-lisp
  (use-package clojure-ts-mode
    :hook
    (clojure-ts-mode . yas-minor-mode)
    (clojure-ts-mode . eldoc-mode)
    (clojure-ts-mode . smartparens-mode)
    (clojure-ts-mode . subword-mode)
    (clojure-ts-mode . flycheck-mode)
    (clojure-ts-mode . rainbow-delimiters-mode)
  )
#+end_src

* REPL
#+begin_src emacs-lisp
    (use-package cider
      :config
      (setq nrepl-log-messages t)
      (add-hook 'before-save-hook 'cider-format-buffer t t)
      :bind (
             :map cider-mode-map
               ("C-c d"    . cider-doc)
               ("C-c D"    . cider-apropos-select)
               ("C-c p"    . er/mark-paragraph)
               ("C-c f"    . er/mark-defun)
               ("C-c s"    . er/mark-symbol)
               ("C-+"      . expreg-expand)
               ("C--"      . expreg-contract)                 
             ("C-c C-f"  . cider-eval-function-at-point)
             ("C-c C-s"  . cider-eval-sexp-at-point)
             ("C-c C-l"  . cider-eval-list-at-point)
             ("C-c C-n"  . cider-repl-set-ns)
             ("S-<return>"   . cider-eval-sexp-at-point)
             ("C-<return>"   . cider-eval-dwim)
             ("M-<return>"   . cider-insert-last-sexp-in-repl)
             ("C-M-x"        . nil)               
             nil
             )
      :hook
      (cider-repl-mode . eldoc-mode)
      (cider-repl-mode . smartparens-mode)
      (cider-repl-mode . subword-mode)
      (cider-repl-mode . rainbow-delimiters-mode)
  ;;    ((cider-mode eglot-managed-mode) . eglot-disable-in-cider)
      )
#+end_src

* Hydras
#+begin_src emacs-lisp
  (use-package cider-hydra
  :hook
      (clojure-ts-mode . cider-hydra-mode)
    )
#+end_src

* Refactoring
#+begin_src emacs-lisp
  (use-package clj-refactor
  :hook
      (clojure-ts-mode . clj-refactor-mode)
  )
#+end_src

* TODO Debugging

* Literate Programming
... with org-mode

#+begin_src emacs-lisp
  (require 'org)
  (require 'ob-clojure)
  (setq org-babel-clojure-backend 'cider)
  (require 'cider)
#+end_src


* Documentation
use Hydra

* UI
#+begin_src emacs-lisp
  (major-mode-hydra-define clojure-ts-mode nil
    ("General"
     (
      ("l" flycheck-list-errors "linter window" :exit t)
      ("+" yas-insert-snippet  "code snippets")
      )
     "Eval"
     (
      ("b"       cider-eval-buffer           "buffer")
      ("f"       cider-eval-defun-at-point   "function")
      ("r"       cider-eval-region           "region")
      ("x"       cider-eval-dwim             "dwim")   
      )
     "REPL"
     (
      ("n"       cider-repl-set-ns      "set namespace")
      ("j"       cider-jack-in-clj      "start clojure repl")
      ("J"       cider-jack-in-cljs     "start clj-script repl")
      )
     "Test"
     (
      )
     "Doc"
     (
      ("d"       cider-doc              "clojure doc")
      ("a"       cider-apropos-select   "clojure apropos ...")
      ("w"       cider-clojuredocs-web  "clojure docs web")
      ("j"       cider-javadoc          "java doc")
      )
     )
    )
#+end_src