VSCode extensions setup

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 = [];
        };
    };
}

Then in configuration.nix you add lines:

  imports = [
    ...
    ./vscode.nix
  ];
  vscode.user = "danbst";
  vscode.homeDir = "/home/danbst";
  vscode.extensions = with pkgs.vscode-extensions; [
    ms-vscode.cpptools
  ];
  nixpkgs.latestPackages = [
    "vscode"
    "vscode-extensions"
  ];

And rebuild. What it does:

  • fetches latest nixpkgs-unstable channel on each rebuild
  • uses vscode and extensions from that channel, so up-to-date ASAP
  • links cpptools directly into ~/.vscode/extensions, which fools VScode to think it actually installed this ext
4 Likes