#+TITLE: Clojure Programming #+AUTHOR: Howard X. Abrams #+DATE: 2022-04-05 #+FILETAGS: :emacs: A literate programming file for programming in Clojure. #+begin_src emacs-lisp :exports none ;;; ha-programming-clojure --- programming in Clojure. -*- lexical-binding: t; -*- ;; ;; © 2022 Howard X. Abrams ;; Licensed under a Creative Commons Attribution 4.0 International License. ;; See http://creativecommons.org/licenses/by/4.0/ ;; ;; Author: Howard X. Abrams ;; Maintainer: Howard X. Abrams ;; Created: April 5, 2022 ;; ;; This file is not part of GNU Emacs. ;; ;; *NB:* Do not edit this file. Instead, edit the original literate file at: ;; ~/other/hamacs/ha-programming-clojure.org ;; And tangle the file to recreate this one. ;; ;;; Code: #+end_src I like [[http://clojure.org][Clojure]] as a /modern Lisp/, but I don’t get to play with it much. The following instructions create a fully blinged-out Emacs-Clojure setup. * Introduction To get Clojure working on a new system, try the following on a Mac: #+begin_src sh brew install clojure/tools/clojure #+end_src And make sure it works: #+begin_src sh clojure --help #+end_src Or by starting a REPL: #+begin_src sh clj #+end_src Also, download this script: #+begin_src sh curl -o ~/bin/lein https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein chmod u+x ~/bin/lein #+end_src Then for each project, create the project directory with this command: #+begin_src sh lein new app fresh-app #+end_src * Emacs Support We begin with using [[https://github.com/clojure-emacs/clojure-mode/][clojure-mode]]: #+begin_src emacs-lisp (use-package clojure-mode :init (add-to-list 'org-babel-load-languages '(clojure . t)) :config (defun ha-prettify-clojure () "Make the Clojure syntax prettier." (push '("fn" . ?𝝀) prettify-symbols-alist) (push '("__" . ?⁈) prettify-symbols-alist) (prettify-symbols-mode)) :hook (clojure-mode . ha-prettify-clojure)) #+end_src Need the IDE feature of [[https://github.com/clojure-emacs/cider][Cider]]: #+begin_src emacs-lisp (use-package cider :commands (cider cider-connect cider-jack-in) :init (setq cider-auto-select-error-buffer nil cider-repl-pop-to-buffer-on-connect nil cider-repl-use-clojure-font-lock t cider-repl-wrap-history t cider-repl-history-size 1000 cider-show-error-buffer t nrepl-hide-special-buffers t ;; Stop error buffer from popping up while working in buffers other than the REPL: nrepl-popup-stacktraces nil)) #+end_src Read the entire [[https://docs.cider.mx/][CIDER manual]]. ** Linting Using [[https://github.com/jonase/eastwood#emacs--cider][Eastwood]] with the [[https://github.com/clojure-emacs/squiggly-clojure][Squiggly Clojure]] project to add lint warnings to [[file:emacs.org::*Flycheck][Flycheck]]: #+begin_src elisp (use-package flycheck-clojure :after flycheck :config (flycheck-clojure-setup)) #+end_src ** Snippets For clojure-specific templates for [[https://github.com/capitaomorte/yasnippet][yasnippets]], clone David Nolen's [[http://github.com/swannodette/clojure-snippets][clojure-snippets]] repository into my =snippets= directory: #+begin_src sh :tangle no git clone http://github.com/swannodette/clojure-snippets ~/.emacs/snippets/clojure-mode #+end_src Or install it as a package: #+begin_src elisp (use-package clojure-snippets) #+end_src ** Refactoring The [[https://github.com/clojure-emacs/clj-refactor.el][clj-refactor]] project: #+begin_src elisp (use-package clj-refactor :hook (clojure-mode . clj-refactor-mode) :config ;; Configure the Clojure Refactoring prefix: (cljr-add-keybindings-with-prefix "C-c .") :diminish clj-refactor-mode) #+end_src The advanced refactorings require the [[https://github.com/clojure-emacs/refactor-nrepl][refactor-nrepl middleware]], which should explain why we added the =refactor-nrepl= to the =:plugins= section in the =~/.lein/profiles.clj= file (see below). The /real problem/ is trying to remember all the [[https://github.com/clojure-emacs/clj-refactor.el/wiki][refactoring options]]. Remember: =C-c . h h= ** Org Babel And of course, we want to put this with org blocks: #+begin_src emacs-lisp (use-package ob-clojure :straight (:type built-in) :custom (org-babel-clojure-backend 'cider) :config (add-to-list 'org-babel-load-languages '(clojure . t))) #+end_src Does this now work? #+begin_src clojure :results raw replace (format "The answer is %d" (+ (* 4 10) 2)) #+end_src #+RESULTS: "The answer is 42" * LSP, a WIP Check out the goodies in [[https://emacs-lsp.github.io/lsp-mode/tutorials/clojure-guide/][this essay]] for hooking Clojure to LSP. Haven’t done this yet. #+begin_src emacs-lisp :tangle no (add-hook 'clojure-mode-hook 'lsp) (add-hook 'clojurescript-mode-hook 'lsp) (add-hook 'clojurec-mode-hook 'lsp) #+end_src * Technical Artifacts :noexport: Let's =provide= a name so we can =require= this file: #+begin_src emacs-lisp :exports none (provide 'ha-programming-clojure) ;;; ha-programming-clojure.el ends here #+end_src #+DESCRIPTION: programming in Clojure. #+PROPERTY: header-args:sh :tangle no #+PROPERTY: header-args:emacs-lisp :tangle yes #+PROPERTY: header-args :results none :eval no-export :comments no mkdirp yes #+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil date:nil #+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil #+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js