···1+{ stdenv, lib, fetchurl, runCommand, buildEnv, vscode, which, writeScript
2+, vscodeExtensions ? [] }:
3+4+/*
5+ `vsixExtensions`
6+ : A set of vscode extensions to be installed alongside the editor. Here's a an
7+ example:
8+9+ ~~~
10+ vscode-with-extensions.override {
11+12+ # When the extension is already available in the default extensions set.
13+ vscodeExtensions = with vscodeExtensions; [
14+ nix
15+ ]
16+17+ # Concise version from the vscode market place when not available in the default set.
18+ ++ vscodeUtils.extensionsFromVscodeMarketplace [
19+ {
20+ name = "code-runner";
21+ publisher = "formulahendry";
22+ version = "0.6.33";
23+ sha256 = "166ia73vrcl5c9hm4q1a73qdn56m0jc7flfsk5p5q41na9f10lb0";
24+ }
25+ ];
26+ }
27+ ~~~
28+29+ This expression should fetch
30+ - the *nix* vscode extension from whatever source defined in the
31+ default nixpkgs extensions set `vscodeExtensions`.
32+33+ - the *code-runner* vscode extension from the marketplace using the
34+ following url:
35+36+ ~~~
37+ https://bbenoist.gallery.vsassets.io/_apis/public/gallery/publisher/bbenoist/extension/nix/1.0.1/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage
38+ ~~~
39+40+ The original `code` executable will be wrapped so that it uses the set of pre-installed / unpacked
41+ extensions as its `--extensions-dir`.
42+*/
43+44+let
45+46+ wrappedPkgVersion = lib.getVersion vscode;
47+ wrappedPkgName = lib.removeSuffix "-${wrappedPkgVersion}" vscode.name;
48+49+ combinedExtensionsDrv = buildEnv {
50+ name = "${wrappedPkgName}-extensions-${wrappedPkgVersion}";
51+ paths = vscodeExtensions;
52+ };
53+54+ wrappedExeName = "code";
55+ exeName = wrappedExeName;
56+57+ wrapperExeFile = writeScript "${exeName}" ''
58+ #!${stdenv.shell}
59+ exec ${vscode}/bin/${wrappedExeName} \
60+ --extensions-dir "${combinedExtensionsDrv}/share/${wrappedPkgName}/extensions" \
61+ "$@"
62+ '';
63+64+in
65+66+# When no extensions are requested, we simply redirect to the original
67+# non-wrapped vscode executable.
68+runCommand "${wrappedPkgName}-with-extensions-${wrappedPkgVersion}" {
69+ buildInputs = [ vscode which ];
70+ dontPatchELF = true;
71+ dontStrip = true;
72+ meta = vscode.meta;
73+} ''
74+ mkdir -p "$out/bin"
75+ ${if [] == vscodeExtensions
76+ then ''
77+ ln -sT "${vscode}/bin/${wrappedExeName}" "$out/bin/${exeName}"
78+ ''
79+ else ''
80+ ln -sT "${wrapperExeFile}" "$out/bin/${exeName}"
81+ ''}
82+''