diskuv / dkml-installer-ocaml

The Windows-friendly distribution of OCaml
Apache License 2.0
63 stars 2 forks source link

Unbound module Stdlib in VS Code #30

Closed TheMingo888 closed 1 year ago

TheMingo888 commented 1 year ago

I installed Diskuv OCaml 1.1.0_r2 a few days ago without issue. UTop, ocamlc, and ocamlopt all seem to work fine. I've installed the OCaml Platform extension for Visual Studio Code, and unchecked "Use OCaml Env" per the documentation, however I have a strange issue where it seems ocamllsp can't find the stdlib module. The code does run in UTop if I use Shift + Enter, it is just the syntax highlighting that is broken. A screenshot is attached. Screenshot 2023-01-16 103448

jonahbeckford commented 1 year ago

Try the following in order and post your results in this ticket:

  1. Try Ctrl+Shift+P and then run OCaml: Restart Language Server whenever you have an Unbound module.
  2. Did you do dune build in your project? If you don't know what dune build means, go over the short doc at https://diskuv-ocaml.gitlab.io/distributions/dkml/doc/BeyondBasics.html#learn-ocaml-a-first-project
  3. Are you in your own self-created own switch (ex. you made it with dkml init)? If so, then you'll need to install ocaml-lsp-server using the instructions at the bottom of https://diskuv-ocaml.gitlab.io/distributions/dkml/doc/BeyondBasics.html#installing-the-ocaml-plugin
TheMingo888 commented 1 year ago
  1. Restarting the language server had no effect.

  2. I actually tried that guide earlier for dune and ran into a problem:

D:\ocamlprojects>mkdir helloworld

D:\ocamlprojects>cd helloworld

D:\ocamlprojects\helloworld>dune init exe helloworld
Success: initialized executable component named helloworld

D:\ocamlprojects\helloworld>dune build
Error: I cannot find the root of the current workspace/project.
If you would like to create a new dune project, you can type:

    dune init project NAME

Otherwise, please make sure to run dune inside an existing project or
workspace. For more information about how dune identifies the root of the
current workspace/project, please refer to
https://dune.readthedocs.io/en/stable/usage.html#finding-the-root

However, I would ideally like to have syntax highlighting for .ml files not part of any project and without using dune. I haven't needed to use dune thus far to compile and run my .ml files.

  1. I am using the default dkml switch.
jonahbeckford commented 1 year ago

Thanks; I see a bug in that documentation now that we have a new version of dune.

Let's do it again using helloworld2 ... your transcript should look like this:

D:\ocamlprojects>mkdir helloworld2

D:\ocamlprojects>cd helloworld2

D:\ocamlprojects\helloworld2>with-dkml sh -c "echo '(lang dune 2.9)' > dune-project"

D:\ocamlprojects\helloworld2>dune init exe helloworld2
�[2;32mSuccess�[0m: initialized executable component named �[1;34mhelloworld2�[0m

D:\ocamlprojects\helloworld2>dune build

That new command creates a single-line file called dune-project.

TheMingo888 commented 1 year ago

Thank you, that does appear to work. Dune build now succeeds and syntax highlighting for helloworld2.ml seems to function properly (though I still need to manually instruct VS Code to convert helloworld2.ml from CRLF to LF to avoid an invalid character message).

As I mentioned previously, though, is it possible to get syntax highlighting working without making these dune files each time? My instructor distributes .ml files (we have not discussed dune) and I'd like to be able to open them without the unbound module errors. My peers on Mac/Linux seem to have VS Code working without using dune (though they probably don't use Diskuv OCaml).

jonahbeckford commented 1 year ago

Interesting ... I assume you are compiling by hand with ocamlc or ocamlopt?

I suspect your peers on Mac/Linux are using older "ocaml-lsp-server" (that is the OCaml tool that talks to VS Code) and they will eventually run into the same problem. Dune recently became the only officially supported way to get syntax highlighting.

But you may be able to get some syntax highlighting if you don't already. Can you switch the "sandbox" in VS Code?

That is:

  1. Go back to a directory that does not have dune-project.
  2. Open an .ml file from that directory.
  3. Press Ctrl+Shift+P and run OCaml: Select a Sandbox for this workspace
  4. Choose the dkml switch (my guess is you are on the playground switch).

Does that work? You will still see Unbound module Stdlib on the first line, but the rest of the code should syntax highlight, have code hovers, etc.

If you can get that far, I will ask you to open a ticket with the team behind "ocaml-lsp-server" (actually, it may be better if your instructor does). They may ask your instructor to provide some Merlin files if you aren't using Dune.

TheMingo888 commented 1 year ago

Yep, we've only been manually compiling or sending lines to UTop. Unfortunately, your instructions just recreated the same situation as the original problem (I had already been using dkml instead of playground). As you can see in the screenshot I originally posted, the lack of Stdlib also causes all operators like + and < and even negative signs in front of integers to be treated like errors too, so it is rather unusual.

Fortunately, I did fix the problem. I ran ocamlc -config and noticed these two lines:

standard_library_default: C:/Users/User/AppData/Local/Programs/DISKUV~1/lib/ocaml
standard_library: C:/Users/User/AppData/Local/Programs/DISKUV~1/lib/ocaml

Technically, the paths are correct, though Windows usually uses backslashes. I am not sure why the installer chose DISKUV~1 instead of DiskuvOCaml, the former being the 8.3 filename retained for DOS compatibility and the latter being the actual folder name, but it should work regardless. And indeed, for UTop and ocamlc and ocamlopt, it does work.

To troubleshoot, I tried creating the OCAMLLIB environment variable (which did not exist post-installation) and setting it to C:\Users\User\AppData\Local\Programs\DiskuvOCaml\lib\ocaml. This changed the output of ocamlc -config to:

standard_library_default: C:/Users/User/AppData/Local/Programs/DISKUV~1/lib/ocaml
standard_library: C:\Users\User\AppData\Local\Programs\DiskuvOCaml\lib\ocaml

After restarting VS Code, syntax highlighting worked as expected for all .ml files, regardless of dune, just as I was hoping for.

I guess the question is, why did the original library path work for UTop and ocamlc but not for ocamllsp? Should the installer be setting the OCAMLLIB environment variable, or perhaps is it possible to change the default library path in the binary? I am not sure whether it was the slashes or the 8.3 filename that ended up fixing things.

Also, how did creating and building a dune project fix the highlighting without this environment variable? Does it override the standard library path reported by ocamlc -config?

EDIT: It looks like the slashes and 8.3 filenames are red herrings. The issue is fixed just by setting the environment variable to the standard_library_default path. It just seems ocamllsp is unable to find Stdlib if OCAMLLIB is unset.

jonahbeckford commented 1 year ago

Clearly that is a bug with ocamllsp. You may want to file a ticket there.

The reason why DOS 8.3 names are given is because many many opam packages do not work with spaces in the path (ex. C:\Users\Some Student). Regardless of the reason, DOS 8.3 are valid paths, and the OCaml runtime accepts DOS 8.3 paths, so they should work.

I'll close this ticket in a couple days because this last issue doesn't belong in this queue.

Thanks for the patience.