This package makes use of clj-kondo's analysis data to provide code editing facilities related to Clojure, ClojureScript and cljc source. This means you get advanced editing features like auto-complete without the need for a connected REPL, because clj-kondo performs its magic using static source code analysis.
Current Features:
It gives you contextual auto-completion using completion-at-point, which works without a REPL connected, since it relies on clj-kondo's static source analysis. It will list out all available Vars, Ns and Aliases in a given buffer.
It can also perform locals completion, using an Emacs implemented heuristic completion based on dabbrev that works really well in practice and can handle unbalanced code.
It can also complete Java classes and their static methods and fields. It does so by relying on jar and javap JDK command line binaries.
It supports the notion of projects, using projectile or clojure-mode and Clojure's tools.deps. This means it'll pick up the buffer's current project root using projectile or clojure-mode, and it will use Clojure's tools.deps to get the project's classpath. If it can't find either, it'll only auto-complete within the buffer, it won't be able to show candidates from the required dependencies.
Screenshots
Clojure completion of namespaces and global Vars and fns without needing to be connected to a REPL:
[[./screenshots/anakondo-auto-completion-no-repl-demo.gif]]
Clojure completion of local bindings without needing to be connected to a REPL, which works even with unbalanced expressions:
[[./screenshots/anakondo-locals-auto-completion-no-repl-demo.gif]]
Java completion of qualified classes, default Java class imports (like Math, Thread, Integer, etc.), and of public static methods and fields, all without needing to be connected to a REPL:
[[./screenshots/anakondo-java-auto-completion-no-repl-demo.gif]]
Contents :noexport: :PROPERTIES: :TOC: :include siblings :END: :CONTENTS:
[[#installation][Installation]]
[[#usage][Usage]]
[[#changelog][Changelog]]
[[#roadmap][Roadmap]]
[[#credits][Credits]]
[[#license][License]] :END:
Installation :PROPERTIES: :TOC: :depth 0 :END:
** Prerequisites
For Clojure[Script] completion, Anakondo needs the Clojure CLI tools.deps and clj-kondo to be installed and accessible from Emacs in order to run properly. To do so:
For Java completion, you also need to be sure that you have a JDK installed and that its ~/bin~ folder is on the environment PATH used by Emacs.
** MELPA
;; Load anakondo to make available its minor mode in clojure buffers (require 'anakondo)
;; Delays loading of anakondo until a clojure buffer is used (autoload 'anakondo-minor-mode "anakondo")
** use-package
Put this in your in your init file:
(use-package anakondo :ensure t :commands anakondo-minor-mode)
** Manual
;; Load anakondo to make available its minor mode in clojure buffers (require 'anakondo)
;; Delays loading of anakondo until a clojure buffer is used (autoload 'anakondo-minor-mode "anakondo")
Turn on anakondo minor mode in one or more Clojure, ClojureScript or cljc buffer:
Run one of these commands:
To have it on by default for all your Clojure, ClojureScript and cljc buffers, add to your Emacs init file, after the anakondo require/autoload:
;; Enable anakondo-minor-mode in all Clojure buffers (add-hook 'clojure-mode-hook #'anakondo-minor-mode) ;; Enable anakondo-minor-mode in all ClojureScript buffers (add-hook 'clojurescript-mode-hook #'anakondo-minor-mode) ;; Enable anakondo-minor-mode in all cljc buffers (add-hook 'clojurec-mode-hook #'anakondo-minor-mode)
If you are also using Cider, the order in which you add the hooks matters in the resulting completion behavior:
Currently, I recommend adding anakondo after Cider. This will make it so when no REPL is connected, you have anakondo's clj-kondo based static analysis completion. While when a REPL is running, you have Cider's completion. If you do it the other way around, when a REPL is running, if anakondo find completions you will only see the ones it found. I'll be exploring options to have the completions merged in the future, so we get the best of both worlds.
This also goes if you turn on/off the modes manually, except in that case, order and effect are reversed. The last mode you turn on will be the one who is in charge of completion first. While with the hooks, it is the first mode you add to the hook that will be in charge of completion first.
** Tips
When you first turn on the minor mode, it will do an initial analysis of the full project associated with your buffer with the classpath as defined by =tools.deps=. This can take a few seconds. This will happen for every project you turn on the mode in a buffer for, but won't happen again when turning on the mode in another buffer in the same project.
If you change your =deps.edn=, or feel the completion is looking out of sync, you can force refresh the cache of the project analysis by running: =M-x anakondo-refresh-project-cache= command.
If dependency completion isn't working, remember that =anakondo= only supports =tools.deps= for now, if you don't have a =deps.edn= for your project, it will pick up your global =deps.edn= instead, it won't use your lein =project.clj= or boot =build.boot= dependencies.
If you've disabled cider-mode, and somehow anakondo completion stopped working, this is because of a known bug in cider-mode, which removes all configured completion for the buffer, not just its own, I am trying to get this fixed in cider as well.
If you've killed the REPL, and somehow anakondo completion doesn't seem to be starting back up, this is also due to a bug in cider, where it deletes all configured completion for the buffer on repl quit. I am trying to get this fixed in cider as well.
For Java completions of the default imports, they are going to be the ones defined by Clojure 1.10. So if you use an older or newer version of Clojure, you'll still see the completion of the imports from Clojure 1.10. So don't take it as a source of truth.
The list of Java classes you get completed comes from the boot classpath specified by the =java= command which is on your environment PATH, and the Java dependencies defined in your project's deps.edn. So if you use Java 8, you will see the Java 8 standard classes, if you use Java 11, you will see Java 11's standard classes, etc.
Only Java classes coming from a Jar on your boot classpath and classpath will be completed. If you have =.class= files in your boot classpath or classpath they will not be completed for now. So if you depend on Java dependencies, make sure it is through a Jar, and not a folder containing =.class= files if you want completion for them.
To auto-complete the static methods and fields of a Java class, type =/= after the class and call your completion function, such as completion-at-point or company-indent-or-complete-common, etc.
Java static methods and fields completion doesn't work with custom imports for now, only fully qualified and default imports will get completion.
Changelog :PROPERTIES: :TOC: :depth 0 :END:
** 0.2.1
Changes
Fixes
** 0.2
Additions
Changes
Fixes
Internal
** 0.1.2
Internal
** 0.1.1
Fixes
** 0.1
Additions
Internal
Clj-kondo analysis is now cached for better performance
Project level analysis done synchronously once on mode enter and cached for later use
Uses projectile to find the project root
Uses tools.deps to find the classpath for project root
On completion, re-analyses the current buffer and updates cache
Handles finding the symbol to complete even in complex forms like =~sym=, =~@sym=, =@sym=, ='sym=, =`sym=, etc.
Roadmap
Planned Features
Have it so completion results are merged with those of Cider's if it is present
Make project analysis async, so it runs in the background and doesn't block Emacs
Have project analysis refresh automatically every X seconds in the background
Have project analysis refresh automatically on file watch of deps.edn
Add support for lein projects
Add support for boot projects
Add auto-installer for clj-kondo on mode enter, if it is missing from path
Add command to update clj-kondo, possibly have it run on mode-enter as well (if it was auto-installed by mode)
Add support for jump to definition
Add support for jump/list vars in buffer
Add support for find var usages
Add support for showing fn/macro available signature (of various arities)
Add support for showing doc-string (maybe with eldoc)
Add support for rename refactoring
Add support for clj-kondo driven font-lock
Add support for completing keywords : pending [[https://github.com/borkdude/clj-kondo/issues/855][clj-kondo-855]]
Add support for completing refered vars : pending [[https://github.com/borkdude/clj-kondo/issues/856][clj-kondo-856]]
Add support for completing Java non-static methods and fields
Add support for completing Java inner classes, with their possible static and non-static methods and fields
Add support for completing Java imported classes, using class name only
Credits
This package would not have been possible without the following packages:
Thanks to all of them and their author/contributors.
MIT License, see accompanying [[https://github.com/didibus/anakondo/blob/master/LICENSE][LICENSE]] file.