Typed Clojure in your editor over LSP. This project is still very fresh, feedback is greatly appreciated.
Please let me know your setup (text editor, Clojure toolchain) and your experience. If you get this working in an editor and there's no documentation for it yet, please feel free to open a PR adding your notes to the README.
The project currently depends on Typed Clojure 1.3.1-SNAPSHOT
, it also includes the malli bridge and the clojure.core
types. The latest Typed Clojure requires a metadata tag on your namespace as shown in this example (which also demonstrates the malli integration).
;; This ^:typed.clojure keyword is required!
(ns ^:typed.clojure examples.core
(:require [malli.experimental :as mx]))
(mx/defn add :- number?
"If you have LSP configured correctly you should see a type error / warning if you try to type (add :foo 10) inside this buffer."
[a :- number?
b :- number?]
(+ a b))
(mx/defn a-bad-fn :- number? []
(add :foo 10)) ;; => Function add could not be applied to arguments... [would appear in your editor]
We configure our editor to attempt to invoke a known script in each directory when we open a Clojure project file. This gives us the flexibility to configure how the LSP server starts and which version we use per-project. First we'll get our editor invoking the script, then we can fill the script out in our project depending on the tooling it relies on.
If you're using nfnl or a similar Fennel compiler system you can paste the following into ~/.config/nvim/lsp/typedclojure.fnl
. As long as you're calling vim.lsp.enable
somewhere with "typedclojure"
as an argument, everything should work automatically when you open a Clojure file.
{:cmd [".typedclojure-lsp/start"]
:filetypes ["clojure"]
:root_markers ["deps.edn" "project.clj" ".git"]}
Identical to the Fennel solution above, but you paste this Lua into ~/.config/nvim/lsp/typedclojure.lua
.
return {
cmd = {".typedclojure-lsp/start"},
filetypes = {"clojure"},
root_markers = {"deps.edn", "project.clj", ".git"}
}
Once your editor is configured to invoke this script, you can add different scripts to your project depending on your tooling choices or special requirements. You might have one per project that your team share or maybe keep them entirely private if you have differing OS needs. Maybe have a shared core script that invokes a sub-script that each of your team members can customise. The possibilities are endless and dictated by each of your projects.
Here's some starting points for different situations, please feel free to add more here if you work out how to get this working under different tooling.
tools.cli
deps.edn
{:deps
{org.clojure/clojure {:mvn/version "..."}
:aliases
{:typedclojure-lsp {:extra-deps {uk.me.oli/typedclojure-lsp {:mvn/version "${VERSION (see clojars badge)}"}}
:main-opts ["-m" "typedclojure-lsp.main"]}}}}
.typedclojure-lsp/start
#!/usr/bin/env bash
clojure -M:typedclojure-lsp
project.clj
(defproject demo "0.1.0-SNAPSHOT"
:dependencies []
:profiles
{:typedclojure-lsp {:dependencies [[uk.me.oli/typedclojure-lsp "${VERSION (see clojars badge)}"]]}}
:aliases
{"typedclojure-lsp" ["with-profile" "+typedclojure-lsp" "run" "-m" "typedclojure-lsp.main/start!"]})
.typedclojure-lsp/start
#!/usr/bin/env bash
lein typedclojure-lsp
Logs are written to stderr and should be visible within your LSP client (text editor) somewhere. In Neovim you can see them in :LspLog
, in VS Code you can view them under View > Output > Select typedclojure-lsp from the list
.
When working on the project I use "clojure" "-X:typedclojure-lsp:test:dev" "typedclojure-lsp.dev/start!"
as my cmd
in my LSP configuration. This starts up the server with an nREPL that Conjure will automatically connect to giving me a tight feedback loop.
You can reach me through issues and discussions on this repo, I highly encourage feedback, good or bad. Alternatively you can reach me on Mastodon or the Conjure Discord. Sometimes I write things on oli.me.uk.
Find the full unlicense in the UNLICENSE
file, but here's a snippet.
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close