old
  1{
  2  config,
  3  lib,
  4  pkgs,
  5  ...
  6}: let
  7  inherit (lib.lists) concatLists;
  8
  9  homeDir = config.home.homeDirectory;
 10  dataDir = config.xdg.dataHome;
 11  userDataDir = "${dataDir}/vscode/data";
 12  extensionsDir = "${dataDir}/vscode/extensions";
 13
 14  pkg = pkgs.vscode.override {
 15    commandLineArgs = concatLists [
 16      ["--extensions-dir" extensionsDir]
 17      ["--user-data-dir" userDataDir]
 18      ["--locale" "zh-cn"]
 19      ["--ozone-platform-hint=auto"]
 20      ["--enable-wayland-ime"]
 21      ["--wayland-text-input-version=3"]
 22    ];
 23  };
 24in {
 25  imports = [./profiles];
 26
 27  programs.vscode = {
 28    enable = true;
 29    package = pkg;
 30    mutableExtensionsDir = false;
 31  };
 32
 33  # To solve VSCode wants to write settings.json
 34  # VSCode will reset per reboot/rebuild.
 35  systemd.user.services.vscode-setup = {
 36    Unit = {
 37      Description = "VSCode Setup service";
 38      After = ["graphical-session-pre.target"];
 39      Wants = ["graphical-session-pre.target"];
 40    };
 41    Install.WantedBy = ["graphical-session.target"];
 42    Service = {
 43      Type = "oneshot";
 44      UMask = "0022";
 45      ExecStart = lib.getExe (pkgs.writeShellApplication {
 46        name = "vscode-setup";
 47        runtimeInputs = with pkgs; [coreutils gnutar jq];
 48        text = let
 49          userSrc = "${homeDir}/.config/Code/User";
 50          userDst = "${userDataDir}/User";
 51          extSrc = "${homeDir}/.vscode/extensions";
 52          extDst = extensionsDir;
 53
 54          dirsToPreserve = [
 55            "workspaceStorage"
 56            "History"
 57          ];
 58          backupCmds = builtins.concatStringsSep "\n" (map (dir: ''
 59              if [ -e "${userDst}/${dir}" ]; then
 60                echo "Backing up data/User/${dir}..."
 61                mv "${userDst}/${dir}" "/tmp/vscode-${dir}-$$"
 62              fi
 63            '')
 64            (dirsToPreserve ++ ["globalStorage"]));
 65          restoreCmds = builtins.concatStringsSep "\n" (map (dir: ''
 66              if [ -e "/tmp/vscode-${dir}-$$" ]; then
 67                echo "Restoring data/User/${dir}..."
 68                mv "/tmp/vscode-${dir}-$$" "${userDst}/${dir}"
 69              fi
 70            '')
 71            dirsToPreserve);
 72        in ''
 73          set -eu
 74
 75          ${backupCmds}
 76
 77          echo "Cleaning old directories..."
 78          rm -rf "${userDst}"
 79          rm -rf "${extDst}"
 80
 81          mkdir -p "${userDataDir}"
 82          mkdir -p "${extDst}"
 83
 84          echo "Copying user settings from ${userSrc}..."
 85          cp -r --dereference --no-preserve=mode,ownership ${userSrc} "${userDst}"
 86
 87          echo "Copying extensions from ${extSrc}..."
 88          tar -h -C "${extSrc}" -cf - . | tar -C "${extDst}" -xf - --no-same-owner --no-same-permissions --mode='u=rX,go=rX'
 89          chmod u+w -R "${extDst}" 2>/dev/null || true
 90
 91          ${restoreCmds}
 92
 93          echo "Restoring and merging data/User/globalStorage..."
 94          if [ -e "/tmp/vscode-globalStorage-$$" ]; then
 95            cp -rT "/tmp/vscode-globalStorage-$$" "${userDst}/globalStorage"
 96
 97            src_storage_json="${userSrc}/globalStorage/storage.json"
 98            dst_storage_json="${userDst}/globalStorage/storage.json"
 99
100            if [ -f "$src_storage_json" ] && [ -f "$dst_storage_json" ]; then
101              echo "Merging data/globalStorage/storage.json with new data..."
102              merged_json=$(mktemp)
103              jq -s '.[0] * .[1]' "$dst_storage_json" "$src_storage_json" > "$merged_json"
104              mv "$merged_json" "$dst_storage_json"
105              echo "Merge complete."
106            else
107              echo "Skipping storage.json merge: one or both files do not exist."
108            fi
109          else
110            echo "No backed-up globalStorage found to restore."
111          fi
112
113          echo "VSCode setup complete."
114        '';
115      });
116    };
117  };
118}