How to configure OCaml Platform in VSCode/Codium?

Hi, I’ve been having some trouble with Ubuntu 20.04 + VSCodium (VSCode) + OCaml Platform extension for VSCode + non-default opam switch.

Eventually I figured out that pressing Ctrl+Shift+P (yes with Shift) and typing ocaml brings up really good commands… I can select the switch to use, I can launch terminal with that switch configured… Pretty cool if not very obvious from the docs.

I still have some questions left

  • is it possible to have ocamlformat, ocaml-lsp-server and dune installed in one switch and use another to write my hello-world apps? ocamlformat and coaml-lsp-server have pulled in a ton of depdendencies and it would have felt cleaner to use an “empty” switch for development…

  • auto-generated .vscode/tasks.json looks a bit strange:

    {
      "version": "2.0.0",
      "tasks": [
      	{
      		"type": "dune",
      		"problemMatcher": [
      			"$ocamlc"
      		],
      		"group": {
      			"kind": "build",
      			"isDefault": true
      		},
      		"label": "dune: build /dune-project"
      	}
      ]
    }
    

    why this?.. the command that ends up being run is ... dune build so how is it related to the above?

  • Is it expected that I have to close/re-open my workspace (“folder”) to pick up changes to .vscode/.settings.json?..

  • does it make sense to try to set something like this in .vscode/settings.json? This doesn’t work…

    "ocaml.terminal.shell.linux": "bash -ci 'eval $(opam env --switch dev --set-switch); bash'"
    
  • what is the best way to run my app from inside VSCodium? Doing dune exec ./proj1.exe each time manually from the correct terminal isn’t that much fun

  • is there a debugger that’d work in VSCode/VSCodium? or am I asking too much? :slight_smile:

2 Likes

Hi!

We can certainly do better with documenting the features available in vscode-ocaml-platform and this kind of feedback is very useful :slight_smile:
That being said, the recently introduced OCaml activity tab is supposed to offer an obvious path to discover the extension features, so if you think something (e.g. a command) should be there, don’t hesitate to open an issue.

is it possible to have ocamlformat, ocaml-lsp-server and dune installed in one switch and use another to write my hello-world apps?

Moving forward, we want users’ projects to be independant from the Platform tools, but that’s not as easy as storing the binaries outside of the opam switch, because some binaries depend on the project configuration (version of ocamlformat to use), some depend on the ocaml version (odoc or merlin), and some even have to be installed in the switch directly to be usable by dune (utop).

So not something that’s possible at the moment, but we’re working on it.

Is it expected that I have to close/re-open my workspace (“folder”) to pick up changes to?

No, what changes are you doing in you settings that requires a reloading?

Does it make sense to try to set something like this in .vscode/settings.json?

If I understand the command correctly, it should be what the integrated terminal does, so you shouldn’t have to define a custom one. If you still want to, maybe try something like this:

"ocaml.terminal.shell.linux": "opam",
"ocaml.terminal.shellArgs.linux": [
    "exec",
    "--switch=vscode",
    "--",
    "bash",
    "-i"
]

what is the best way to run my app from inside VSCodium?

In the future, a tight integration with dune could allow us to provide commands to build/run the executables defined in your dune files, but in the meantime, you could define a custom task to execute the binary.

Personnally, I open an integrated terminal and run dune build -w. I also use this script (typically for web servers when I am doing UI work) to run my executables everytime there is a filesystem change:

#!/usr/bin/env bash

source_dirs="lib bin"
args=${*:-"bin/server.exe"}
cmd="opam exec -- dune exec ${args}"

function sigint_handler() {
  kill "$(jobs -pr)"
  exit 1
}

trap sigint_handler SIGINT

while true; do
  make build
  $cmd &
  fswatch -r -1 $source_dirs
  printf "\nRestarting server.exe due to filesystem change\n"
  kill "$(jobs -pr)"
done

is there a debugger that’d work in VSCode/VSCodium?

Not in vscode-ocaml-platform yet, but @hackwaly is doing great work with ocamlearlybird

TBH the only way to bring up that tab that I discovered was to press Ctrl+Shift+P and type ocaml. If there is another way to bring it up that could well be put front and center into the main .md file.

Right, the docs say it’s Ctrl+P outside of Mac OS but it is Ctrl+Shift+P on Ubuntu right now. Also the documents could make it more clear: “this is your starting point! that’s how you start!”

I guess if that was an explicit option for people to opt in - to run ocamlformat from a different switch - people would be aware of this and could even keep a couple of switches around with the correct version of ocamlformat - if they needed different version for different projects.

ocamlformat brings in a ton of dependencies, a lot more than ocaml-lsp-server itself. So in my view it is fully worthy of being banished into a different switch. Perhaps OCaml Platform for VSCode could check that the version in that other switch is correct somehow?..

Wow! Is that another dependency to install? The docs never mention it’s needed explicitly

G’luck with it… Just a random idea: what if there was a concept of a “shadow switch” - e.g. OCaml Platform for VSCode would agree to use ocaml-lsp-server from a switch different from the project’s switch only if the version of compiler matched exactly between the two switches?

It could even offer the option to create such a switch explicitly for you, calling it say lsp-4.11.1 switch? Just an idea…

