{"id":13863080,"url":"https://github.com/clojure-emacs/inf-clojure","last_synced_at":"2025-04-06T09:08:05.972Z","repository":{"id":24108625,"uuid":"27496578","full_name":"clojure-emacs/inf-clojure","owner":"clojure-emacs","description":"Basic interaction with a Clojure subprocess","archived":false,"fork":false,"pushed_at":"2023-12-02T16:36:08.000Z","size":361,"stargazers_count":251,"open_issues_count":24,"forks_count":44,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-03-30T07:11:13.369Z","etag":null,"topics":["clojure","clojure-repl","clojurescript","emacs","repl","socket-repl"],"latest_commit_sha":null,"homepage":"","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clojure-emacs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"bbatsov","patreon":"bbatsov","custom":"https://www.paypal.me/bbatsov"}},"created_at":"2014-12-03T16:34:56.000Z","updated_at":"2025-02-07T02:17:46.000Z","dependencies_parsed_at":"2024-01-11T01:23:10.072Z","dependency_job_id":null,"html_url":"https://github.com/clojure-emacs/inf-clojure","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Finf-clojure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Finf-clojure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Finf-clojure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Finf-clojure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clojure-emacs","download_url":"https://codeload.github.com/clojure-emacs/inf-clojure/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247457801,"owners_count":20941906,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","clojure-repl","clojurescript","emacs","repl","socket-repl"],"created_at":"2024-08-05T06:02:01.541Z","updated_at":"2025-04-06T09:08:05.945Z","avatar_url":"https://github.com/clojure-emacs.png","language":"Emacs Lisp","readme":"[![Circle CI][circleci-badge]][circleci]\n[![MELPA][melpa-badge]][melpa-package]\n[![MELPA Stable][melpa-stable-badge]][melpa-stable-package]\n[![NonGNU ELPA](https://elpa.nongnu.org/nongnu/inf-clojure.svg)](https://elpa.nongnu.org/nongnu/inf-clojure.html)\n[![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://discord.com/invite/nFPpynQPME)\n[![License GPL 3][badge-license]][copying]\n\n# inf-clojure\n\nThis package provides basic interaction with a Clojure subprocess (REPL).\nIt's based on ideas from the popular `inferior-lisp` package.\n\n`inf-clojure` has two components - a nice REPL buffer (`inf-clojure-mode`) and a REPL\ninteraction minor mode (`inf-clojure-minor-mode`), which extends `clojure-mode`\nwith commands to evaluate forms directly in the REPL.\n\n-----------\n\n**This documentation tracks the `master` branch of `inf-clojure`. Some of\nthe features and settings discussed here might not be available in\nolder releases (including the current stable release). Please, consult\nthe relevant git tag (e.g. 2.2.0) if you need documentation for a\nspecific `inf-clojure` release.**\n***\n\n## Overview\n\n`inf-clojure` aims to expose the extensive self-documenting features of Clojure\nREPLs via an Emacs package. `inf-clojure` is extremely simple and does not require special tooling.\nIt supports the following REPLs:\n\n- Clojure\n- ClojureScript\n- ClojureCLR (via [lein-clr](https://github.com/kumarshantanu/lein-clr))\n- [Planck](http://planck-repl.org/)\n- [Lumo](https://github.com/anmonteiro/lumo)\n- [Joker](https://joker-lang.org/)\n- [babashka](https://github.com/borkdude/babashka)\n\n`inf-clojure` provides a set of essential features for interactive\nClojure/ClojureScript/ClojureCLR development:\n\n* Enhanced REPL\n* Interactive code evaluation\n* Code completion\n* Definition lookup\n* Documentation lookup\n* ElDoc\n* Apropos\n* Macroexpansion\n* Reloading a namespace (via `require :reload`/`require :reload-all`)\n* Connecting to socket REPLs\n\nFor a more powerful/full-featured solution see [CIDER](https://github.com/clojure-emacs/cider).\n\n## Rationale\n\n`inf-clojure`'s goal is to provide the simplest possible way to interact with a Clojure REPL.\nIn Emacs terminology \"inferior\" process is a subprocess started by Emacs (it being the \"superior\" process, of course).\n\n`inf-clojure` doesn't require much of setup, as at its core it simply runs a terminal REPL process, pipes input to it, and\nprocesses its output. As the Clojure socket REPL works in exactly the same manner `inf-clojure` can also interact with it.\n\nFunctionality like code completion and eldoc is powered by evaluation of predefined code snippets that provide the necessary results.\nAs different Clojure REPLs have different capabilities, `inf-clojure` tracks the type of a REPL and invokes\nthe right code for each REPL type.\n\n`inf-clojure` is built on top of Emacs's [comint](https://github.com/emacs-mirror/emacs/blob/master/lisp/comint.el). Unfortunately `comint` is pretty light on official documentation, but there is a good overview/tutorial [here](https://www.masteringemacs.org/article/comint-writing-command-interpreter).\n\n## Installation\n\n**Note:** `inf-clojure` requires Emacs 25 or newer.\n\n`inf-clojure` is available on the official [NonGNU ELPA](https://elpa.nongnu.org/nongnu/inf-clojure.html) `package.el` repo and on the community-maintained\n[MELPA Stable][] and [MELPA][] repos.\n\nNonGNU ELPA and MELPA Stable are recommended as they have the latest stable version.\nMELPA has a development snapshot for users who don't mind breakage but\ndon't want to run `inf-clojure` from a git checkout.\n\nYou can install `inf-clojure` using the following command:\n\n\u003ckbd\u003eM-x package-install [RET] inf-clojure [RET]\u003c/kbd\u003e\n\nor if you'd rather keep it in your Emacs config:\n\n```emacs-lisp\n(unless (package-installed-p 'inf-clojure)\n  (package-refresh-contents)\n  (package-install 'inf-clojure))\n```\n\nIf the installation doesn't work try refreshing the package list:\n\n\u003ckbd\u003eM-x package-refresh-contents\u003c/kbd\u003e\n\n`inf-clojure-minor-mode` will be auto-enabled for Clojure source buffers after you do\n`M-x inf-clojure`. You can disable this behavior by setting `inf-clojure-auto-mode` to\n`nil`.\n\nYou can also add the following to your Emacs config to enable\n`inf-clojure-minor-mode` for Clojure source buffers, regardless of whether there's an `inf-clojure` REPL running:\n\n```emacs-lisp\n(add-hook 'clojure-mode-hook #'inf-clojure-minor-mode)\n```\n\n**Warning:** Don't enable `inf-clojure-minor-mode` and `cider-mode` at the same time. They\nhave overlapping functionality and keybindings and the result will be nothing\nshort of havoc.\n\n## Basic Usage\n\nJust invoke `M-x inf-clojure` or press `C-c C-z` within a Clojure\nsource file. You should get a prompt with the supported REPL types and\ncommon startup forms. You can select one of these or type in your own\ncustom startup. This will start a REPL process for the current project\nand you can start interacting with it.\n\nIf you want to use a socket REPL server, use `M-x inf-clojure-socket-repl`\nwhich will start a socket server and connect to it for you.\n\nIf you've already started a socket REPL server, use `M-x inf-clojure-connect`\nand enter its host and port numbers.\n\nInf-clojure aims to be very simple and offer tooling that the REPL\nitself exposes. A few commands are:\n\n- eval last sexp (`C-x C-e`)\n- show arglists for function (`C-c C-a`)\n- show var documentation (`C-c C-v`)\n- show source (`C-c C-s`)\n- insert top level form into REPL (`C-c C-j d`)\n\nFor a list of all available commands in `inf-clojure-mode` (a.k.a. the\nREPL) and `inf-clojure-minor-mode` you can either invoke `C-h f RET\ninf-clojure-mode` and `C-h f RET inf-clojure-minor-mode` or simply\nbrowse their menus.\n\nMany `inf-clojure-minor-mode` commands by default act on the symbol at\npoint. You can, however, change this behaviour by invoking such\ncommands with a prefix argument. For instance: `C-u C-c C-v` will ask\nfor the symbol you want to show the docstring for.\n\n## Configuration\n\n**Note:** The configuration options were changed massively in `inf-clojure` 3.0.\n\nIn the time-honoured Emacs tradition `inf-clojure`'s behaviour is extremely\nconfigurable.\n\nYou can set custom values to `inf-clojure` variables on a\nper-project basis using [directory\nvariables](https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html)\nor by setting them in in your init file.\n\nYou can see all the configuration options available using the command\n`M-x customize-group RET inf-clojure`.\n\n### Startup\n\nWhile `inf-clojure` is capable of starting many common REPLs out of the box, it's\nfairly likely you will want to set some custom REPL startup command\n(e.g. because you need to include some `tools.deps` profile) and the REPL type\nthat goes with it. This is most easily achieved with the following `.dir-locals.el`:\n\n```emacs-lisp\n((nil\n  (inf-clojure-custom-startup . \"clojure -A:compliment\")\n  (inf-clojure-custom-repl-type . clojure)))\n```\n\n**Note:** This file has to be in the directory in which you're invoking `inf-clojure` or a parent\ndirectory.\n\nThere are two important configuration variables here:\n\n1. `inf-clojure-custom-startup`: Which startup command to use so\n   inf-clojure can run the inferior Clojure process (REPL).\n2. `inf-clojure-custom-repl-type`: The type of the REPL started by the above command (e.g. `lumo`).\n\nIf these are set and you wish to prevent inf-clojure from using them,\nuse a prefix arg when invoking `inf-clojure` (`C-u M-x inf-clojure`).\n\n### REPL Features\n\nThe supported REPL-features are in an alist called\n`inf-clojure-repl-features` and it has the following shape:\n\n```emacs-lisp\n'((cljs . ((doc . \"(cljs.repl/doc %s)\")\n           (source . \"(cljs.repl/source %s)\")\n           (arglists . \"(try (-\u003e\u003e '%s cljs.core/resolve cljs.core/meta :arglists) (catch :default _ nil))\")\n           (apropos . \"(cljs.repl/apropos \\\"%s\\\")\")\n           (ns-vars . \"(cljs.repl/dir %s)\")\n           (set-ns . \"(in-ns '%s)\")\n           (macroexpand . \"(cljs.core/macroexpand '%s)\")\n           (macroexpand-1 . \"(cljs.core/macroexpand-1 '%s)\"))))\n```\n\nIf you want to add a new REPL type, just do something like:\n\n``` emacs-lisp\n(add-to-list 'inf-clojure-repl-features\n             (cons new-repl-type '((doc . \"(myrepl/doc-command %s\")\n                                   (source . \"...\")\n                                   ...)))\n```\n\nThe `inf-clojure-repl-features` data structure is just an\nalist of alists, so you can manipulate it in numerous ways.\n\nIf you want to update a specific form there is a function\n`inf-clojure-update-repl-feature` which can be used like so:\n\n```emacs-lisp\n(inf-clojure-update-feature 'clojure 'completion \"(incomplete.core/completions \\\"%s\\\")\")\n```\n\n#### Caveats\n\nAs `inf-clojure` is built on top of `comint` it has all the usual comint limitations -\nnamely it can't handle well some fancy terminal features (e.g. ANSI colours).\nIn general the \"dumber\" your terminal REPL is, the better (e.g. `clojure` vs `clj`).\nConnecting to a socket REPL is one simple way to avoid dealing with this type of\nproblems.\n\nIf you decide _not_ to use the socket REPL, it is highly recommended\nyou disable output coloring and/or `readline` facilities: `inf-clojure` does not\nfilter out ASCII escape characters at the moment and will not behave correctly.\n\nFor Leiningen, there are no command-line switches and you need to add\na custom [`project.clj`\noption](https://github.com/technomancy/leiningen/blob/master/sample.project.clj):\n\n```clojure\n...\n:repl-options {:color false}\n...\n```\n\n#### Clojure Command Line Socket REPL\n\nIf you have the new [Clojure CLI tools][] installed you can use the `clojure` command:\n\n_do not use `clj` because it adds readline support_\n\n``` shellsession\n$ clojure -J-Dclojure.server.repl=\"{:port 5555 :accept clojure.core.server/repl}\"\n```\n\nThen either `C-c M-c RET localhost RET 5555` from within Emacs or add the following to your `.dir-locals.el`:\n\n```emacs-lisp\n((nil . ((inf-clojure-custom-startup . (\"localhost\" . 5555)))))\n```\n#### Leiningen Socket REPL\n\nFor Leiningen, add the following option to your `~/.lein/profiles.clj` or your `project.clj`:\n\n```clojure\n:jvm-opts [\"-Dclojure.server.repl={:port 5555 :accept clojure.core.server/repl}\"]\n```\n\nThen run `lein repl` from within your project directory to start the\nREPL.  To connect, you can either `m-x inf-clojure-connect [RET]\nlocalhost [RET] 5555` or you can put in a dir local file the\ninformation on how connect:\n\n```emacs-lisp\n((nil (inf-clojure-custom-startup \"localhost\" . 5555)))\n```\n\nThe socket server REPL configuration options are described [here](https://clojure.org/reference/repl_and_main#_launching_a_socket_server).\n\n#### Lumo Socket REPL\n\nLumo is decoupled from `inf-clojure-project-type` and therefore the command used depends on what you are using for dependency resolution.\n\nFor example if a `project.clj` is present in the project root folder, `inf-clojure-lein-cmd` will be used.\n\nAfter you launch `lumo ... -n 5555`, as customary, either `C-c M-c RET localhost RET 5555` from within Emacs or add the following to your `.dir-locals.el`:\n\n```emacs-lisp\n((nil (inf-clojure-custom-startup \"localhost\" . 5555)))\n```\n\n#### Multiple Process Support\n\nTo run multiple Clojure processes, you start the first up\nwith `inf-clojure`.  It will be in a buffer named `*inf-clojure*`.\nRename this buffer with `rename-buffer`.  You may now start up a new\nprocess with another `inf-clojure`.  It will be in a new buffer,\nnamed `*inf-clojure*`.  You can switch between the different process\nbuffers with `switch-to-buffer`.\n\n**Note:** If you're starting `inf-clojure` within a Clojure project directory\nthe name of the project will be incorporated into the name of the REPL buffer\n- e.g. `*inf-clojure my-project*`.\n\nCommands that send text from source buffers to Clojure processes (like `inf-clojure-eval-defun`\nor `inf-clojure-show-arglists`) have to choose a process to send to, when you have more than\none Clojure process around. This is determined by the global variable `inf-clojure-buffer`.\n\nSuppose you have three inferior Clojures running:\n\n```\nBuffer              Process\n------              -------\nfoo                 inf-clojure\nbar                 inf-clojure\u003c2\u003e\n*inf-clojure*       inf-clojure\u003c3\u003e\n```\n\nIf you do a `inf-clojure-eval-defun` command on some Clojure source code,\nwhat process do you send it to?\n\n- If you're in a process buffer (foo, bar, or `*inf-clojure*`),\n  you send it to that process.\n- If you're in some other buffer (e.g., a source file), you\n  send it to the process attached to buffer `inf-clojure-buffer`.\n\nThis process selection is performed by function `inf-clojure-proc`.\nWhenever `inf-clojure` fires up a new process, it resets\n`inf-clojure-buffer` to be the new process's buffer.  If you only run\none process, this does the right thing.  If you run multiple\nprocesses, you might need to change `inf-clojure-buffer` to\nwhichever process buffer you want to use.\n\nYou can use the helpful function `inf-clojure-set-repl`. If called in\nan `inf-clojure` REPL buffer, it will assign that buffer as the current\nREPL (`(setq inf-clojure-buffer (current-buffer)`). If you are\nnot in an `inf-clojure` REPL buffer, it will offer a choice of\nacceptable buffers to set as the REPL buffer. If called with a prefix,\nit will always give the list even if you are currently in an\nacceptable REPL buffer.\n\n**Tip:** Renaming buffers will greatly improve the\nfunctionality of this list; the list \"project-1: clojure repl\",\n\"project-2: cljs repl\" is far more understandable than \"inf-clojure\",\n\"inf-clojure\u003c2\u003e\".\n\n#### REPL Type\n\nAn `inf-clojure` REPL has an associated type. The available types can be\nobtained from `inf-clojure-repl-features`:\n\n```emacs-lisp\n(mapcar 'car inf-clojure-repl-features)\n\n;; =\u003e (cljs lumo planck joker clojure babashka)\n```\n\nWhat does it mean that a REPL type is supported? Well, it means that\n`inf-clojure` would use the proper Clojure(Script) code internally to power\ncommands like definition lookup and friends.  Those differ from REPL to REPL and\ncan't be implemented in a REPL-independent way. The REPL type is inferred on\nstartup when using the `inf-clojure` command or is specified manually when using\n`inf-clojure-connect`.\n\n#### ElDoc\n\n`eldoc-mode` is supported in Clojure source buffers and `*inferior-clojure*`\nbuffers which are running a Clojure REPL.\n\nWhen ElDoc is enabled and there is an active REPL, it will show the argument\nlist of the function call you are currently editing in the echo area. It\naccomplishes this by evaluating forms to get the metadata for the vars under\nyour cursor. One side effect of this is that it can mess with repl vars like\n`*1` and `*2`. You can disable inf-clojure's Eldoc functionality with `(setq\ninf-clojure-enable-eldoc nil)`.\n\n\nElDoc should be enabled by default in Emacs 26.1+. If it is not active by\ndefault, you can activate ElDoc with `M-x eldoc-mode` or by adding the following\nto you Emacs config:\n\n```emacs-lisp\n(add-hook 'clojure-mode-hook #'eldoc-mode)\n(add-hook 'inf-clojure-mode-hook #'eldoc-mode)\n```\n\nElDoc currently doesn't work with ClojureScript buffers and REPL's.\nYou can leave it enabled, it just won't show anything in the echo area.\n\n#### Code Completion\n\nCode completion is a tricky aspect if you are trying to be as close to\na generic REPL as possible. Planck and lumo REPL implementations\nexplicitly provide completion functions in their REPL namespaces. For\nclojure, you will need to have a library on your classpath. If you are\nusing a recent version of Leiningen, you already have\n[incomplete](https://github.com/nrepl/incomplete). You\ncould alternatively use `compliment {:mvn/version \"0.3.10\"}`.\n\n```emacs-lisp\n;; for incomplete\n(inf-clojure-update-feature 'clojure 'completion \"(incomplete.core/completions \\\"%s\\\")\")\n\n;; or\n;; for compliment\n(inf-clojure-update-feature 'clojure 'completion \"(compliment.core/completions \\\"%s\\\")\")\n\n```\n\nIf you give a form for the completion form, it is your responsibility\nto ensure that this namespace is on the classpath and required. If\nusing Leiningen, this is done for you with `incomplete`. If adding\n`compliment`, the following sample `deps.edn` can conveniently add the dep\nto your program:\n\n```clojure\n{:aliases {:compliment {:extra-deps {compliment {:mvn/version \"0.3.10\"}}}}}\n```\n\nUse the startup command: `clojure -A:compliment`. Then require the ns\nonce so that the completion machinery will work: `(require\n'compliment.core)`. Now tab completion should work.\n\nFor more advanced customization, code completion is particularly open\nto customization. Not only you can `setq` the customary\n`inf-clojure-completion-form`, `inf-clojure-completion-form-lumo`,\n`inf-clojure-completion-form-planck` and\n`inf-clojure-completion-form-joker` - the form to send to the REPL -\nbut you can also use `inf-clojure-completions-fn` for specifying a\nfunction that given the REPL response should return Elisp data\ncompatible with\n[`completion-at-point-functions`](https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion-in-Buffers.html).\nFor more info run `M-x describe-variable RET\ninf-clojure-completions-fn`.  Another option is to have a look at [how\ncider does\nit](https://github.com/clojure-emacs/cider/blob/3e9ed12e8cfbad04d7618e649322765dc9bff5d6/cider-interaction.el#L595).\n\n#### Lumo Setup\n\nFor an optimal Lumo experience the `-d` needs to be passed to Lumo\nwhen launched from the command line. This disable `readline` support\nin order to play nicely with Emacs.\n\n## Troubleshooting\n\n### Things seem broken\n\nInf-clojure is intentionally quite simple and just sends commands to a\nREPL on your behalf to provide features. In order to do this\ninf-clojure largely needs to know the REPL type so it can format the\ncorrect calls. Most end up in `(lumo.repl/doc [symbol])` or\n`(cljs.repl/doc ...)` so its important that the REPL type is set\ncorrectly. This REPL type exists in the process buffer (REPL) and the\nsource buffers as a cache. If you have problems, run `m-x\ninf-clojure-set-repl-type` from the source buffer to set the REPL type\nin both buffers. To see how simple inf-clojure is, look at\n`inf-clojure-repl-features` to see largely how things are laid out.\n\n### REPL not responsive in Windows OS\n\nIn Windows, the REPL is not returning anything. For example, type `(+\n1 1)` and press `ENTER`, the cursor just drops to a new line and\nnothing is shown.\n\nThe explanation of this problem and solution can be found [here](https://groups.google.com/forum/#!topic/leiningen/48M-xvcI2Ng).\n\nThe solution is to create a file named `.jline.rc` in your `$HOME`\ndirectory and add this line to that file:\n\n```\njline.terminal=unsupported\n```\n\n### Log process activity\n\nStandard Emacs debugging turns out to be difficult when an asynchronous process is involved. In this case try to enable logging:\n\n```emacs-lisp\n(setq inf-clojure-log-activity t)\n```\n\nThis creates `.inf-clojure.log` in the project directory so that you can `tail -f` on it.\n\n## License\n\nCopyright © 2014-2022 Bozhidar Batsov and [contributors][].\n\nDistributed under the GNU General Public License; type \u003ckbd\u003eC-h C-c\u003c/kbd\u003e to view it.\n\n[badge-license]: https://img.shields.io/badge/license-GPL_3-green.svg\n[melpa-badge]: http://melpa.org/packages/inf-clojure-badge.svg\n[melpa-stable-badge]: http://stable.melpa.org/packages/inf-clojure-badge.svg\n[melpa-package]: http://melpa.org/#/inf-clojure\n[melpa-stable-package]: http://stable.melpa.org/#/inf-clojure\n[COPYING]: http://www.gnu.org/copyleft/gpl.html\n[circleci]: https://circleci.com/gh/clojure-emacs/inf-clojure\n[circleci-badge]: https://circleci.com/gh/clojure-emacs/inf-clojure.svg?style=svg\n[CIDER]: https://github.com/clojure-emacs/cider\n[Leiningen]: http://leiningen.org\n[contributors]: https://github.com/clojure-emacs/inf-clojure/contributors\n[melpa]: http://melpa.org\n[melpa stable]: http://stable.melpa.org\n[Emacs init file]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html\n[Clojure cli tools]: https://clojure.org/guides/getting_started\n[Boot]: http://boot-clj.com\n","funding_links":["https://github.com/sponsors/bbatsov","https://patreon.com/bbatsov","https://www.paypal.me/bbatsov"],"categories":["Emacs Lisp","Clojure Tools, Libraries, and Frameworks"],"sub_categories":["JavaScript Libraries for Machine Learning"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclojure-emacs%2Finf-clojure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclojure-emacs%2Finf-clojure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclojure-emacs%2Finf-clojure/lists"}