Liking cljdoc? Tell your friends :D

Features

Above you can find all available features that clojure-lsp provides with examples using Emacs lsp-mode as the client.

Find a function/var definition

Find defprotocol/defmulti implementations

Find a function/var declaration in the ns

Find all references of a function, var, keyword or namespace alias

Show all workspace/project symbols

Show all symbols on current file

Rename symbols

Also, it's possible to live rename symbols on the same buffer with linkedEditingRange feature.

Document highlight on hover showing symbol usages

Documentation and clojuredocs integration

Completion

Snippets

Snippets are templates that make it easier to enter repeating code patterns, such as common functions/forms, they are available during completion. Tabstops are defined as $number with $0 as last tabstop.

Check all available snippets here
namedescriptionraw content
commentInsert comment block(comment\n ${0:body}\n )
comment-headingInsert comment Header;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; ${1:Namespace summary title}\n;;\n;; ${2:Brief description}\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n$0
comment-separatorInsert comment separator ;; ${1:Namespace summary title}\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n$0
rich-commentInsert rich comment (comment $0 #_())
rich-comment-rddInsert rich comment rdd block #_{:clj-kondo/ignore [:redefined-var]}\n(comment\n $0 #_())
rich-comment-hotloadInsert rich comment library hotload #_{:clj-kondo/ignore [:redefined-var]}\n(comment\n ;; Add-lib library for hot-loading\n (require '[clojure.tools.deps.alpha.repl :refer [add-libs]])\n (add-libs '{${1:domain/library-name} {:mvn/version \"${2:1.0.0}\"}$3})\n $0\n)
condpInsert condp(condp ${1:pred} ${2:expr}\n $0)
defInsert def(def ${1:name} $0)
def-Insert def private(def ^:private ${1:name} $0)
def-docInsert def with docstring(def ${1:name}\n \"${2:docstring}\"\n $0)
defmethodInsert defmethod(defmethod ${1:name} ${2:match}\n [${3:args}]\n $0)
defmultiInsert defmulti(defmulti ${1:name} ${2:dispatch-fn})
defnInsert public defn(defn ${1:name} [$2]\n $0)
defn-docInsert public defn with docstring(defn ${1:name}\n \"${2:docstring}\"\n [${3:args}]\n $0)
defn-Insert private defn(defn%s ${1:name} [$2]\n $0)
defprotocolInsert defprotocol(defprotocol ${1:Name}\n $0)
defrecordInsert defrecord(defrecord ${1:Name} [${2:fields}]\n ${3:Protocol}\n $0)
deftypeInsert deftype(deftype ${1:Name} [${2:fields}]\n ${3:Protocol}\n $0)
fnInsert fn(fn [${1:arg-list}] $0)
forInsert for(for [${1:item} ${2:coll}]\n $0)
ifInsert if(if ${1:test-expr}\n ${2:then-expr}\n ${3:else-expr})
kwargsInsert keyword args{:keys [${1:keys}] :or {${2:defaults}}}
letInsert let(let [$0])
letfnInsert letfn(letfn [(${1:name} [${2:args}]\n $0)])
nsInsert ns(ns ${1:name}\n $0:references})
ns-docInsert ns with docstring(ns ${1:name}\n \"${2:docstring}\"\n ${0:references})
requireInsert ns :require(:require [${1:namespace}])$0
require-asInsert ns require with :as alias(:require [${1:namespace} :as ${2:alias}]$3)
require-referInsert ns :require with :refer(:require [${1:namespace} :refer [$2]]$3)
require-rddInsert require for rich comment experiments(require '[${1:namespace} :as ${2:alias}]$3)$0
req-asInsert single require dep :as alias[${1:namespace} :as ${2:alias}]
req-referInsert single require dep with :refer[${1:namespace} :refer [$2]]
importInsert import(:import [${1:package}])
useInsert require refer preferred over use(:require [${1:namespace} :refer [$2]])
deps-aliasInsert alias with extra path & deps :${1:category/name}\n {:extra-paths [\"${2:path}\"]\n :extra-deps {${3:deps-maven or deps-git}}}$0
deps-mavenInsert maven dependency${1:domain/library-name} {:mvn/version \"${2:1.0.0}\"}$0
deps-gitInsert git dependency ${1:domain/library-name}\n {:git/sha \"${2:git-sha-value}\"}$0
deps-git-tagInsert git tag dependency ${1:domain/library-name}\n {:git/tag \"${2:git-tag-value}\"\n :git/sha \"${3:git-sha-value}\"}$0
deps-git-urlInsert git URL dependency ${1:domain/library-name}\n {:git/url \"https://github.com/$1\"\n :git/sha \"${2:git-sha-value}\"}$0
deps-localInsert local dependency ${1:domain/library-name} {:local/root \"${2:/path/to/project/root}\"}$0
deftestInsert deftest clojure.test (deftest ${1:name}-test\n (testing \"${2:Context of the test assertions}\"\n (is (= ${3:assertion-values}))$4)) $0
testingInsert testing clojure.test (testing \"${1:Context of the test assertions}\"\n $0)
isInsert is clojure.test(is (= ${1:assertion-values}))
Custom snippets

User can register additional custom snippets, for more information on how to configure it, check the snippets settings section.

Code actions

NameExample
Clean namespace require/imports
Add require
Add known common require
Add known common import
Add suggested alias require
Create private function
Resolve macro as...
Inline symbol
Change coll to map,vector,set,list
Move coll entry up/down
Move to let
Cycle privacy
Cycle fn literal
Extract function
Thread first/all last
Unwind thread
Sort map
Suppress diagnostic
Create test for function

Code lenses showing symbol references

Format a whole file or range

Signature help

Semantic tokens

The LSP server is the best to say what is the semantic value of a token on the editor, semantic tokens allows server return to client all tokens of a buffer and how client show apply highlight.

Note: server return the semantic token (e.g. function) and the client/editor apply the color that matches the user's theme.

Call hierarchy

Show the incoming or outgoing call hierarchy of a function/variable as a lazy tree

Incoming

Show functions that call the current one recursively

Outgoing

Show functions that the current one call, recursively

Test Tree

Show the tests tree hierarchy of a file

Diagnostics (linter)

All linters besides the ones below come from clj-kondo that clojure-lsp calls under the hood to lint the code and retrieve the analysis to make most of features work.

Every linter configuration should be done on clj-kondo side, so anything related to unresolved symbols or unknown macros are probably related to wrong clj-kondo for the project. For more information on how to configure clj-kondo check here.

Below you can find the custom linters implemented on clojure-lsp side that uses the :custom-lint-fn from clj-kondo:

clojure-lsp/unused-public-var

For more information on how to configure it, check the diagnostics settings section.

Stub generation

It's possible to configure clojure-lsp to generate and analyze stubs for specific namespaces available on your project classpath, this is useful for closed source dependencies like datomic.api, with that clojure-lsp will be able to make most features work with those dependencies. For more information check the stubs settings section.

Execute command

Commands that client can request. Most code actions use these commands as actions.

Refactoring

Commands that change/refactor the code. See above for screenshots.

Note: Most of them are available via code actions and most of the time you want to call the code action and not the command manually

  • Clean namespace *
  • Add import to namespace
  • Add missing require *
  • Cycle privacy of def/defn *
  • Cycle fn literal (fn []), #() *
  • Cycle collection (#{}, {}, [], ())
  • Change collection to {}, (), #{}, [] *
  • Extract Function *
  • Create private function *
  • Inline Symbol *
  • Expand let
  • Introduce let
  • Move expression to let
  • Thread first expression
  • Thread last expression
  • Thread first all *
  • Thread last all *
  • Unwind all *
  • Unwind thread
  • Resolve macro as *
  • Create test *
  • Sort map *
  • Move coll entry up *
  • Move coll entry down *

Dev

Server information

Return basic information about the server.

Cursor information

Return debug information about the element at point.

Can you improve this documentation? These fine people already did:
Eric Dallo & Jacob Maine
Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close