Skip to content

Commit 94e2dea

Browse files
RossBruntonandre4ik3
authored andcommitted
vscode: get paths from product.json
The VSCode packages contain a product.json which is used to determine the extension and config dirs. When the package name is not known, this change parses this file (using IFD) (which may appear in a few places) and uses that to generate the paths. This hopefully allows more VSCode derivatives to "just work" without home-manager updates. Co-authored-by: andre4ik3 <[email protected]>
1 parent 817ace4 commit 94e2dea

File tree

1 file changed

+77
-25
lines changed

1 file changed

+77
-25
lines changed

modules/programs/vscode/default.nix

Lines changed: 77 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,58 @@ let
2222

2323
jsonFormat = pkgs.formats.json { };
2424

25-
configDir =
26-
{
27-
"vscode" = "Code";
28-
"vscode-insiders" = "Code - Insiders";
29-
"vscodium" = "VSCodium";
30-
"openvscode-server" = "OpenVSCode Server";
31-
"windsurf" = "Windsurf";
32-
"cursor" = "Cursor";
33-
"kiro" = "Kiro";
34-
}
35-
.${vscodePname};
36-
37-
extensionDir =
38-
{
39-
"vscode" = "vscode";
40-
"vscode-insiders" = "vscode-insiders";
41-
"vscodium" = "vscode-oss";
42-
"openvscode-server" = "openvscode-server";
43-
"windsurf" = "windsurf";
44-
"cursor" = "cursor";
45-
"kiro" = "kiro";
46-
}
47-
.${vscodePname};
25+
productInfoPath =
26+
if
27+
lib.pathExists "${cfg.package}/Applications/${
28+
cfg.package.passthru.longName or "Code"
29+
}.app/Contents/Resources/app/product.json"
30+
then
31+
"${cfg.package}/Applications/${
32+
cfg.package.passthru.longName or "Code"
33+
}.app/Contents/Resources/app/product.json"
34+
else if lib.pathExists "${cfg.package}/lib/vscode/resources/app/product.json" then
35+
# Visual Studio Code, VSCodium, Windsurf, Cursor
36+
"${cfg.package}/lib/vscode/resources/app/product.json"
37+
else
38+
# OpenVSCode Server
39+
"${cfg.package}/product.json";
40+
41+
productInfo = lib.importJSON productInfoPath;
42+
43+
# Use preset names for known products to avoid IFD loading it from product.json
44+
knownProducts = {
45+
cursor = {
46+
dataFolderName = ".cursor";
47+
nameShort = "Cursor";
48+
};
49+
kiro = {
50+
dataFolderName = ".kiro";
51+
nameShort = "Kiro";
52+
};
53+
openvscode-server = {
54+
dataFolderName = ".openvscode-server";
55+
nameShort = "OpenVSCode Server";
56+
};
57+
vscode = {
58+
dataFolderName = ".vscode";
59+
nameShort = "Code";
60+
};
61+
vscode-insiders = {
62+
dataFolderName = ".vscode-insiders";
63+
nameShort = "Code - Insiders";
64+
};
65+
vscodium = {
66+
dataFolderName = ".vscode-oss";
67+
nameShort = "VSCodium";
68+
};
69+
windsurf = {
70+
dataFolderName = ".windsurf";
71+
nameShort = "Windsurf";
72+
};
73+
};
74+
75+
configDir = cfg.nameShort;
76+
extensionDir = cfg.dataFolderName;
4877

4978
userDir =
5079
if pkgs.stdenv.hostPlatform.isDarwin then
@@ -62,8 +91,7 @@ let
6291

6392
snippetDir = name: "${userDir}/${optionalString (name != "default") "profiles/${name}/"}snippets";
6493

65-
# TODO: On Darwin where are the extensions?
66-
extensionPath = ".${extensionDir}/extensions";
94+
extensionPath = "${extensionDir}/extensions";
6795

6896
extensionJson = ext: pkgs.vscode-utils.toExtensionJson ext;
6997
extensionJsonFile =
@@ -319,6 +347,30 @@ in
319347
'';
320348
};
321349

350+
nameShort = mkOption {
351+
type = types.str;
352+
default = knownProducts.${vscodePname}.nameShort or productInfo.nameShort;
353+
defaultText = "(derived from product.json)";
354+
example = "MyCoolVSCodeFork";
355+
description = ''
356+
Override for package "short name", used for generating configuration.
357+
358+
This should match the `shortName` field in the package's product.json. If `null`, then searches common locations for a product.json and uses the value from there.
359+
'';
360+
};
361+
362+
dataFolderName = mkOption {
363+
type = types.str;
364+
default = knownProducts.${vscodePname}.dataFolderName or productInfo.dataFolderName;
365+
defaultText = "(derived from product.json)";
366+
example = ".cool-vscode";
367+
description = ''
368+
Override for extensions directory.
369+
370+
This should match the `dataFolderName` field in the package's product.json. If `null`, then searches common locations for a product.json and uses the value from there.
371+
'';
372+
};
373+
322374
profiles = mkOption {
323375
type = types.attrsOf profileType;
324376
default = { };

0 commit comments

Comments
 (0)