microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
162.62k stars 28.67k forks source link

Support for setting a shell command for nix based builders #218361

Closed qknight closed 2 months ago

qknight commented 2 months ago

Motivation

Using nix for development one can use nix develop for nix-flake based development to get into a development shell.

The basic idea of a development shell is that it contains software and development packages which the default system shell does not share. In other words, this let's use have multiple projects on one machine with different stripped-down isolated development environments.

Target audience

This feature request is for local development and for remote development using https://github.com/Microsoft/vscode-remote-release using visual studio code.

Required changes

@jeanp413 said:

vscode is the one who does the shell resolution internally here, by default it will use the shell from $SHELL but if that's unset it will use node's userInfo().shell which will read /etc/passwd source code

My proposal for resolving the shell command would be:

  1. vscode checks for a .vscode-nix.toml file which could look like this:
    
    # .vscode-nix.toml
    # This configuration file helps Visual Studio Code determine the shell to use for different Nix environments.

Specify the shell to use for Nix Flake's 'nix develop'

[shell] name = "nix flake" command = "nix develop"

Specify the shell to use for Devenv

[shell]

name = "devenv"

command = "devenv shell"

Specify the shell to use for Direnv

[shell]

name = "direnv"

command = "direnv allow && direnv exec . $SHELL"

Specify the shell to use for Nix Shell

[shell]

name = "nix-shell"

command = "nix-shell"



2. if `.vscode-nix.toml` exists, vscode should use the command from there, to spawn all shells, instead of using the target systems SHELL variable (or the fallback). this should only be done if not in [restricted mode](https://code.visualstudio.com/docs/editor/workspace-trust).

vscode uses these types of shell currently: 

* the project build uses a shell (the user can't input anything into this shell)
* there is the 'terminal' button also, which spanws an interactive shell (this is not used by the project builder but instead only for the interactive changes by the user)

toml is just a proposal markup language, could be any other. I like it over json because it supports comments.

See details about the idea in: https://lastlog.de/blog/vscodium_and_nix_develop.html

# help and testing

If someone is interested in this proposal, I'd be happy to test the PR.
roblourens commented 2 months ago

So you want to be able to open a terminal with this environment? Or you want all of VS Code's environment to be inside this kind of shell?

qknight commented 2 months ago

@roblourens actually both. It would be great, that if that envrionment can't be built, that vscode prints a meaningful error message.

For instance, this would be one error message:

PS C:\Users\joschie> wsl -d nixos
interactive
error:
       … while fetching the input 'git+file:///home/nixos/klick'

       error: getting the HEAD of the Git tree '/home/nixos/klick' failed with exit code 1:
       error: executing 'git': No such file or directory

But there could be so many other kinds of error mesages when a nix develop build shell is opened and a build failed.

Update: I've added a http://localhost:8000/vscodium_and_nix_develop.html#nix-shell-error-handling-ux section covering error handling and recovery.

roblourens commented 2 months ago

We likely aren't going to add anything specifically to handle this kind of nix shell, so I'm trying to understand how you can configure vscode to get what you expect. If you just want to open a terminal in this environment, you can probably configure a terminal profile to do this, see https://code.visualstudio.com/docs/terminal/profiles. You can even define it as the automation profile so it's used for build/debug terminals.

If you want the entire vscode remote environment to be in this environment, you can probably activate it in a .bash_profile so that it's set up when the remote environment is installed.

Does that help?

qknight commented 2 months ago

@roblourens one day we hopefully get support for this concept. The proposed profiles concept is too general. In practice each project has its own setup. I have a hack discussed in the blog post, which is already working. With some tinkering I can also come up with another more comfy hack but this is nothing compared to a IDE based solution.

Thanks for your time.