Skip to content

Commit 9292668

Browse files
committed
formatting: add support for JuliaFormatter
This commit extends the formatting system to support multiple formatter backends beyond Runic.jl. Users can now choose between preset formatters ("Runic" or "JuliaFormatter") or configure custom formatters with their own executables. The formatter configuration has been redesigned from a nested structure (`formatter.runic.executable`) to a simpler top-level `formatter` setting that accepts either: - A preset name string: "Runic" or "JuliaFormatter" - A custom formatter defined under `formatter.custom` with `executable` and optional `executable_range` fields The preset names use proper package names for clarity, while executables remain as `runic`/`jlfmt` to match the actual binary names. Due to limitations in Configurations.jl, custom formatters must be specified in the `[formatter.custom]` section rather than directly as the `formatter` value. Custom formatters can specify separate executables for document and range formatting operations. Additionally, `FormattingOptions` from LSP requests are now propagated through the formatting pipeline, enabling formatters to respect client-provided settings like tab size. For JuliaFormatter, the tab size option is passed via the `--indent` flag. This client-wise setting will be overwritten by .JuliaFormatter.toml configuration if it's found since we are using the `--prioritize-config-file` option. Requires domluna/JuliaFormatter.jl#947 to be merged.
1 parent 4804031 commit 9292668

File tree

5 files changed

+342
-79
lines changed

5 files changed

+342
-79
lines changed

README.md

