Hi everyone I'm running into a persistent formatting issue with Calva on VSCode (macOS) that I haven't been able to resolve, despite trying multiple configurations. I’m hoping someone can spot what I’m missing or confirm a working setup. I want Calva to apply the same formatting as the cljfmt CLI, using a custom cljfmt.edn file in my project root — especially for :extra-indents used with some custom macros (like m/sp, m/via, etc.). # Currently: Running clojure -M:cljfmt fix works as expected. Pressing TAB or CMD+S in Calva update well default formating but not custom macros. it seems to ignore my cljfmt.edn. This is my cljfmt.edn:
clojure
{:remove-multiple-non-indenting-spaces? true
:indent-line-comments? true
:remove-trailing-whitespace? true
:sort-ns-references? true
:extra-indents {>defn [[:inner 0]]
loop-iter! [[:inner 0]]
sp-let [[:inner 0]]
missionary.core/via [[:block 1]]
missionary.core/sp [[:block 0]]}}
My deps.edn includes:
:cljfmt {:extra-deps {dev.weavejester/cljfmt {:mvn/version "0.13.1"}}
:main-opts ["-m" "cljfmt.main"]}
Running clojure -M:cljfmt --config cljfmt.edn fix src/test_calva_format/core.clj gives the correct formatting.
# What I’ve tried in VSCode:
I tried those configurations in .vscode/settings.json:
## Specify config path, with newIndentEngine:
{
"editor.formatOnSave": true,
"calva.fmt.configPath": "cljfmt.edn",
"calva.fmt.newIndentEngine": true
}
## Via clojure-lsp, last version:
First I created .lsp/config.edn with:
{:cljfmt-config-path "cljfmt.edn"}
Then tested:
{
"[clojure]": {
"editor.formatOnSave": true,
"editor.formatOnType": true
},
"calva.clojureLspVersion": "nightly",
"calva.fmt.configPath": "CLOJURE-LSP"
}
And:
{
"editor.formatOnSave": true,
"calva.fmt.configPath": "CLOJURE-LSP",
"calva.enableClojureLspOnStart": "always"
}
I tested also without option, as Calva is supposed to detect cljfmt.edn:
{
"editor.formatOnSave": true
}
cljfmt.edn is in the root.
For each config, I confirmed that CMD+S or TAB triggers Calva formatting, but it doesn't follow :extra-indents while CLI is doing it well.
# Folder structure
test-calva-format/
├── .lsp/
│ └── config.edn
├── .vscode/
│ └── settings.json
├── cljfmt.edn
├── deps.edn
├── src/
│ └── test_calva_format/
│ └── core.clj
└── README.md
# What else I’ve tested
• Applied same user settings than workspace ones.
• Explicit absolute path for calva.fmt.configPath → no change.
• Verified that Calva version is 2.0.523.
• Tried enabling/disabling calva.fmt.newIndentEngine (doesn’t seem to affect).
Can you help me to find a configuration ensuring Calva uses my custom cljfmt.edn, and applies the same formatting as the CLI? I would prefer using clojure-lsp way to be iso in usage with Emacs users.
The test repository is here:
https://github.com/patinside/clojure-format-calva-testIt could be that Calva doesn’t handle some of the symbols in the extra-indents map. Try with something really simple there and see if you can get Calva to honor that.
Hum, interesting. when specifying m/via instead of missionary.core/via , I get what I expect regarding the via macro.
What do you recommend? to only use the aliases in the cljfmt.edn? or both?
Also I noticed a difference of behaviour between CMD-S and TAB :
CMD-S
(defn via-fn
[req]
(m/via m/blk
(let [deps (req :deps)]
(+ 1 1))))
TAB:
(defn via-fn
[req]
(m/via m/blk
(let [deps (req :deps)]
(+ 1 1))))
And last question: what is the minimal settings.json vscodeconfiguration recommended to work with clojure-lsp?I don’t understand that last question. No settings.json is needed to work with clojure-lsp. It’s only needed if you are not happy with some default.
As for the difference between saving and formatting the current form. Do you have format-on-save enabled?
I mean for the formating:
Is "calva.fmt.configPath": "CLOJURE-LSP" enough?
> As for the difference between saving and formatting the current form. Do you have format-on-save enabled? Yes
I noticed format-on-save formating is not working well.
> Is "calva.fmt.configPath": "CLOJURE-LSP" enough?
It’s enough for telling Calva to ask clojure-lsp to provide the config.
Do you have any special reason for going via clojure-lsp for this?
Just want to be as close as possible to team members using emacs.
It adds layers to the configuration. Anyway, with that setting, to see what Calva is fed use the command for printing out the clojure-lsp config and check the cljfmt entry.
Seems good:
"cljfmt-raw": "{:remove-multiple-non-indenting-spaces? true, :indent-line-comments? true, :remove-trailing-whitespace? true, :sort-ns-references? true, :extra-indents {>defn [[:inner 0]], loop-iter! [[:inner 0]], sp-let [[:inner 0]], missionary.core/via [[:block 1]], missionary.core/sp [[:block 0]], m/via [[:block 1]], m/sp [[:block 0]]}}"
}Yeah, but also seems like it doesn’t bring anything to the table. 😃
What do you mean? 😅
While figuring things out, at least, it is much more convenient to let Calva use the file directly. Then you can experiment in the cljfmt.edn file directlty, relying on Calva to hot reload it.
ok, I will try access directly to cljfmt.edn. And what about "calva.fmt.newIndentEngine" ?
Indenting and formatting are different things in Calva. (And generally different things in VS Code too.) So indenting is only happening when you insert a new line in the editor, generally informing VS Code where the cursor should go. The legacy indent engine used cljfmt for this. The new engine is custom Calva code, but we use the cljfmt config.
As far as troubleshooting formatting goes, it doesn’t matter what indent engine you use. But generally the new engine is the default for reasons.
I’m a bit confused why format on save misbehaves. In theory it should work better with aliases since then cljfmt has the full file.
{:remove-multiple-non-indenting-spaces? true
:indent-line-comments? true
:remove-trailing-whitespace? true
:sort-ns-references? true
:extra-indents {>defn [[:inner 0]]
loop-iter! [[:inner 0]]
sp-let [[:inner 0]]
missionary.core/via [[:block 1]]
missionary.core/sp [[:block 0]]
m/via [[:block 1]]
m/sp [[:block 0]]}}
this is after format-on-save
and when TAB, everything is great.
I’m starting to think that you are running into bugs in Calva. I will try to look at it later with your config examples.
I will use tab for the moment. Thanks for you help.
I have never used format-on-save so may have dropped some balls there…