Julia Language Server (VS Code Julia Extension) "missing reference"

What is required for the Julia Language Server to recognize packages which I am writing locally?

Can someone show a short example of a repo structure which the Julia Language Server will recognize correctly?

Everything seems to be ok until I try to define multiple packages.

This question is a bit open-ended, because I am not sure what sort of structure will or will not work.

For example, here is something I have tried:

example-repo/
  PackageA/
    src/
      PackageA.jl
      ModuleA2.jl
  PackageB/
    src/
      PackageB.jl
myTarget.jl

myTarget.jl is intended to be a target executable.

It contains the following.

println("myTarget")

using PackageA
using PackageB

PackageA.exampleA()
PackageA.exampleA2()

PackageB.exampleB()

Every reference to PackageA and PackageB are marked by the Julia Language Server as Missing reference.

I cannot CTRL+LEFTCLICK to jump to the definitions of any of these things.

Does anyone know why this is the case? I would guess some kind of configuration is missing?

myTarget.jl should be in a properly constructed project (“workspace” in VSC terminology IIRC) with PackageA and PackageB listed in its Project.toml and manifest. (Maybe you know this, but you didn’t list TOML files above.) Are references not reliably resolved for you in this situation?

I think you have to restart the language server if you add new objects to PackageA or B (or to files include’d by myTarget.jl) during a session.

I’m probably not doing most of these things correctly. Some specific questions:

  • What defines a workspace in this context and how/where should I put myTarget.jl?
  • PackageA and PackageB are not in Project.toml.
  • In addition to this I suspect that I have not created Project.toml correctly. What should I do to create it? (Assume I either start again or delete it.)

I tried to find information about these things before creating this test project, but I was trying to piece together bits of information I found in different places.

It’s probably safer just to assume I have no idea what I am doing in this particular case.

First make sure your library packages have their own Project.toml files. These normally come from using the generate package REPL command or by using PkgTemplates.jl for bigger efforts.

Now if you put your script in a directory, say example-project, parallel to your example-repo above, then from a Julia REPL running in that directory, enter the Package mode with ‘]’ and run the commands

activate .
develop ../example-repo/PackageA
develop ../example-repo/PackageB

I don’t know if there is an alternative using VS Code commands.

Thanks for the help.

I think you misinterpreted the location of PackageA and PackageB.

To explain in more detail, the top level directory of the repo is like this:

MyProject/
  PackageA
  PackageB
  myTarget.jl

Do I still need those develop commands in this case?

Well, usually you should keep each package in separate repository, create new julia environment for the target project, and add those packages to the environment via add or develop command in pkg mode, but it’s not what you doing as far as I understand. In you case, you probably should do something like this:

include("PackageA/src/PackageA.jl")
include("PackageB/src/PackageB.jl")

using .PackageA
using .PackageB

The develop and add commands get the references into the manifest, which is how the language server resolves namespaces. As detailed in the other thread, automatic lookup in subdirectories is not currently available.

Pedro’s approach will also work, but those are really just submodules and it seems confusing to lay them out as if they were packages.

One thing which I have tried doing, which does not appear to work, has been to add a path to JULIA_LOAD_PATH. That path being the root of this repository.

That works when Julia runs, one can do

using PackageA
using PackageB

and Julia will be able to find those packages because of the additional path in JULIA_LOAD_PATH.

However, VS Code (Julia Extension) does not appear to understand this. Maybe it doesn’t read the LOAD_PATH?

The key to making LSP work is to point its “project directory” to a folder containing a fully instantiated (!) environment with your package and any other package that the LSP should know about, e.g., test dependencies. Personally, I use a test/Project.toml file for test/docs dependencies (instead of the older [extras] in the main Project.toml file, make sure that’s always instantiated (via a Makefile), and point LSP to that.

To be fair, I always found the LSP to be tricky in VS Code. It only really started to work reliably once I set it up in Neovim. But that may also be because I haven’t invested that much time into VS Code and never figured out the way to penetrate that “black box”.

add a path to JULIA_LOAD_PATH

Probably, VS Code controls the environment for the julia subprocess. Depending on where you set that environment variable, it was probably not forwarded.

But based on this and a number of your other recent posts: you seem to be a bit enamored with JULIA_LOAD_PATH. Modifying JULIA_LOAD_PATH is basically never the right answer. To first order, you should forget that it exists.

3 Likes

If you were talking about Python, I would agree with you.

However with Julia there is no other (good) solution.