{"id":13591746,"url":"https://github.com/clojure-emacs/clojure-mode","last_synced_at":"2025-05-14T14:10:05.618Z","repository":{"id":461338,"uuid":"85632","full_name":"clojure-emacs/clojure-mode","owner":"clojure-emacs","description":"Emacs support for the Clojure(Script) programming language","archived":false,"fork":false,"pushed_at":"2025-04-06T15:43:34.000Z","size":24680,"stargazers_count":942,"open_issues_count":45,"forks_count":247,"subscribers_count":48,"default_branch":"master","last_synced_at":"2025-04-11T21:48:47.965Z","etag":null,"topics":["clojure","clojure-mode","emacs","emacs-lisp","emacs-package","major-mode"],"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":"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,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"bbatsov","patreon":"bbatsov","ko_fi":"bbatsov","open_collective":"cider","liberapay":"bbatsov","custom":"https://www.paypal.me/bbatsov"}},"created_at":"2008-12-05T17:45:07.000Z","updated_at":"2025-04-09T00:36:46.000Z","dependencies_parsed_at":"2023-01-11T15:35:08.850Z","dependency_job_id":"e69133f3-f3a9-4001-8517-78f4a381efc7","html_url":"https://github.com/clojure-emacs/clojure-mode","commit_stats":{"total_commits":1333,"total_committers":182,"mean_commits":7.324175824175824,"dds":0.7756939234808702,"last_synced_commit":"eabe29b076fff19db552d36d4babaa36ecf0b704"},"previous_names":[],"tags_count":47,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Fclojure-mode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Fclojure-mode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Fclojure-mode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Fclojure-mode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clojure-emacs","download_url":"https://codeload.github.com/clojure-emacs/clojure-mode/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254160555,"owners_count":22024571,"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-mode","emacs","emacs-lisp","emacs-package","major-mode"],"created_at":"2024-08-01T16:01:01.549Z","updated_at":"2025-05-14T14:10:00.610Z","avatar_url":"https://github.com/clojure-emacs.png","language":"Emacs Lisp","funding_links":["https://github.com/sponsors/bbatsov","https://patreon.com/bbatsov","https://ko-fi.com/bbatsov","https://opencollective.com/cider","https://liberapay.com/bbatsov","https://www.paypal.me/bbatsov"],"categories":["Emacs Lisp","Clojure Tools, Libraries, and Frameworks"],"sub_categories":["JavaScript Libraries for Machine Learning"],"readme":"[![circleci][badge-circleci]][circleci]\n[![MELPA][melpa-badge]][melpa-package]\n[![MELPA Stable][melpa-stable-badge]][melpa-stable-package]\n[![NonGNU ELPA](https://elpa.nongnu.org/nongnu/clojure-mode.svg)](https://elpa.nongnu.org/nongnu/clojure-mode.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# Clojure Mode\n\n`clojure-mode` is an Emacs major mode that provides font-lock (syntax\nhighlighting), indentation, navigation and refactoring support for the\n[Clojure(Script) programming language](https://clojure.org).\n\n-----------\n\n**This documentation tracks the `master` branch of `clojure-mode`. 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. [5.19.0](https://github.com/clojure-emacs/clojure-mode/tree/v5.19.0)) if you need documentation for a\nspecific `clojure-mode` release.**\n\n## Installation\n\nAvailable on the major `package.el` community maintained repos -\n[MELPA Stable][] and [MELPA][] repos.\n\nMELPA Stable is the recommended repo as it has the latest stable\nversion.  MELPA has a development snapshot for users who don't mind\n(infrequent) breakage but don't want to run from a git checkout.\n\nYou can install `clojure-mode` using the following command:\n\n\u003ckbd\u003eM-x\u003c/kbd\u003e `package-install` \u003ckbd\u003e[RET]\u003c/kbd\u003e `clojure-mode` \u003ckbd\u003e[RET]\u003c/kbd\u003e\n\nor if you'd rather keep it in your dotfiles:\n\n```el\n(unless (package-installed-p 'clojure-mode)\n  (package-install 'clojure-mode))\n```\n\nIf the installation doesn't work try refreshing the package list:\n\n\u003ckbd\u003eM-x\u003c/kbd\u003e `package-refresh-contents`\n\n## Bundled major modes\n\nThe `clojure-mode` package actually bundles together several major modes:\n\n* `clojure-mode` is a major mode for editing Clojure code\n* `clojurescript-mode` is a major mode for editing ClojureScript code\n* `clojurec-mode` is a major mode for editing `.cljc` source files\n\nAll the major modes derive from `clojure-mode` and provide more or less the same\nfunctionality.  Differences can be found mostly in the font-locking -\ne.g. ClojureScript has some built-in constructs that are not present in Clojure.\n\nThe proper major mode is selected automatically based on the extension of the\nfile you're editing.\n\nHaving separate major modes gives you the flexibility to attach different hooks\nto them and to alter their behavior individually (e.g. add extra font-locking\njust to `clojurescript-mode`) .\n\nNote that all modes derive from `clojure-mode`, so things you add to\n`clojure-mode-hook` and `clojure-mode-map` will affect all the derived modes as\nwell.\n\n## Configuration\n\nIn the spirit of Emacs, pretty much everything you can think of in `clojure-mode` is configurable.\n\nTo see a list of available configuration options do `M-x customize-group RET clojure`.\n\n### Indentation options\n\nThe default indentation rules in `clojure-mode` are derived from the\n[community Clojure Style Guide](https://guide.clojure.style).\nPlease, refer to the guide for the general Clojure indentation rules.\n\nIf you'd like to use the alternative \"fixed/tonsky\" indentation style you should\nupdate your configuration accordingly:\n\n``` el\n(setq clojure-indent-style 'always-indent\n      clojure-indent-keyword-style 'always-indent\n      clojure-enable-indent-specs nil)\n```\n\nRead on for more details on the available indentation-related configuration options.\n\n#### Indentation of docstrings\n\nBy default multi-line docstrings are indented with 2 spaces, as this is a\nsomewhat common standard in the Clojure community. You can however adjust this\nby modifying `clojure-docstring-fill-prefix-width`. Set it to 0 if you don't\nwant multi-line docstrings to be indented at all (which is pretty common in most lisps).\n\n#### Indentation of function forms\n\nThe indentation of function forms is configured by the variable\n`clojure-indent-style`. It takes three possible values:\n\n- `always-align` (the default)\n\n```clj\n(some-function\n 10\n 1\n 2)\n(some-function 10\n               1\n               2)\n```\n\n- `always-indent`\n\n```clj\n(some-function\n  10\n  1\n  2)\n(some-function 10\n  1\n  2)\n```\n\n- `align-arguments`\n\n```clj\n(some-function\n  10\n  1\n  2)\n(some-function 10\n               1\n               2)\n```\n\n**Note:** Prior to clojure-mode 5.10, the configuration options for `clojure-indent-style` used to be\nkeywords, but now they are symbols. Keywords will still be supported at least until clojure-mode 6.\n\n#### Indentation of keywords\n\nSimilarly we have the `clojure-indent-keyword-style`, which works in the following way:\n\n* `always-align` (default) -  All\n    args are vertically aligned with the first arg in case (A),\n    and vertically aligned with the function name in case (B).\n\n``` clojure\n(:require [foo.bar]\n          [bar.baz])\n(:require\n [foo.bar]\n [bar.baz])\n```\n\n* `always-indent` - All args are indented like a macro body.\n\n``` clojure\n(:require [foo.bar]\n   [bar.baz])\n(:x\n   location\n   0)\n```\n\n* `align-arguments` - Case (A) is indented like `always-align`, and\n    case (B) is indented like a macro body.\n\n``` clojure\n(:require [foo.bar]\n          [bar.baz])\n(:x\n   location\n   0)\n```\n\n#### Indentation of macro forms\n\nThe indentation of special forms and macros with bodies is controlled via\n`put-clojure-indent`, `define-clojure-indent` and `clojure-backtracking-indent`.\nNearly all special forms and built-in macros with bodies have special indentation\nsettings in `clojure-mode`. You can add/alter the indentation settings in your\npersonal config. Let's assume you want to indent `-\u003e\u003e` and `-\u003e` like this:\n\n```clojure\n(-\u003e\u003e something\n  ala\n  bala\n  portokala)\n```\n\nYou can do so by putting the following in your config:\n\n```el\n(put-clojure-indent '-\u003e 1)\n(put-clojure-indent '-\u003e\u003e 1)\n```\n\nThis means that the body of the `-\u003e/-\u003e\u003e` is after the first argument.\n\nA more compact way to do the same thing is:\n\n```el\n(define-clojure-indent\n  (-\u003e 1)\n  (-\u003e\u003e 1))\n```\n\nTo indent something like a definition (`defn`) you can do something like:\n\n``` el\n(put-clojure-indent '\u003edefn :defn)\n```\n\nYou can also specify different indentation settings for symbols\nprefixed with some ns (or ns alias):\n\n```el\n(put-clojure-indent 'do 0)\n(put-clojure-indent 'my-ns/do 1)\n```\n\nThe bodies of certain more complicated macros and special forms\n(e.g. `letfn`, `deftype`, `extend-protocol`, etc) are indented using\na contextual backtracking indentation method, require more sophisticated\nindent specifications. Here are a few examples:\n\n```el\n(define-clojure-indent\n  (implement '(1 (1)))\n  (letfn     '(1 ((:defn)) nil))\n  (proxy     '(2 nil nil (1)))\n  (reify     '(:defn (1)))\n  (deftype   '(2 nil nil (1)))\n  (defrecord '(2 nil nil (1)))\n  (specify   '(1 (1)))\n  (specify   '(1 (1))))\n```\n\nThese follow the same rules as the `:style/indent` metadata specified by [cider-nrepl][].\nFor instructions on how to write these specifications, see\n[this document](https://docs.cider.mx/cider/indent_spec.html).\nThe only difference is that you're allowed to use lists instead of vectors.\n\nThe indentation of [special arguments](https://docs.cider.mx/cider/indent_spec.html#special-arguments) is controlled by\n`clojure-special-arg-indent-factor`, which by default indents special arguments\na further `lisp-body-indent` when compared to ordinary arguments.\n\nAn example of the default formatting is:\n\n```clojure\n(defrecord MyRecord\n    [my-field])\n```\n\nNote that `defrecord` has two special arguments, followed by the form's body -\nnamely the record's name and its fields vector.\n\nSetting `clojure-special-arg-indent-factor` to 1, results in:\n\n```clojure\n(defrecord MyRecord\n  [my-field])\n```\n\nYou can completely disable the effect of indentation specs like this:\n\n``` el\n(setq clojure-enable-indent-specs nil)\n```\n\n#### Indentation of Comments\n\n`clojure-mode` differentiates between comments like `;`, `;;`, etc.\nBy default `clojure-mode` treats `;` as inline comments and *always* indents those.\nYou can change this behaviour like this:\n\n```emacs-lisp\n(add-hook 'clojure-mode-hook (lambda () (setq-local comment-column 0)))\n```\n\nYou might also want to change `comment-add` to 0 in that way, so that Emacs comment\nfunctions (e.g. `comment-region`) would use `;` by default instead of `;;`.\n\n**Note:** Check out [this section](https://guide.clojure.style/#comments) of the Clojure style guide to understand better the semantics of the different comment levels and why `clojure-mode` treats them differently by default.\n\n### Vertical alignment\n\nYou can vertically align sexps with `C-c SPC`. For instance, typing\nthis combo on the following form:\n\n```clj\n(def my-map\n  {:a-key 1\n   :other-key 2})\n```\n\nLeads to the following:\n\n```clj\n(def my-map\n  {:a-key     1\n   :other-key 2})\n```\n\nThis can also be done automatically (as part of indentation) by\nturning on `clojure-align-forms-automatically`. This way it will\nhappen whenever you select some code and hit `TAB`.\n\n### Font-locking\n\n`clojure-mode` features static font-locking (syntax highlighting) that you can extend yourself\nif needed. As typical for Emacs, it's based on regular expressions. You can find\nthe default font-locking rules in `clojure-font-lock-keywords`. Here's how you can add font-locking for built-in Clojure functions and vars:\n\n``` el\n(defvar clojure-built-in-vars\n  '(;; clojure.core\n    \"accessor\" \"aclone\"\n    \"agent\" \"agent-errors\" \"aget\" \"alength\" \"alias\"\n    \"all-ns\" \"alter\" \"alter-meta!\" \"alter-var-root\" \"amap\"\n    ;; omitted for brevity\n    ))\n\n(defvar clojure-built-in-dynamic-vars\n  '(;; clojure.test\n    \"*initial-report-counters*\" \"*load-tests*\" \"*report-counters*\"\n    \"*stack-trace-depth*\" \"*test-out*\" \"*testing-contexts*\" \"*testing-vars*\"\n    ;; clojure.xml\n    \"*current*\" \"*sb*\" \"*stack*\" \"*state*\"\n    ))\n\n(font-lock-add-keywords 'clojure-mode\n                        `((,(concat \"(\\\\(?:\\.*/\\\\)?\"\n                                    (regexp-opt clojure-built-in-vars t)\n                                    \"\\\\\u003e\")\n                           1 font-lock-builtin-face)))\n\n(font-lock-add-keywords 'clojure-mode\n                        `((,(concat \"\\\\\u003c\"\n                                    (regexp-opt clojure-built-in-dynamic-vars t)\n                                    \"\\\\\u003e\")\n                           0 font-lock-builtin-face)))\n\n```\n\n**Note:** The package `clojure-mode-extra-font-locking` provides such additional\nfont-locking for Clojure built-ins.\n\nAs you might imagine one problem with this font-locking approach is that because\nit's based on regular expressions you'll get some false positives here and there\n(there's no namespace information, and no way for `clojure-mode` to know what\nvar a symbol resolves to). That's why `clojure-mode`'s font-locking defaults are\nconservative and minimalistic.\n\nPrecise font-locking requires additional data that can obtained from a running\nREPL (that's how CIDER's [dynamic font-locking](https://docs.cider.mx/cider/config/syntax_highlighting.html) works) or from static code analysis.\n\nWhen it comes to non built-in definitions, `clojure-mode` needs to be manually instructed how to handle the docstrings and highlighting. Here's an example:\n\n``` emacs-lisp\n(put '\u003edefn 'clojure-doc-string-elt 2)\n\n(font-lock-add-keywords 'clojure-mode\n                        `((,(concat \"(\\\\(?:\" clojure--sym-regexp \"/\\\\)?\"\n                                    \"\\\\(\u003edefn\\\\)\\\\\u003e\")\n                           1 font-lock-keyword-face)))\n```\n\n**Note:** The `clojure-doc-string-elt` attribute is processed by the function `clojure-font-lock-syntactic-face-function`.\n\n## Refactoring support\n\nThe available refactorings were originally created and maintained by the\n`clj-refactor.el` team. The ones implemented in Elisp only are gradually migrated\nto `clojure-mode`.\n\n### Threading macros related features\n\n`clojure-thread`: Thread another form into the surrounding thread. Both `-\u003e\u003e`\nand `-\u003e` variants are supported.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-thread.gif\"\u003e\n\n`clojure-unwind`: Unwind a threaded expression. Supports both `-\u003e\u003e` and `-\u003e`.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-unwind.gif\"\u003e\n\n`clojure-thread-first-all`: Introduce the thread first macro (`-\u003e`) and rewrite\nthe entire form. With a prefix argument do not thread the last form.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-thread-first-all.gif\"\u003e\n\n`clojure-thread-last-all`: Introduce the thread last macro and rewrite the\nentire form. With a prefix argument do not thread the last form.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-thread-last-all.gif\"\u003e\n\n`clojure-unwind-all`: Fully unwind a threaded expression removing the threading\nmacro.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-unwind-all.gif\"\u003e\n\n### Cycling things\n\n`clojure-cycle-privacy`: Cycle privacy of `def`s or `defn`s. Use metadata\nexplicitly with setting `clojure-use-metadata-for-privacy` to `t` for `defn`s\ntoo.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-cycle-privacy.gif\"\u003e\n\n`clojure-cycle-not`: Add or remove a `not` form around the current form.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-cycle-not.gif\"\u003e\n\n`clojure-cycle-when`: Find the closest `when` or `when-not` up the syntax tree\nand toggle it.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-cycle-when.gif\"\u003e\n\n`clojure-cycle-if`: Find the closest `if` or `if-not` up the syntax tree and\ntoggle it. Also transpose the `else` and `then` branches, keeping the semantics\nthe same as before.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-cycle-if.gif\"\u003e\n\n### Convert collection\n\nConvert any given collection at point to list, quoted list, map, vector or set.\n\n### Let expression\n\n`clojure-introduce-let`: Introduce a new `let` form. Put the current form into\nits binding form with a name provided by the user as a bound name. If called\nwith a numeric prefix put the let form Nth level up in the form hierarchy.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-introduce-let.gif\"\u003e\n\n`clojure-move-to-let`: Move the current form to the closest `let`'s binding\nform. Replace all occurrences of the form in the body of the let.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-move-to-let.gif\"\u003e\n\n`clojure-let-forward-slurp-sexp`: Slurp the next form after the `let` into the\n`let`. Replace all occurrences of the bound forms in the form added to the `let`\nform. If called with a prefix argument slurp the next n forms.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-let-forward-slurp-sexp.gif\"\u003e\n\n`clojure-let-backward-slurp-sexp`: Slurp the form before the `let` into the\n`let`. Replace all occurrences of the bound forms in the form added to the `let`\nform. If called with a prefix argument slurp the previous n forms.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-let-backward-slurp-sexp.gif\"\u003e\n\n`paredit-convolute-sexp` is advised to replace occurrences of bound forms with their bound names when convolute is used on a let form.\n\n### Rename ns alias\n\n`clojure-rename-ns-alias`: Rename an alias inside a namespace declaration,\nand all of its usages in the buffer\n\n\u003cimg width=\"512\" src=\"/doc/clojure-rename-ns-alias.gif\"\u003e\n\nIf there is an active selected region, only rename usages of aliases within the region,\nwithout affecting the namespace declaration.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-rename-ns-alias-region.gif\"\u003e\n\n### Add arity to a function\n\n`clojure-add-arity`: Add a new arity to an existing single-arity or multi-arity function.\n\n\u003cimg width=\"512\" src=\"/doc/clojure-add-arity.gif\"\u003e\n\n## Related packages\n\n* [clojure-mode-extra-font-locking][] provides additional font-locking\nfor built-in methods and macros.  The font-locking is pretty\nimprecise, because it doesn't take namespaces into account and it\nwon't font-lock a function at all possible positions in a sexp, but\nif you don't mind its imperfections you can easily enable it:\n\n```el\n(require 'clojure-mode-extra-font-locking)\n```\n\nThe code in `clojure-mode-font-locking` used to be bundled with\n`clojure-mode` before version 3.0.\n\nYou can also use the code in this package as a basis for extending the\nfont-locking further (e.g. functions/macros from more\nnamespaces). Generally you should avoid adding special font-locking\nfor things that don't have fairly unique names, as this will result in\nplenty of incorrect font-locking. CIDER users should avoid this package,\nas CIDER does its own dynamic font-locking, which is namespace-aware\nand doesn't produce almost any false positives.\n\n* [clj-refactor][] provides refactoring support.\n\n* Enabling `CamelCase` support for editing commands(like\n`forward-word`, `backward-word`, etc) in `clojure-mode` is quite\nuseful since we often have to deal with Java class and method\nnames. The built-in Emacs minor mode `subword-mode` provides such\nfunctionality:\n\n```el\n(add-hook 'clojure-mode-hook #'subword-mode)\n```\n\n* The use of [paredit][] when editing Clojure (or any other Lisp) code\nis highly recommended. It helps ensure the structure of your forms is\nnot compromised and offers a number of operations that work on code\nstructure at a higher level than just characters and words. To enable\nit for Clojure buffers:\n\n```el\n(add-hook 'clojure-mode-hook #'paredit-mode)\n```\n\n* [smartparens][] is an excellent\n  (newer) alternative to paredit. Many Clojure hackers have adopted it\n  recently and you might want to give it a try as well. To enable\n  `smartparens` use the following code:\n\n```el\n(add-hook 'clojure-mode-hook #'smartparens-strict-mode)\n```\n\n* [RainbowDelimiters][] is a\n  minor mode which highlights parentheses, brackets, and braces\n  according to their depth. Each successive level is highlighted in a\n  different color. This makes it easy to spot matching delimiters,\n  orient yourself in the code, and tell which statements are at a\n  given depth. Assuming you've already installed `RainbowDelimiters` you can\n  enable it like this:\n\n```el\n(add-hook 'clojure-mode-hook #'rainbow-delimiters-mode)\n```\n\n* [aggressive-indent-mode][] automatically adjust the indentation of your code,\nwhile you're writing it. Using it together with `clojure-mode` is highly\nrecommended. Provided you've already installed `aggressive-indent-mode` you can\nenable it like this:\n\n```el\n(add-hook 'clojure-mode-hook #'aggressive-indent-mode)\n```\n\n## REPL Interaction\n\nOne of the fundamental aspects of Lisps in general, and Clojure in\nparticular, is the notion of interactive programming - building your\nprograms by continuously changing the state of the running Lisp\nprogram (as opposed to doing something more traditional like making a\nchange and re-running the program afterwards to see the changes in\naction). To get the most of clojure-mode you'll have to combine it\nwith some tool which will allow you to interact with your Clojure program\n(a.k.a. process/REPL).\n\nA number of options exist for connecting to a\nrunning Clojure process and evaluating code interactively.\n\n### Basic REPL\n\n[inf-clojure][] provides basic interaction with a Clojure REPL process.\nIt's very similar in nature and supported functionality to `inferior-lisp-mode`\nfor Common Lisp.\n\n### CIDER\n\n[CIDER][] is a powerful Clojure interactive development environment,\nsimilar to SLIME for Common Lisp.\n\nIf you're into Clojure and Emacs you should definitely check it out.\n\n## Tutorials\n\nTutorials,\ntargeting Emacs beginners, are available at\n[clojure-doc.org](https://clojure-doc.org/articles/tutorials/editors/) and\n[Clojure for the Brave and the True](https://www.braveclojure.com/basic-emacs/).\nKeep in mind, however, that they might be out-of-date.\n\n## Caveats\n\n`clojure-mode` is a capable tool, but it's certainly not perfect. This section\nlists a couple of general design problems/limitations that might affect your\nexperience negatively.\n\n### General Issues\n\n`clojure-mode` derives a lot of functionality directly from `lisp-mode` (an Emacs major mode for Common Lisp), which\nsimplified the initial implementation, but also made it harder to implement\ncertain functionality. Down the road it'd be nice to fully decouple `clojure-mode`\nfrom `lisp-mode`.\n\nSee [this ticket](https://github.com/clojure-emacs/clojure-mode/issues/270) for a bit more details.\n\n### Indentation Performance\n\n`clojure-mode`'s indentation engine is a bit slow. You can speed things up significantly by disabling `clojure-use-backtracking-indent`, but this will break the indentation of complex forms like `deftype`, `defprotocol`, `reify`, `letfn`, etc.\n\nWe should look into ways to optimize the performance of the backtracking indentation logic. See [this ticket](https://github.com/clojure-emacs/clojure-mode/issues/606) for more details.\n\n### Font-locking Implementation\n\nAs mentioned [above](https://github.com/clojure-emacs/clojure-mode#font-locking), the font-locking is implemented in terms of regular expressions which makes it both slow and inaccurate.\n\n## Changelog\n\nAn extensive changelog is available [here](CHANGELOG.md).\n\n## License\n\nCopyright © 2007-2024 Jeffrey Chu, Lennart Staflin, Phil Hagelberg, Bozhidar\nBatsov, Artur Malabarba, Magnar Sveen 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]: https://melpa.org/packages/clojure-mode-badge.svg\n[melpa-stable-badge]: https://stable.melpa.org/packages/clojure-mode-badge.svg\n[melpa-package]: https://melpa.org/#/clojure-mode\n[melpa-stable-package]: https://stable.melpa.org/#/clojure-mode\n[COPYING]: https://www.gnu.org/copyleft/gpl.html\n[badge-circleci]: https://circleci.com/gh/clojure-emacs/clojure-mode.svg?style=svg\n[circleci]: https://circleci.com/gh/clojure-emacs/clojure-mode\n[CIDER]: https://github.com/clojure-emacs/cider\n[cider-nrepl]: https://github.com/clojure-emacs/cider-nrepl\n[inf-clojure]: https://github.com/clojure-emacs/inf-clojure\n[contributors]: https://github.com/clojure-emacs/clojure-mode/contributors\n[melpa]: https://melpa.org\n[melpa stable]: https://stable.melpa.org\n[clojure-mode-extra-font-locking]: https://github.com/clojure-emacs/clojure-mode/blob/master/clojure-mode-extra-font-locking.el\n[clj-refactor]: https://github.com/clojure-emacs/clj-refactor.el\n[paredit]: https://mumble.net/~campbell/emacs/paredit.html\n[smartparens]: https://github.com/Fuco1/smartparens\n[RainbowDelimiters]: https://github.com/Fanael/rainbow-delimiters\n[aggressive-indent-mode]: https://github.com/Malabarba/aggressive-indent-mode\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclojure-emacs%2Fclojure-mode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclojure-emacs%2Fclojure-mode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclojure-emacs%2Fclojure-mode/lists"}