How can I avoid these kinds of errors? My understanding is that JETLS is not starting in my current environment. How can I make it start? Or should I add DataFrames to the main Julia environment?
More context helps others understand your problem. Please see below.
I use eglot in emacs with JETLS. My main julia environment does not have DataFrames. I make separate packages for each project and install DataFrames separately in each project. My config details below. For JETLS install, I’m using the documentation.
Emacs init and Julia pkg details
;; Julia REPL
(use-package julia-repl
:ensure t
:hook (julia-ts-mode . julia-repl-mode)
:config
(julia-repl-set-terminal-backend 'vterm)
(setq julia-repl-executable-records '((default "julia" :basedir "/Users/foo/applications/julia/usr/share/julia/base/")))
(setq julia-repl-executable-key 'default)
)
;;
;; Eglot
;;
(use-package sideline-eglot
:ensure t
:init
(setq sideline-backends-right '(sideline-eglot)))
;; Set up the Language Server Protocol (LSP) servers using Eglot.
(use-package eglot
:ensure t
:hook ((eglot-mode . sideline-mode)
(ess-r-mode . eglot-ensure))
:commands (eglot-ensure
eglot-rename
eglot-format-buffer))
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
'(((julia-mode :language-id "julia")
(julia-ts-mode :language-id "julia"))
"jetls"
"--threads=auto"
"--"
"serve"
"--socket"
:autoport))
(add-to-list 'eglot-server-programs
'(ess-r-mode . ("R" "--slave" "--args" "-e" "languageserver::run()"))))
(use-package consult-eglot
:ensure t)
(use-package consult-eglot-embark
:ensure t)
(with-eval-after-load 'embark
(with-eval-after-load 'consult-eglot
(require 'consult-eglot-embark)
(consult-eglot-embark-mode)))
(@v1.13) pkg> st
Status `~/.julia/environments/v1.13/Project.toml`
[2b0e0bc5] LanguageServer v6.0.1
[295af30f] Revise v3.17.2
(@v1.13) pkg> app status
[a3b70258] JETLS v2026.10.4 `https://github.com/aviatesk/JETLS.jl#release`
jetls ~/applications/julia/usr/bin/julia
[62bfec6d] Runic v1.13.0
git-runic ~/applications/julia/usr/bin/julia
runic ~/applications/julia/usr/bin/julia
Thanks for this. I think I understand the issue, I have to add using DataFrames in the top. JETLS does not understand that the file is part of a package that uses DataFrames. I guess this is how it works?
I’m still confused as to how to edit a package where .jl files use structs and functions declared outside Base.
Well, I work with packages and have nearly nothing in the global environment, and JETLS finds the packages of Project.toml in the project root folder just fine. It needs some startup time, though, can be minutes.
I use VSCode where you can follow the startup of JETLS in the status bar.
It needs to instantiate the project to be able to work. Check manually that
using Pkg
Pkg.resolve()
Pkg.instantiate()
works.
I don’t know how to debug JETLS startup issues with EMACS.
Thanks! About the last three commands, do they need to be added to the file I’m editing in JETLS or to the current environment?
No. Just instantiate the project once in the REPL. But thats what you have to do anyways if you work with projects, if you use JETLS or not. If you want to learn how to work with projects, have a look at Working with Julia projects | Julia programming notes
Question: Even if your jl files are under the src/ folder, but the packages are in the main folder of the project, you don’t have any issue with using?
No, I don’t. Project.toml has to be in the root folder. JETLS needs to know where the root folder is, but as long as I use VSCode it knows that automatically.
JETLS normally determines the workspace/project root from the editor’s LSP initialization: the editor searches upward from the opened Julia file for a root marker such as Project.toml, then tells JETLS that directory is the workspace root.
How it resolves the root
-
Editor-provided workspace root: VS Code, Neovim, Emacs, etc. usually use root markers. A typical Neovim configuration uses
root_markers = { "Project.toml", "JuliaProject.toml" }; another example searches forProject.tomlor.git. -
Nearest
Project.toml: For analysis, JETLS determines each file’s package/project context from the nearestProject.tomlabove that file, independent of the current working directory. -
Package versus script mode: If the nearest project is a package directory—its
Project.tomlhas anameentry—JETLS treats it as package mode and usessrc/<PackageName>.jlas the package entry file.
Perhaps your Project.toml file has no name entry? Or you have no src/<PackageName>.jl file?
Thanks. That question was for @George9000 .
Did you follow the instructions for Emacs: Index · JETLS.jl
If you did, perhaps they are incomplete/ outdated?
I still don’t understand your context. I don’t understand the problem you are experiencing, and I’m guessing at what you mean. This is why I suggested in my first reply that you document a MWE and delineate the problem.
Here’s my usual workflow when starting a project, usually a data analysis of some sort.
julia -e 'using Pkg;Pkg.generate("aproject")'
cd aproject
julia -e 'using Pkg;Pkg.activate(".");Pkg.instantiate()'
You should now see a Project.toml and a Manifest.toml in your project directory.
I work with Revise as one of the few packages in my global environment and is part of my startup. So my ~/.julia/config/startup.jl reads (in part)
using Pkg
if isfile("Project.toml") && isfile("Manifest.toml")
Pkg.activate(".")
end
try
using Revise
catch e
@warn "Error initializing Revise" exception=(e, catch_backtrace())
end
println(":")
println(":" * pwd())
println(":")
In the project directory, I start julia. Dropping to the package prompt, pkg> I add DataFrames, CSV, etc. to the project.
Now back to the project directory.
touch myanalysis.jl
echo "using aproject;\nusing DataFrames;" > myanalysis.jl
In my src/aproject.jl, I use this trick
module aproject
using DatFrames
@static if false
include("../myanalysis.jl")
end
end # module aproject
Note that the follow-up reply reported success in emacs. I’m not strictly sure that’s needed for eglot but I’ve left it there for now.
As @ufechner7 notes, eglot / jetls takes a bit of time to start up in Emacs. But once it does, things seem to work. I haven’t got all the xref lookup functions working but with the emacs consult/embark, I can also do a consult-rg (ripgrep) which generally finds anything I need in the project.
Thanks a lot, @George9000 ! I didn’t add context because we are basically doing the same thing.
However, this is not how I usually work with projects:
- My main project.jl file is under /src, not in the main project directory.
- I don’t touch the src/Project.toml file (are you sure you can add a module definition in a .toml file?).
If I got it right, the idea is to add a script in the main folder that calls the package with using, and then the @static block goes to /src/mypackage.jl. It’s not a very elegant solution.
I wonder whether @Tamas_Papp has any suggestions (or configurations he might want to share
).
are you sure you can add a module definition in a .toml file
Typo. It is the src/aproject.jl (the module definition file)
My main project.jl file is under /src, not in the main project directory
That’s a new one to me. I see in most Julia packages that the Project.toml is in the main directory, not src/
The Project .toml sure. I was talking about the project.jl.