From fd9db946a566c9d1e469d40142417d33e552213b Mon Sep 17 00:00:00 2001 From: Howard Abrams Date: Wed, 24 Aug 2022 14:37:29 -0700 Subject: [PATCH] Initial Clojure Integration This has been ported to my system for years, and much of what I had I don't really need anymore. --- ha-programming-clojure.org | 162 +++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 ha-programming-clojure.org diff --git a/ha-programming-clojure.org b/ha-programming-clojure.org new file mode 100644 index 0000000..188f1ff --- /dev/null +++ b/ha-programming-clojure.org @@ -0,0 +1,162 @@ +#+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