1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 19:46:05 +01:00

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 <andre4ik3@fastmail.com>
This commit is contained in:
Ross Brunton 2025-10-04 03:20:39 +00:00 committed by Robert Helgesson
parent 817ace497b
commit 03f83f513d
No known key found for this signature in database
GPG key ID: 96E745BD17AA17ED

View file

@ -22,29 +22,58 @@ let
jsonFormat = pkgs.formats.json { }; jsonFormat = pkgs.formats.json { };
configDir = productInfoPath =
{ if
"vscode" = "Code"; lib.pathExists "${cfg.package}/Applications/${
"vscode-insiders" = "Code - Insiders"; cfg.package.passthru.longName or "Code"
"vscodium" = "VSCodium"; }.app/Contents/Resources/app/product.json"
"openvscode-server" = "OpenVSCode Server"; then
"windsurf" = "Windsurf"; "${cfg.package}/Applications/${
"cursor" = "Cursor"; cfg.package.passthru.longName or "Code"
"kiro" = "Kiro"; }.app/Contents/Resources/app/product.json"
} else if lib.pathExists "${cfg.package}/lib/vscode/resources/app/product.json" then
.${vscodePname}; # Visual Studio Code, VSCodium, Windsurf, Cursor
"${cfg.package}/lib/vscode/resources/app/product.json"
else
# OpenVSCode Server
"${cfg.package}/product.json";
extensionDir = productInfo = lib.importJSON productInfoPath;
{
"vscode" = "vscode"; # Use preset names for known products to avoid IFD loading it from product.json
"vscode-insiders" = "vscode-insiders"; knownProducts = {
"vscodium" = "vscode-oss"; cursor = {
"openvscode-server" = "openvscode-server"; dataFolderName = ".cursor";
"windsurf" = "windsurf"; nameShort = "Cursor";
"cursor" = "cursor"; };
"kiro" = "kiro"; kiro = {
} dataFolderName = ".kiro";
.${vscodePname}; nameShort = "Kiro";
};
openvscode-server = {
dataFolderName = ".openvscode-server";
nameShort = "OpenVSCode Server";
};
vscode = {
dataFolderName = ".vscode";
nameShort = "Code";
};
vscode-insiders = {
dataFolderName = ".vscode-insiders";
nameShort = "Code - Insiders";
};
vscodium = {
dataFolderName = ".vscode-oss";
nameShort = "VSCodium";
};
windsurf = {
dataFolderName = ".windsurf";
nameShort = "Windsurf";
};
};
configDir = cfg.nameShort;
extensionDir = cfg.dataFolderName;
userDir = userDir =
if pkgs.stdenv.hostPlatform.isDarwin then if pkgs.stdenv.hostPlatform.isDarwin then
@ -62,8 +91,7 @@ let
snippetDir = name: "${userDir}/${optionalString (name != "default") "profiles/${name}/"}snippets"; snippetDir = name: "${userDir}/${optionalString (name != "default") "profiles/${name}/"}snippets";
# TODO: On Darwin where are the extensions? extensionPath = "${extensionDir}/extensions";
extensionPath = ".${extensionDir}/extensions";
extensionJson = ext: pkgs.vscode-utils.toExtensionJson ext; extensionJson = ext: pkgs.vscode-utils.toExtensionJson ext;
extensionJsonFile = extensionJsonFile =
@ -319,6 +347,30 @@ in
''; '';
}; };
nameShort = mkOption {
type = types.str;
default = knownProducts.${vscodePname}.nameShort or productInfo.nameShort;
defaultText = "(derived from product.json)";
example = "MyCoolVSCodeFork";
description = ''
Override for package "short name", used for generating configuration.
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.
'';
};
dataFolderName = mkOption {
type = types.str;
default = knownProducts.${vscodePname}.dataFolderName or productInfo.dataFolderName;
defaultText = "(derived from product.json)";
example = ".cool-vscode";
description = ''
Override for extensions directory.
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.
'';
};
profiles = mkOption { profiles = mkOption {
type = types.attrsOf profileType; type = types.attrsOf profileType;
default = { }; default = { };