Clojure LSP Snippetsλ︎
Custom snippets are defined in the Clojure LSP EDN configuration using the :additional-snipets
key. The snippet body uses the same tab stop and placeholder syntax as Yasnipets, although the body is contained within a string.
Built-in snippets can include Clojure code for generating the text of the snippet when expanded. Custom snippets do not currently support evaluation of code in the snippet.
Clojure LSP Configuration locations
Project specific configuration resides in .lsp/config.edn
User level configuration is either $XDG_CONFIG_HOME/clojure-lsp/config.edn
or $HOME/.clojure-lsp/config
Snippet definitionλ︎
The :additional-snippets
key is associated with a vector or hash-maps, [{}{},,,]
with each hash-map defining a snippet using the keys:
:name
- name of the snippet, typed into the editor for completion
:detail
- a meaningful description of the snippet
:snippet
- the definition of the snippet, with tab stops and current-form syntax
The :snippet
can be any text, ideally with syntax that is correct for the particular language
Snippet Tab Stopsλ︎
Include $
with a number, e.g. $1
,$2
,$3
, to include tab stops in the snippet. Once the snippet code has been generated, TAB
key jumps through the tab stops in sequence, allowing customisation of a generic snippet.
$0
marks the final position of the cursor, after which TAB
has no more positions in the snippet to jump to.
Snippet current-formλ︎
When a Clojure LSP snipped includes $current-form
then typing a snippet name in front of an existing Clojure form includes that form in the generated code.
{:additional-snippets [{:name "wrap-let-sexpr"
:detail "Wrap current sexpr in let"
:snippet "(let [$1 $current-form] $0)"}]}
Limited scope with current-form
A Snippet including $current-form
is only active when typed in front of an existing expression. A snippet is not recognised when typed at the top level.
Placeholdersλ︎
Tab Stops can also include default values or text used as hint on what each tab stop value is for. These are referred to as placeholders.
${1:default-value}
is the form of a placeholder for tab stop 1. When the cursor tabs to tab stop 1, the default-value text is highlighted and replaces as soon as characters are typed.
Placeholder text is not replaced for $0
tab-stop, as the snippet interaction is effectively over at this point.
The deftest
custom snippet shows examples of placeholders for three tab stops.
{:name "deftest"
:detail "deftest clojure.test"
:snippet
"(deftest ${1:name}-test
(testing \"${2:Context of the test assertions}\"
(is (= ${3:assertion-values}))$4))
$0"}
Escape string quotes in snippet body
Use \
character before the "
character within the snippet body. For example, doc-strings in defn
function definitions or the string in testing
function.
Code driven snippetλ︎
The built-in defn
snippet uses Clojure code to help generate the snippet.
%s
is a substitution point within a snippet, used by the standard Clojure format
command, used to included either defn ^:private
or defn-
, depending on the value returned from the if
expression.
:use-metadata-for-privacy?
is a key from the Clojure LSP configuration
{:label "defn-"
:detail "Create private function"
:insert-text (format "(defn%s ${1:name} [$2]\n ${0:body})"
(if (:use-metadata-for-privacy? settings)
" ^:private"
"-"))}
The syntax for built-in snippets is slightly different that the :additional-syntax
form. The internal form uses :label
for :name
and :insert-text
for :snippet
.
Code supported only in built-in snippets
Clojure code only works for built-in snippets and not for :additional-snippets
.
Clojure LSP is compiled by Graal to a native binary, including the built-in snippets. To include Clojure code in a snippet then consider submitting a pull request to the Clojure LSP project to add a built-in snippet.