As far as I can tell, one cannot easily use cpptools in visual studio code, due the C# executable. Thus, developing C/C++ is not really possible with VSCode on NixOS.
To work around this, we can use vscode-with-extension and use an overlay to install cpptools via nix:
self: super:
{
mycode = super.vscode-with-extensions.override {
# When the extension is already available in the default extensions set.
vscodeExtensions = with super.vscode-extensions; [
ms-vscode.cpptools
];
};
}
However, this removes all existing plugins, from VSCode and prevents you from installing them via VSCode Marketplace.
We can also work around this, by declaring every extension in our above setup.
This is where the problem arises, in my opinion, for every unpackaged extension, I have to declare it, include the commit and if I want to update I need to modify the commit hash.
It seems unfeasible for me to update manually the commit hash of each package that I want to update.
Are my observations correct?
Could I automate the updating of plugins?
Can I install cpptools without declaring it explicitly in a vscode-with-extensions?
Good you’ve mentioned you are using NixOS (because my method won’t work with plain Nix)
My recipe for this is to install extensions imperatively. In those rare cases when it is not possible (cpptools requires some native libs, lucky it is packaged in Nixpkgs), use this module:
vscode.nix
{ config, pkgs, lib, ... }: {
options = {
vscode.extensions = lib.mkOption { default = []; };
vscode.user = lib.mkOption { }; # <- Must be supplied
vscode.homeDir = lib.mkOption { }; # <- Must be supplied
nixpkgs.latestPackages = lib.mkOption { default = []; };
};
config = {
###
# DIRTY HACK
# This will fetch latest packages on each rebuild, whatever channel you are at
nixpkgs.overlays = [
(self: super:
let latestPkgs = import (fetchTarball https://github.com/nixos/nixpkgs-channels/archive/nixpkgs-unstable.tar.gz) {
config.allowUnfree = true;
};
in lib.genAttrs config.nixpkgs.latestPackages (pkg: latestPkgs."${pkg}")
)
];
# END DIRTY HACK
###
environment.systemPackages = [ pkgs.vscode ];
system.activationScripts.fix-vscode-extensions = {
text = ''
EXT_DIR=${config.vscode.homeDir}/.vscode/extensions
mkdir -p $EXT_DIR
chown ${config.vscode.user}:users $EXT_DIR
for x in ${lib.concatMapStringsSep " " toString config.vscode.extensions}; do
ln -sf $x/share/vscode/extensions/* $EXT_DIR/
done
chown -R ${config.vscode.user}:users $EXT_DIR
'';
deps = [];
};
};
}
“Dirty hack” will never become “official”. For example, I’ve had to revert the abovementioned “fetch latest VScode” hack from my configuration. Why? It crashed sometimes, probably due to essential impurities: glibc mismatch, protocols mismatch, kernel mismatch, whatnot. I think, it crashed only because of this update, not because VSCode has an actual bug.
Another example is calibre - latest calibre crashes for me on opening file, but I suppose it crashes only for me. And will no longer crash after system update.
It is also nightmare to debug such cases, so better to stick to packages coherent with system.
Then the problem persists, how can I install packages over nix, while also maintaining the “ease of use” of querying for packages in the editor and installing them?
Oh, no. latest Nix package and VScode extensions live in different worlds. You still can use second part of my solution above. Just remove nixpkgs.latestPackages part from configuration.
Yes, you’ll have slightly outdated VSCode. But maybe better to switch to nixos-unstable channel and update your system periodically (nixos-rebuild switch --upgrade or nixos-rebuild boot --upgrade && reboot)? This would solve your other issue as well.
In the meantime, one might be tempted to write a companion helper to vscode-with-extensions which instead of passing the --extension-dir argument in its wrapper, dynamically creates symlinks to each nix provided extension before launching vscode.
I think that the problem is that you’re installing vscode under systemPackages, which correlates to the root user.
The first part of the error seems to indicate that vscode is trying to write to a location in the nix store, which is not writable other than by the root user. I’m not sure if the second part of the error is actually accurate.
If you move the vscode config from environment.systemPackages to user.users.<your user>.packages, then it should work for your user. That’s how I currently have it set up. Or otherwise use home manager, which I’m about to try instead. I think one difference between using the user section of environment.config vs home manager would be the ability to rollback easily, but not entirely sure actually.
If you have multiple users and want to have vscode globally, then I think you’ll have to create shell aliases or something to launch code and supply a --user-data-dir to the command line, which should cause vscode to store the extensions, config, and other things in a directory in the user’s own home folder.
Yes, while adding vscode to user packages the error was gone and it worked. Nevertheless, when adding extensions to my config vscode crashed on start up without an error. Weird. Using home-manager did the trick and it is working also with vscode extensions. Thanks for your replies.