This codebase is a clone of zed-julia. Its purpose is to enable testing of the new Julia language server JETLS.jl in the Zed editor.
By following the steps below, you can use JETLS within Zed:
- The latest version of Zed
- Julia
v"1.12.0-beta2"
or higher
- Follow these instructions to install the requirements for developing Zed extensions, particularly the Rust installation via rustup
- Clone JETLS.jl
- Clone aviatesk/zed-julia and check out to the
avi/JETLS
branch - Run
julia --project=. -e 'using Pkg; Pkg.instantiate()'
in the JETLS.jl folder to install all necessary Julia packages - Open Zed and invoke the
zed: extensions
command - Click
Install Dev Extension
and specify the directory of zed-julia - Specify the path of Julia executable and the directory of JETLS.jl in the
lsp
section of Zed settings:"lsp": { "JETLS": { "binary": { "path": "/path/to/julia", "env": { "JETLS_DIRECTORY": "/path/to/JETLS.jl/" // must end with `/` } } } }
Now your Julia files should be analyzed by JETLS:
This extension adds support for the Julia language in the zed editor.
- Install Julia for your platform: https://julialang.org/downloads/
- Install Zed for your platform: https://zed.dev/download
- Start Zed.
- Inside Zed, go to the extensions view by
executing the
zed: extensions
command (click Zed->Extensions). - In the extensions view, simply search for the term
julia
in the search box, then select the extension namedJulia
and click the install button. You might have to restart Zed after this step.
The Julia Zed extension looks for your Julia binary in the standard locations.
Make sure that the Julia binary is on your PATH
.
By default, Zed tasks (like running tests) use the julia
command from your PATH.
You can customize which Julia executable is used by setting the julia
environment variable:
-
In your shell configuration (
.bashrc
,.zshrc
, etc.):export julia="/path/to/custom/julia"
-
When launching Zed from the terminal:
julia="/path/to/custom/julia" zed .
-
Using direnv (automatically supported by Zed):
- Create a
.envrc
file in your project root with:.envrc
JULIA_HOME="path/to/julia/directory" PATH_add "$JULIA_HOME/bin" export julia="$JULIA_HOME/bin/julia"
- Run
direnv allow
to approve the file
- Create a
This allows you to use different Julia versions for different projects or to specify a Julia installation that's not on your PATH.
The Julia extension supports TestRunner.jl for running individual tests, testsets, and test expressions directly from the editor. This provides a more granular testing experience compared to running the entire test suite with Pkg.test()
.
[!note] Note This integration requires Julia 1.12 or higher.
To use TestRunner.jl, install it globally as a Julia app:
julia -e 'using Pkg; Pkg.Apps.add("TestRunner")'
This will install the testrunner
command to your Julia apps directory. Make sure Julia apps are accessible from your PATH by following the instructions at https://pkgdocs.julialang.org/dev/apps/.
Note: The Julia executable used for running tests can be configured as described in the Configuring the Julia executable for tasks section above.
TestRunner.jl integration provides several runnable tasks:
- Julia: Run test file (TestRunner.jl) - Runs all tests in the current file
- Julia: Run
@testset
(TestRunner.jl) - Runs a specific@testset
block at the cursor position - Julia: Run
# [TESTRUNNER]
comment expression (TestRunner.jl) - Runs an expression following# [TESTRUNNER]
comments - Julia: Run expression at cursor (TestRunner.jl) - Runs an expression at line of the current cursor position, useful for debugging arbitrary code including standalone
@test
cases (manual invocation only, experimental)
You can run tests in two ways:
- Using the play button - Zed displays a play button (▶) in the gutter next to each
@testset
or any expression following comment starting[TestRunner]
. Simply click the button to run that specific test.
- Using the command palette - Position your cursor on or inside the test element you want to run, then:
- Use the command palette (Cmd/Ctrl+Shift+P) and search for "task: spawn"
- Select the appropriate Julia test task from the list
- The test will run in a new terminal with detailed output
Both methods will execute tests using TestRunner.jl with output shown in the terminal dock.
using Test
test_func() = @test sin(x) == 0 # should fail
@testset "begin" begin
println("foo")
@test sin(0) == 0
@testset let name = "bar",
v = π
println(name)
@test sin(v) == 0
end
@testset "some testset" include("some_test_file.jl")
x = 3π/2
# [TestRunner]
test_func(x) # should fail
end
# [TESTRUNNER]
println("Debug output") # Run with "Run [TESTRUNNER] expression"
Zed is currently not on the list of Julia's predefined editors. You can add it to your ~/.julia/config/startup.jl
:
atreplinit() do repl
InteractiveUtils.define_editor("zed") do cmd, path, line, column
`$cmd $path:$line:$column`
end
end
Set the environment variable EDITOR (or VISUAL or JULIA_EDITOR, whatever you use) to zed --wait
. Then, using InteractiveUtils.edit
etc. will open the document in Zed.
You can change the foreground color and text attributes of syntax tokens in your ~/.config/zed/settings.json
, for instance:
{
"experimental.theme_overrides": {
"syntax": {
"comment.doc": {
"color": "#808080",
"font_style": "italic"
},
"function.definition": {
"color": "#0000AA",
"font_weight": 700
}
}
}
}
Note: the "color" field is mandatory even if you just want to change the "font_style" (the example in Zed's docs does not work).
See Syntax Highlighting and Themes and Tree-sitter Queries for further details.
Syntax tokens are called captures in tree-sitter jargon. The following table lists all captures provided by zed-julia. Some captures have default values (defined in Zed's color themes) and the other captures fall back to one of the defaults. Depending on your color theme, some captures may be set to the editor's foreground color or to a very similar one. In this case, try to assign a different color to improve the contrast.
Capture | Is there a default value? | Note/Example |
---|---|---|
boolean |
yes | |
comment |
yes | line or block comment |
comment.doc |
yes | docstring |
constant.builtin |
no, falls back to constant | core julia built-in |
function.builtin |
no, falls back to function | core julia built-in |
function.call |
no, falls back to function | name of the called function |
function.definition |
no, falls back to function | name of the defined function |
function.macro |
no, falls back to function | name of the macro |
keyword |
yes | |
keyword.conditional |
no, falls back to keyword | if , else |
keyword.conditional.ternary |
no, falls back to keyword | ? : |
keyword.exception |
no, falls back to keyword | try , catch |
keyword.function |
no, falls back to keyword | function , do , short function definition: = |
keyword.import |
no, falls back to keyword | im/export , using , module definition |
keyword.operator |
no, falls back to keyword | in , isa , where |
keyword.repeat |
no, falls back to keyword | for , while |
keyword.return |
no, falls back to keyword | return |
number |
yes | |
number.float |
no, falls back to number | |
operator |
yes | |
punctuation.bracket |
yes | () , [] , {} |
punctuation.delimiter |
yes | , , ; |
punctuation.special |
yes | string interpolation: $() |
string |
yes | |
string.escape |
yes | escape sequence |
string.special |
yes | command literal |
string.special.symbol |
yes | quote expression |
type |
yes | |
type.builtin |
no, falls back to type | core julia built-in |
type.definition |
no, falls back to type | |
variable |
yes | |
variable.builtin |
no, falls back to variable | core julia built-in: begin and end in indices |
variable.member |
no, falls back to variable | example: in foo.bar , the member is bar |
See this document.