Not sure if it’s a good idea to banish ocamlformat together with ocaml-lsp-server into the same shadow switch… It seems less clear which version ocamlformat should be. If they’re banished together then the name of the shadow switch would probably need to follow the name of the current switch with some suffix. Not sure what to do if people choose to use a local switch instead… Create yet one more inside .vscode?

Changes to ocaml.sandbox I think even changes to "switch"= require a reload of the project in VSCodium and definitely to template in

{
    "ocaml.sandbox": {
        "kind" : "custom",
        "template" : "opam exec --switch dev -- $prog $args"
    }
}

Thanks a lot for other answers too

Thank your for the questions. I think it’s clear we need to work on the documentation. Maybe it would even be useful to have a “getting started” panel directly in VSCode? I know some other extensions like the Java extension have something similar.

I tried my best to answer most of your questions below. Feel free to ask anything else if I didn’t explain something well.

is it possible to have ocamlformat , ocaml-lsp-server and dune installed in one switch and use another to write my hello-world apps? ocamlformat and coaml-lsp-server have pulled in a ton of depdendencies and it would have felt cleaner to use an “empty” switch for development…

Sure, just make sure you select a switch that has the same version of ocaml as the one you’re building in.

You can select a switch by clicking on the status bar item with the package icon:

Then select the switch you want:

auto-generated .vscode/tasks.json looks a bit strange:

The "type": "dune" means it is handled internally by the extension. It will run in the selected sandbox automatically. Note that if you’ve selected a sandbox that’s not the one you’re building from, you might run into some issues. There is some work on separating these concepts that @tmattio is working on, but for now, using the same switch would probably be easier.

Is it expected that I have to close/re-open my workspace (“folder”) to pick up changes to .vscode/.settings.json ?..

If you’re manually editing the settings.json, the extension will not pick up a change in the sandbox automatically. If you want to change the sandbox, use the select sandbox command.

does it make sense to try to set something like this in .vscode/settings.json ? This doesn’t work…

That’s unnecessary because the terminal you get from running the create terminal command is already created from the sandbox. You can leave these empty and it will use the same shell as your normal VSCode integrated terminal.

TBH the only way to bring up that tab that I discovered was to press Ctrl+Shift+P and type ocaml . If there is another way to bring it up that could well be put front and center into the main .md file.

The button for activity panel should be visible in the side bar by default. Does VSCodium have different behavior?

Wow! Is that another dependency to install? The docs never mention it’s needed explicitly

You do not need to install odoc or utop.

Just a random idea: what if there was a concept of a “shadow switch”

This is something we’re already working on, along with automatic installation of certain tools.

Changes to ocaml.sandbox I think even changes to "switch"= require a reload of the project in VSCodium and definitely to template in

As I mentioned earlier, using the select sandbox command will allow you to change the sandbox without reloading. If you’re just using opam switches, there’s no need to use the custom sandbox. Your settings.json would look like

{
	"ocaml.sandbox": {
		"kind": "opam",
		"switch": "dev"
	}
}

First of all thank you folks for your patient and detailed answers. This helps me feel more at home in a new environment.

I am okay to be mixing the two switches for now.

Mostly because of my tendency to dot all i-s and cross all t-s… Right now I have only been able to select one switch in OCaml Platform extension. I guess that switch is used both to run ocaml-rsp-server and to compile my app.

If I tried to follow the suggestion above and attempted to separate I would have needed to specify two switches isn’t that right? One to run ocaml-rsp-server and another to build? But the extension only gives me one choice which seems to be going into settings.xml into

{
    "ocaml.sandbox": {
       "kind": "opam",
       "switch": "dev"
    }
}

There is a blob of documentation that can be easily read from inside VSCodium. It seems to be coming from README.md in the code repository. That was one of the first documents I read. In fact I kept reading it through and through in order to figure out how to start. So in my case it would have been totally sufficient if instructions were there, I didn’t really need a new window that much. In fact I don’t like apps showing me “tip of the day”, that seems quite intrusive to workflow…

Oh yes, it’s there. I see it now. But this being almost my first day with VSCode/Codium and the first day with OCaml Platform extension I just didn’t know where to look… The icon was totally invisible to me until after the fact. But actually accessing the same commands via Ctrl+Shift+P feels better. Using keyboard is great :slight_smile:

Yep seen that now. Somewhat unfortunately the main terminal you get from top menu - and from the keyboard shortcut - doesn’t have the sandboxing… Oh well… guess it’s a “can’t have it all” situation. I’m sure you folks have done your best with the terminals.

I’ve managed to create a “shell” task in tasks.json now which executes

opam exec --switch dev -- dune exec -- ./proj1.exe

the next awkward problem is that I always need to use mouse to execute it… It’s nice that I can Ctrl+Shift+B my main build task which is configured now to be dune but I’m lacking the ability to run the app as easily from keyboard.

On the other hand I’m using mouse always in Eclipse to run my Java app and it never occurred to me to complain. Not sure why I expect my OCaml experience to be better :slight_smile:

Right now, the extension uses the same switch for running ocaml-lsp-server, running the dune build task, and creating the terminal. This is likely to change in the future to support workflows like yours, but currently there is no way to have separate switches.

It does in fact come from the README. I’ll try my best to improve it before the next release.

You can add a keyboard shortcut for the OCaml: Create Terminal command (or any command) by going to the VSCode Keyboard Shortcuts page, searching for the command and clicking on the pencil next to it to add a keybinding.

1 Like