Lines changed: 123 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,8 @@ the list itself is subject to change.
240240
- [ ] Type of local binding on hover
241241
- Formatting
242242
- [x] [Runic](https://github.com/fredrikekre/Runic.jl) integration
243-
- [ ] [JuliaFormatter](https://github.com/domluna/JuliaFormatter.jl) integration
244-
- [ ] Make formatting backend configurable
243+
- [x] [JuliaFormatter](https://github.com/domluna/JuliaFormatter.jl) integration
244+
- [x] Make formatting backend configurable
245245
- Rename
246246
- [x] Local binding
247247
- [ ] Global binding
@@ -311,22 +311,32 @@ executable = "/custom/path/to/testrunner"
311311

312312
See [TestRunner integration](#testrunner-integration) for setup instructions.
313313

314-
#### `[formatter.runic] executable`
314+
#### `formatter`
315315

316-
- Type: string (path)
317-
- Default: `"runic"` (or `"runic.bat"` on Windows)
316+
- Type: string or table
317+
- Default: `"Runic"`
318318

319-
Path to the [Runic](https://github.com/fredrikekre/Runic.jl) formatter
320-
executable. If not specified, JETLS looks for `runic` in your `PATH` (typically
321-
`~/.julia/bin/runic`). Used for document formatting (triggered via editor
322-
format command).
319+
Configures the formatter backend for document and range formatting. Accepts
320+
either a preset formatter name or a custom formatter configuration.
323321

324-
Example:
322+
Preset options:
323+
- `"Runic"` (default): Uses [Runic.jl](https://github.com/fredrikekre/Runic.jl)
324+
- `"JuliaFormatter"`: Uses [JuliaFormatter.jl](https://github.com/domluna/JuliaFormatter.jl)
325+
326+
Examples:
325327
```toml
326-
[formatter.runic]
327-
executable = "/custom/path/to/runic"
328+
# Use JuliaFormatter preset
329+
formatter = "JuliaFormatter"
330+
331+
# Or use custom formatter (both fields optional)
332+
[formatter.custom]
333+
executable = "/path/to/custom-formatter"
334+
executable_range = "/path/to/custom-range-formatter"
328335
```
329336

337+
See [Formatting](#formatting) for detailed configuration instructions and setup
338+
requirements.
339+
330340
### How to configure
331341

332342
#### Method 1: Project-specific configuration file
@@ -343,6 +353,9 @@ debounce = 2.0
343353

344354
[testrunner]
345355
executable = "/custom/path/to/testrunner"
356+
357+
# Use JuliaFormatter instead of Runic
358+
formatter = "JuliaFormatter"
346359
```
347360

348361
#### Method 2: Editor configuration via LSP
@@ -353,7 +366,7 @@ As examples, we show the configuration methods for the VSCode extension `jetls-c
353366
and the Zed extension [`aviatesk/zed-julia#avi/JETLS`](https://github.com/aviatesk/zed-julia/tree/avi/JETLS).
354367

355368
##### VSCode (`jetls-client` extension)
356-
Configure JETLS in Zed's settings.json file with `jetls-client.jetlsSettings` section:
369+
Configure JETLS in VSCode's settings.json file with `jetls-client.jetlsSettings` section:
357370
```jsonc
358371
{
359372
"jetls-client.jetlsSettings": {
@@ -362,7 +375,8 @@ Configure JETLS in Zed's settings.json file with `jetls-client.jetlsSettings` se
362375
},
363376
"testrunner": {
364377
"executable": "/custom/path/to/testrunner"
365-
}
378+
},
379+
"formatter": "JuliaFormatter"
366380
}
367381
}
368382
```
@@ -387,7 +401,8 @@ Configure JETLS in Zed's settings.json file with the `lsp.JETLS.settings` sectio
387401
},
388402
"testrunner": {
389403
"executable": "/custom/path/to/testrunner"
390-
}
404+
},
405+
"formatter": "JuliaFormatter"
391406
}
392407
}
393408
}
@@ -407,6 +422,99 @@ The `.JETLSConfig.toml` file takes precedence, since it provides a
407422
**client-agnostic** way to configure JETLS that works consistently across
408423
all editors.
409424

425+
## Formatting
426+
427+
JETLS provides document formatting support through integration with external
428+
formatting tools. By default, [Runic.jl](https://github.com/fredrikekre/Runic.jl)
429+
is used, but you can configure alternative formatters or use custom formatting
430+
executables.
431+
432+
### Features
433+
434+
- **Document formatting**: Format entire Julia files
435+
- **Range formatting**: Format selected code regions (Runic and custom
436+
formatters only)
437+
- **Progress notifications**: Visual feedback during formatting operations
438+
for clients that support work done progress
439+
440+
### Prerequisites
441+
442+
JETLS supports preset formatters as well as custom formatting executables.
443+
For preset formatters, install your preferred formatter and ensure it's
444+
available in your system `PATH`:
445+
- [Runic](https://github.com/fredrikekre/Runic.jl) (default):
446+
```bash
447+
julia -e 'using Pkg; Pkg.Apps.add("Runic")'
448+
```
449+
- [JuliaFormatter](https://github.com/domluna/JuliaFormatter.jl):
450+
```bash
451+
julia -e 'using Pkg; Pkg.Apps.add("JuliaFormatter")'
452+
```
453+
454+
Note that you need to manually make `~/.julia/bin` available on the `PATH`
455+
environment for the formatter executables to be accessible.
456+
See <https://pkgdocs.julialang.org/dev/apps/> for the details.
457+
458+
For custom formatters, no installation is required—simply configure the path
459+
to your executable in `.JETLSConfig.toml` (see the [custom formatter](#custom-formatter) section below).
460+
461+
### Configuration
462+
463+
Create a `.JETLSConfig.toml` file in your project root to configure the
464+
formatter. The configuration supports three options:
465+
466+
#### Preset: [Runic](https://github.com/fredrikekre/Runic.jl) (default)
467+
468+
```toml
469+
formatter = "Runic"
470+
```
471+
472+
This is the default setting and doesn't require explicit configuration.
473+
Runic supports both document and range formatting.
474+
475+
#### Preset: [JuliaFormatter](https://github.com/domluna/JuliaFormatter.jl)
476+
477+
```toml
478+
formatter = "JuliaFormatter"
479+
```
480+
481+
If a [`.JuliaFormatter.toml` configuration](https://domluna.github.io/JuliaFormatter.jl/dev/config/)
482+
file is found in your project, JuliaFormatter will use those settings.
483+
Otherwise, it uses default settings with formatting options provided by the
484+
editor client (such as tab size) when available.
485+
486+
> [!WARNING]
487+
> Note that JuliaFormatter currently, as of v2.2.0, only supports full document
488+
> formatting, not range formatting.
489+
490+
#### Custom formatter
491+
492+
```toml
493+
[formatter.custom]
494+
executable = "/path/to/custom-formatter"
495+
executable_range = "/path/to/custom-range-formatter"
496+
```
497+
498+
Custom formatters should accept Julia code via stdin and output formatted
499+
code to stdout, following the same interface as `runic`:
500+
- `executable`: Command for full document formatting. The formatter should
501+
read the entire Julia source code from stdin, format it completely, and
502+
write the formatted result to stdout. The exit code should be 0 on success.
503+
- `executable_range`: Command for range formatting. The formatter should
504+
accept a `--lines=START:END` argument to format only the specified line
505+
range. It should read the entire document code from stdin and write the
506+
_entire document code_ to stdout with only the specified region formatted.
507+
The rest of the document must remain unchanged.
508+
509+
### Troubleshooting
510+
511+
If you see an error about the formatter not being found:
512+
1. Ensure you've installed the formatter as described above
513+
2. Check that the formatter executable is in your system PATH by running
514+
`which runic` or `which jlfmt`
515+
3. For custom formatters, verify the executable path in `.JETLSConfig.toml`
516+
4. Restart your editor to ensure it picks up the updated PATH or configuration
517+
410518
## TestRunner integration
411519

412520
JETLS integrates with [TestRunner.jl](https://github.com/aviatesk/TestRunner.jl)

package.json

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,19 +108,37 @@
108108
}
109109
},
110110
"formatter": {
111-
"type": "object",
112-
"properties": {
113-
"runic": {
111+
"oneOf": [
112+
{
113+
"type": "string",
114+
"enum": [
115+
"Runic",
116+
"JuliaFormatter"
117+
],
118+
"default": "Runic",
119+
"description": "Preset formatter to use. 'Runic' (default) or 'JuliaFormatter'."
120+
},
121+
{
114122
"type": "object",
115123
"properties": {
116-
"executable": {
117-
"type": "string",
118-
"default": "",
119-
"description": "Path to the Runic formatter executable. If empty, uses 'runic' from PATH."
124+
"custom": {
125+
"type": "object",
126+
"properties": {
127+
"executable": {
128+
"type": "string",
129+
"description": "Path to custom formatter executable for document formatting. The formatter should read Julia code from stdin and output formatted code to stdout. Optional."
130+
},
131+
"executable_range": {
132+
"type": "string",
133+
"description": "Path to custom formatter executable for range formatting. Should accept --lines=START:END argument. Optional."
134+
}
135+
}
120136
}
121137
}
122138
}
123-
}
139+
],
140+
"default": "Runic",
141+
"markdownDescription": "Formatter configuration. Can be a preset name ('Runic' or 'JuliaFormatter') or a custom formatter object. See [Formatting](https://github.com/aviatesk/JETLS.jl#formatting) for details."
124142
}
125143
}
126144
}

0 commit comments

Comments
 (0)