summary refs log tree commit diff
path: root/pkgs/misc/vscode-extensions
diff options
context:
space:
mode:
authorOren Rozen <countoren@gmail.com>2020-05-25 16:55:10 -0500
committerOren Rozen <countoren@gmail.com>2020-05-25 16:55:10 -0500
commit4d58f006ff4a6bdedcce793057c8533d8e73ed2a (patch)
tree1bc0ea96b367947522d2bfedc5fe5f00536c8121 /pkgs/misc/vscode-extensions
parente708176d43f11823054d07a1ad8db79e8e5e291c (diff)
parent673b122836136e58842b316bcb49158c8322132a (diff)
downloadnixpkgs-4d58f006ff4a6bdedcce793057c8533d8e73ed2a.tar
nixpkgs-4d58f006ff4a6bdedcce793057c8533d8e73ed2a.tar.gz
nixpkgs-4d58f006ff4a6bdedcce793057c8533d8e73ed2a.tar.bz2
nixpkgs-4d58f006ff4a6bdedcce793057c8533d8e73ed2a.tar.lz
nixpkgs-4d58f006ff4a6bdedcce793057c8533d8e73ed2a.tar.xz
nixpkgs-4d58f006ff4a6bdedcce793057c8533d8e73ed2a.tar.zst
nixpkgs-4d58f006ff4a6bdedcce793057c8533d8e73ed2a.zip
Merge branch 'updateSettings' into vscode-utils/vscodeEnv
Diffstat (limited to 'pkgs/misc/vscode-extensions')
-rw-r--r--pkgs/misc/vscode-extensions/cpptools/default.nix4
-rw-r--r--pkgs/misc/vscode-extensions/default.nix27
-rw-r--r--pkgs/misc/vscode-extensions/python/default.nix33
-rw-r--r--pkgs/misc/vscode-extensions/remote-ssh/default.nix55
-rw-r--r--pkgs/misc/vscode-extensions/rust-analyzer/build-deps/package.json22
-rw-r--r--pkgs/misc/vscode-extensions/rust-analyzer/default.nix50
-rw-r--r--pkgs/misc/vscode-extensions/updateSettings.nix39
-rw-r--r--pkgs/misc/vscode-extensions/updateSettingsTest.nix6
-rw-r--r--pkgs/misc/vscode-extensions/vscode-utils.nix12
-rw-r--r--pkgs/misc/vscode-extensions/vscodeEnv.nix51
-rw-r--r--pkgs/misc/vscode-extensions/vscodeEnvTest.nix12
-rw-r--r--pkgs/misc/vscode-extensions/vscodeWithConfiguration.nix22
-rw-r--r--pkgs/misc/vscode-extensions/wakatime/default.nix4
13 files changed, 305 insertions, 32 deletions
diff --git a/pkgs/misc/vscode-extensions/cpptools/default.nix b/pkgs/misc/vscode-extensions/cpptools/default.nix
index 08fee83d8ce..77cf28c552e 100644
--- a/pkgs/misc/vscode-extensions/cpptools/default.nix
+++ b/pkgs/misc/vscode-extensions/cpptools/default.nix
@@ -83,8 +83,8 @@ vscode-utils.buildVscodeMarketplaceExtension {
   mktplcRef = {
     name = "cpptools";
     publisher = "ms-vscode";
-    version = "0.26.1";
-    sha256 = "09khm0byxa9mv8qbqrikd7akz3p816ra5z8l86xqkmbm6j1k4wpc";
+    version = "0.27.0";
+    sha256 = "06l25fjlcj0m7f7883afbh0x2ikgkqi768kv8y4qi1jc1gxndpm0";
   };
 
   buildInputs = [
diff --git a/pkgs/misc/vscode-extensions/default.nix b/pkgs/misc/vscode-extensions/default.nix
index 5d4fafacadd..433371e079e 100644
--- a/pkgs/misc/vscode-extensions/default.nix
+++ b/pkgs/misc/vscode-extensions/default.nix
@@ -122,6 +122,8 @@ in
 
   ms-vscode.cpptools = callPackage ./cpptools {};
 
+  ms-vscode-remote.remote-ssh = callPackage ./remote-ssh {};
+
   ms-python.python = callPackage ./python {
     extractNuGet = callPackage ./python/extract-nuget.nix { };
   };
@@ -138,6 +140,31 @@ in
     };
   };
 
+  matklad.rust-analyzer = callPackage ./rust-analyzer {};
+
+  scala-lang.scala = buildVscodeMarketplaceExtension {
+    mktplcRef = {
+      name = "scala";
+      publisher = "scala-lang";
+      version = "0.3.8";
+      sha256 = "17dl10m3ayf57sqgil4mr9fjdm7i8gb5clrs227b768pp2d39ll9";
+    };
+    meta = {
+      license = stdenv.lib.licenses.mit;
+    };
+  };
+
+  scalameta.metals = buildVscodeMarketplaceExtension {
+    mktplcRef = {
+      name = "metals";
+      publisher = "scalameta";
+      version = "1.6.3";
+      sha256 = "1mc3awybzd2ql1b86inirhsw3j2c7cs0b0nvbjp38jjpq674bmj7";
+    };
+    meta = {
+      license = stdenv.lib.licenses.asl20;
+    };
+  };
 
   skyapps.fish-vscode = buildVscodeMarketplaceExtension {
     mktplcRef = {
diff --git a/pkgs/misc/vscode-extensions/python/default.nix b/pkgs/misc/vscode-extensions/python/default.nix
index 00f97f37307..8f5a92e4722 100644
--- a/pkgs/misc/vscode-extensions/python/default.nix
+++ b/pkgs/misc/vscode-extensions/python/default.nix
@@ -1,18 +1,18 @@
 { lib, stdenv, fetchurl, vscode-utils, extractNuGet
 , icu, curl, openssl, lttng-ust, autoPatchelfHook
-, pythonUseFixed ? false, python  # When `true`, the python default setting will be fixed to specified.
-                                  # Use version from `PATH` for default setting otherwise.
-                                  # Defaults to `false` as we expect it to be project specific most of the time.
-, ctagsUseFixed ? true, ctags     # When `true`, the ctags default setting will be fixed to specified.
-                                  # Use version from `PATH` for default setting otherwise.
-                                  # Defaults to `true` as usually not defined on a per projet basis.
+, python3
+, pythonUseFixed ? false       # When `true`, the python default setting will be fixed to specified.
+                               # Use version from `PATH` for default setting otherwise.
+                               # Defaults to `false` as we expect it to be project specific most of the time.
+, ctagsUseFixed ? true, ctags  # When `true`, the ctags default setting will be fixed to specified.
+                               # Use version from `PATH` for default setting otherwise.
+                               # Defaults to `true` as usually not defined on a per projet basis.
 }:
 
-assert pythonUseFixed -> null != python;
 assert ctagsUseFixed -> null != ctags;
 
 let
-  pythonDefaultsTo = if pythonUseFixed then "${python}/bin/python" else "python";
+  pythonDefaultsTo = if pythonUseFixed then "${python3}/bin/python" else "python";
   ctagsDefaultsTo = if ctagsUseFixed then "${ctags}/bin/ctags" else "ctags";
 
   # The arch tag comes from 'PlatformName' defined here:
@@ -23,14 +23,14 @@ let
     else throw "Only x86_64 Linux and Darwin are supported.";
 
   languageServerSha256 = {
-    linux-x64 = "1w3y0sn6ijk1vspi4lailg1q1iy9lwslhx92c7jbrrkiaszvaqwn";
-    osx-x64 = "11l4fic8cvgh1l3dq6qxi51pwhcic79zf13rhyajl5w5g13caafp";
+    linux-x64 = "1pmj5pb4xylx4gdx4zgmisn0si59qx51n2m1bh7clv29q6biw05n";
+    osx-x64 = "0ishiy1z9dghj4ryh95vy8rw0v7q4birdga2zdb4a8am31wmp94b";
   }.${arch};
 
   # version is languageServerVersion in the package.json
   languageServer = extractNuGet rec {
     name = "Python-Language-Server";
-    version = "0.4.24";
+    version = "0.5.30";
 
     src = fetchurl {
       url = "https://pvsc.azureedge.net/python-language-server-stable/${name}-${arch}.${version}.nupkg";
@@ -41,8 +41,8 @@ in vscode-utils.buildVscodeMarketplaceExtension {
   mktplcRef = {
     name = "python";
     publisher = "ms-python";
-    version = "2019.10.44104";
-    sha256 = "1k0wws430psrl8zp9ky5mifbg02qmh2brjyqk5k9pn3y1dks5gns";
+    version = "2020.3.71659";
+    sha256 = "1smhnhkfchmljz8aj1br70023ysgd2hj6pm1ncn1jxphf89qi1ja";
   };
 
   buildInputs = [
@@ -54,6 +54,11 @@ in vscode-utils.buildVscodeMarketplaceExtension {
 
   nativeBuildInputs = [
     autoPatchelfHook
+    python3.pkgs.wrapPython
+  ];
+
+  pythonPath = with python3.pkgs; [
+    setuptools
   ];
 
   postPatch = ''
@@ -70,6 +75,8 @@ in vscode-utils.buildVscodeMarketplaceExtension {
     mkdir -p "$out/$installPrefix/languageServer.${languageServer.version}"
     cp -R --no-preserve=ownership ${languageServer}/* "$out/$installPrefix/languageServer.${languageServer.version}"
     chmod -R +wx "$out/$installPrefix/languageServer.${languageServer.version}"
+
+    patchPythonScript "$out/$installPrefix/pythonFiles/lib/python/isort/main.py"
   '';
 
   meta = with lib; {
diff --git a/pkgs/misc/vscode-extensions/remote-ssh/default.nix b/pkgs/misc/vscode-extensions/remote-ssh/default.nix
new file mode 100644
index 00000000000..e58ea98a606
--- /dev/null
+++ b/pkgs/misc/vscode-extensions/remote-ssh/default.nix
@@ -0,0 +1,55 @@
+{ stdenv
+, vscode-utils
+, useLocalExtensions ? false}:
+# Note that useLocalExtensions requires that vscode-server is not running
+# on host. If it is, you'll need to remove ~/.vscode-server,
+# and redo the install by running "Connect to host" on client
+
+let
+  inherit (vscode-utils) buildVscodeMarketplaceExtension;
+
+  # patch runs on remote machine hence use of which
+  # links to local node if version is 12
+  patch = ''
+    f="/home/''$USER/.vscode-server/bin/''$COMMIT_ID/node"
+    localNodePath=''$(which node)
+    if [ -x "''$localNodePath" ]; then
+      localNodeVersion=''$(node -v)
+      if [ "\''${localNodeVersion:1:2}" = "12" ]; then
+        echo PATCH: replacing ''$f with ''$localNodePath
+        rm ''$f
+        ln -s ''$localNodePath ''$f
+      fi
+    fi
+    ${stdenv.lib.optionalString useLocalExtensions ''
+      # Use local extensions
+      if [ -d ~/.vscode/extensions ]; then
+        if ! test -L "~/.vscode-server/extensions"; then
+          mkdir -p ~/.vscode-server
+          ln -s ~/.vscode/extensions ~/.vscode-server/
+        fi
+      fi
+    ''}
+  '';
+in
+  buildVscodeMarketplaceExtension {
+    mktplcRef = {
+      name = "remote-ssh";
+      publisher = "ms-vscode-remote";
+      version = "0.50.0";
+      sha256 = "01pyd6759p5nkjhjy3iplrl748xblr54l1jphk2g02s1n5ds2qb9";
+    };
+
+    postPatch = ''
+      substituteInPlace "out/extension.js" \
+        --replace "# install extensions" '${patch}'
+    '';
+
+    meta = with stdenv.lib; {
+      description ="Use any remote machine with a SSH server as your development environment.";
+      license = licenses.unfree;
+      maintainers = with maintainers; [
+        tbenst
+      ];
+    };
+  }
diff --git a/pkgs/misc/vscode-extensions/rust-analyzer/build-deps/package.json b/pkgs/misc/vscode-extensions/rust-analyzer/build-deps/package.json
new file mode 100644
index 00000000000..5769db505d8
--- /dev/null
+++ b/pkgs/misc/vscode-extensions/rust-analyzer/build-deps/package.json
@@ -0,0 +1,22 @@
+{
+  "name": "rust-analyzer",
+  "version": "0.4.0-dev",
+  "dependencies": {
+    "jsonc-parser": "^2.2.1",
+    "node-fetch": "^2.6.0",
+    "vscode-languageclient": "6.1.3",
+    "@rollup/plugin-commonjs": "^11.0.2",
+    "@rollup/plugin-node-resolve": "^7.1.1",
+    "@types/node": "^12.12.34",
+    "@types/node-fetch": "^2.5.5",
+    "@types/vscode": "1.43.0",
+    "@typescript-eslint/eslint-plugin": "^2.26.0",
+    "@typescript-eslint/parser": "^2.26.0",
+    "eslint": "^6.8.0",
+    "rollup": "^2.3.2",
+    "tslib": "^1.11.1",
+    "typescript": "^3.8.3",
+    "typescript-formatter": "^7.2.2",
+    "vsce": "^1.75.0"
+  }
+}
diff --git a/pkgs/misc/vscode-extensions/rust-analyzer/default.nix b/pkgs/misc/vscode-extensions/rust-analyzer/default.nix
new file mode 100644
index 00000000000..230ee383af3
--- /dev/null
+++ b/pkgs/misc/vscode-extensions/rust-analyzer/default.nix
@@ -0,0 +1,50 @@
+# Update script: pkgs/development/tools/rust/rust-analyzer/update.sh
+{ lib, stdenv, vscode-utils, jq, rust-analyzer, nodePackages_10_x
+, setDefaultServerPath ? true
+}:
+
+let
+  pname = "rust-analyzer";
+  publisher = "matklad";
+
+  # Follow the unstable version of rust-analyzer, since the extension is not stable yet.
+  inherit (rust-analyzer) version;
+
+  build-deps = nodePackages_10_x."rust-analyzer-build-deps-../../misc/vscode-extensions/rust-analyzer/build-deps";
+  # FIXME: Making a new derivation to link `node_modules` and run `npm run package`
+  # will cause a build failure.
+  vsix = build-deps.override {
+    src = "${rust-analyzer.src}/editors/code";
+    outputs = [ "vsix" "out" ];
+
+    postInstall = ''
+      npm run package
+      mkdir $vsix
+      cp ${pname}.vsix $vsix/${pname}.zip
+    '';
+  };
+
+in vscode-utils.buildVscodeExtension {
+  inherit version vsix;
+  name = "${pname}-${version}";
+  src = "${vsix}/${pname}.zip";
+  vscodeExtUniqueId = "${publisher}.${pname}";
+
+  nativeBuildInputs = lib.optional setDefaultServerPath jq;
+
+  postFixup = lib.optionalString setDefaultServerPath ''
+    package_json="$out/${publisher}.${pname}/package.json"
+    jq '.contributes.configuration.properties."rust-analyzer.serverPath".default = $s' \
+      --arg s "${rust-analyzer}/bin/rust-analyzer" \
+      $package_json >$package_json.new
+    mv $package_json.new $package_json
+  '';
+
+  meta = with lib; {
+    description = "An alternative rust language server to the RLS";
+    homepage = "https://github.com/rust-analyzer/rust-analyzer";
+    license = with licenses; [ mit asl20 ];
+    maintainers = with maintainers; [ oxalica ];
+    platforms = platforms.all;
+  };
+}
diff --git a/pkgs/misc/vscode-extensions/updateSettings.nix b/pkgs/misc/vscode-extensions/updateSettings.nix
new file mode 100644
index 00000000000..a033229c589
--- /dev/null
+++ b/pkgs/misc/vscode-extensions/updateSettings.nix
@@ -0,0 +1,39 @@
+# Updates the vscode setting file base on a nix expression
+# should run from the workspace root.
+{ writeShellScriptBin
+, lib
+, jq
+}:
+##User Input
+{ settings      ? {}
+# if marked as true will create an empty json file if does not exists
+, createIfDoesNotExists ? true
+, vscodeSettingsFile ? ".vscode/settings.json"
+, userSettingsFolder ? ""
+, symlinkFromUserSetting ? false
+}:
+let
+
+  updateVSCodeSettingsCmd = ''
+  (
+    echo 'updateSettings.nix: Updating ${vscodeSettingsFile}...' 
+    oldSettings=$(cat ${vscodeSettingsFile})
+    echo $oldSettings' ${builtins.toJSON settings}' | ${jq}/bin/jq -s add > ${vscodeSettingsFile}
+  )'';
+
+  createEmptySettingsCmd = ''mkdir -p .vscode && echo "{}" > ${vscodeSettingsFile}'';
+  fileName = builtins.baseNameOf vscodeSettingsFile;
+  symlinkFromUserSettingCmd = lib.optionalString symlinkFromUserSetting
+    '' && mkdir -p "${userSettingsFolder}" && ln -sfv "$(pwd)/${vscodeSettingsFile}" "${userSettingsFolder}/" '';
+in 
+
+  writeShellScriptBin ''vscodeNixUpdate-${lib.removeSuffix ".json" (fileName)}''
+  (lib.optionalString (settings != {}) 
+    (if createIfDoesNotExists then ''
+      [ ! -f "${vscodeSettingsFile}" ] && ${createEmptySettingsCmd}
+      ${updateVSCodeSettingsCmd} ${symlinkFromUserSettingCmd}
+    ''
+    else ''[ -f "${vscodeSettingsFile}" ] && ${updateVSCodeSettingsCmd} ${symlinkFromUserSettingCmd}
+    ''
+    )
+  )
diff --git a/pkgs/misc/vscode-extensions/updateSettingsTest.nix b/pkgs/misc/vscode-extensions/updateSettingsTest.nix
new file mode 100644
index 00000000000..097b9cad166
--- /dev/null
+++ b/pkgs/misc/vscode-extensions/updateSettingsTest.nix
@@ -0,0 +1,6 @@
+with import <nixpkgs>{};
+callPackage (import ./updateSettings.nix) {} {
+  settings = {
+    a = "fdsdf";
+  };
+}
diff --git a/pkgs/misc/vscode-extensions/vscode-utils.nix b/pkgs/misc/vscode-extensions/vscode-utils.nix
index b4c1fda5e6e..743ae13a3e4 100644
--- a/pkgs/misc/vscode-extensions/vscode-utils.nix
+++ b/pkgs/misc/vscode-extensions/vscode-utils.nix
@@ -1,5 +1,4 @@
-{ stdenv, lib, buildEnv, writeShellScriptBin, fetchurl, vscode, unzip }:
-
+{ stdenv, lib, buildEnv, writeShellScriptBin, fetchurl, vscode, unzip, jq }:
 let
   extendedPkgVersion = lib.getVersion vscode;
   extendedPkgName = lib.removeSuffix "-${extendedPkgVersion}" vscode.name;
@@ -48,12 +47,15 @@ let
   buildVscodeMarketplaceExtension = a@{
     name ? "",
     src ? null,
+    vsix ? null,
     mktplcRef,
     ...
   }: assert "" == name; assert null == src;
-  buildVscodeExtension ((removeAttrs a [ "mktplcRef" ]) // {
+  buildVscodeExtension ((removeAttrs a [ "mktplcRef" "vsix" ]) // {
     name = "${mktplcRef.publisher}-${mktplcRef.name}-${mktplcRef.version}";
-    src = fetchVsixFromVscodeMarketplace mktplcRef;
+    src = if (vsix != null)
+      then vsix
+      else fetchVsixFromVscodeMarketplace mktplcRef;
     vscodeExtUniqueId = "${mktplcRef.publisher}.${mktplcRef.name}";
   });
 
@@ -85,7 +87,7 @@ let
   };
 
   vscodeEnv = import ./vscodeEnv.nix {
-    inherit lib buildEnv writeShellScriptBin extensionsFromVscodeMarketplace;
+    inherit lib buildEnv writeShellScriptBin extensionsFromVscodeMarketplace jq;
     vscodeDefault = vscode;
   };
 in 
diff --git a/pkgs/misc/vscode-extensions/vscodeEnv.nix b/pkgs/misc/vscode-extensions/vscodeEnv.nix
index b2f717ccc3e..6e4bb7b3ea8 100644
--- a/pkgs/misc/vscode-extensions/vscodeEnv.nix
+++ b/pkgs/misc/vscode-extensions/vscodeEnv.nix
@@ -4,11 +4,21 @@
 , writeShellScriptBin
 , extensionsFromVscodeMarketplace
 , vscodeDefault
+, jq
 }:
 ##User input
-{ vscode                ? vscodeDefault
-, nixExtensions         ? []
-, vscodeExtsFolderName  ? ".vscode-exts"
+{ vscode                           ? vscodeDefault
+, nixExtensions                    ? []
+, vscodeExtsFolderName             ? ".vscode-exts"
+# will add to the command updateSettings (which will run on executing vscode) settings to override in settings.json file
+, settings                         ? {}
+, createSettingsIfDoesNotExists    ? true
+, launch                           ? {}
+, createLaunchIfDoesNotExists      ? true
+# will add to the command updateKeybindings(which will run on executing vscode) keybindings to override in keybinding.json file
+, keybindings                      ? {}
+, createKeybindingsIfDoesNotExists ? true
+, user-data-dir ? ''"''${TMP}''${name}"/vscode-data-dir''
 # if file exists will use it and import the extensions in it into this dervation else will use empty extensions list
 # this file will be created/updated by vscodeExts2nix when vscode exists
 , mutableExtensionsFile 
@@ -22,7 +32,35 @@ let
     vscodeDefault = vscode;
   }
   {
-    inherit nixExtensions mutableExtensions vscodeExtsFolderName;
+    inherit nixExtensions mutableExtensions vscodeExtsFolderName user-data-dir;
+  };
+
+  updateSettings = import ./updateSettings.nix { inherit lib writeShellScriptBin jq; };
+  userSettingsFolder = "${ user-data-dir }/User";
+
+  updateSettingsCmd = updateSettings {
+    settings = {
+        "extensions.autoCheckUpdates" = false;
+        "extensions.autoUpdate" = false;
+        "update.mode" = "none";
+    } // settings;
+    inherit userSettingsFolder;
+    createIfDoesNotExists = createSettingsIfDoesNotExists;
+    symlinkFromUserSetting = (user-data-dir != "");
+  };
+
+  updateLaunchCmd = updateSettings {
+    settings = launch;
+    createIfDoesNotExists = createLaunchIfDoesNotExists;
+    vscodeSettingsFile = ".vscode/launch.json";
+  };
+
+  updateKeybindingsCmd = updateSettings {
+    settings = keybindings;
+    createIfDoesNotExists = createKeybindingsIfDoesNotExists;
+    vscodeSettingsFile = ".vscode/keybindings.json";
+    inherit userSettingsFolder;
+    symlinkFromUserSetting = (user-data-dir != "");
   };
 
   vscodeExts2nix = import ./vscodeExts2nix.nix { 
@@ -34,6 +72,9 @@ let
     extensions = mutableExtensions; 
   };
   code = writeShellScriptBin "code" ''
+    ${updateSettingsCmd}/bin/vscodeNixUpdate-settings
+    ${updateLaunchCmd}/bin/vscodeNixUpdate-launch
+    ${updateKeybindingsCmd}/bin/vscodeNixUpdate-keybindings
     ${vscodeWithConfiguration}/bin/code --wait "$@" 
     echo 'running vscodeExts2nix to update ${mutableExtensionsFilePath}...'
     ${vscodeExts2nix}/bin/vscodeExts2nix > ${mutableExtensionsFilePath}
@@ -41,5 +82,5 @@ let
 in
 buildEnv {
   name = "vscodeEnv";
-  paths = [ code vscodeExts2nix ];
+  paths = [ code vscodeExts2nix updateSettingsCmd updateLaunchCmd updateKeybindingsCmd ];
 }
diff --git a/pkgs/misc/vscode-extensions/vscodeEnvTest.nix b/pkgs/misc/vscode-extensions/vscodeEnvTest.nix
new file mode 100644
index 00000000000..d7e586cab6e
--- /dev/null
+++ b/pkgs/misc/vscode-extensions/vscodeEnvTest.nix
@@ -0,0 +1,12 @@
+with import <nixpkgs>{};
+callPackage (import ./vscodeEnv.nix) { 
+  extensionsFromVscodeMarketplace = vscode-utils.extensionsFromVscodeMarketplace;
+  vscodeDefault = vscode;
+} {
+  mutableExtensionsFile = ./extensions.nix;
+  settings = {
+    a = "fdsdf";
+    t = "test";
+  };
+}
+
diff --git a/pkgs/misc/vscode-extensions/vscodeWithConfiguration.nix b/pkgs/misc/vscode-extensions/vscodeWithConfiguration.nix
index 0ad32392192..83cf84586b8 100644
--- a/pkgs/misc/vscode-extensions/vscodeWithConfiguration.nix
+++ b/pkgs/misc/vscode-extensions/vscodeWithConfiguration.nix
@@ -11,10 +11,17 @@
 # extensions to be copied into the project's extensions folder
 , mutableExtensions    ? []        
 , vscodeExtsFolderName ? ".vscode-exts"        
+, user-data-dir ? ''"''${TMP}vscodeWithConfiguration/vscode-data-dir"''
 }:
 let 
   nixExtsDrvs = extensionsFromVscodeMarketplace nixExtensions;
   mutExtsDrvs = extensionsFromVscodeMarketplace mutableExtensions;
+  mutableExtsPaths = lib.forEach mutExtsDrvs ( e: 
+  {
+    origin = ''${e}/share/vscode/extensions/${e.vscodeExtUniqueId}'';
+    target = ''${vscodeExtsFolderName}/${e.vscodeExtUniqueId}-${(lib.findSingle (ext: ''${ext.publisher}.${ext.name}'' == e.vscodeExtUniqueId) "" "m" mutableExtensions ).version}'';
+  }
+  );
 
   #removed not defined extensions
   rmExtensions =  lib.optionalString (nixExtensions++mutableExtensions != []) ''
@@ -23,16 +30,21 @@ let
   #copy mutable extension out of the nix store
   cpExtensions = ''
     ${lib.concatMapStringsSep "\n" (e : ''ln -sfn ${e}/share/vscode/extensions/* ${vscodeExtsFolderName}/'') nixExtsDrvs}
-    ${lib.concatMapStringsSep "\n" (e : ''
-      cp -a ${e}/share/vscode/extensions/${e.vscodeExtUniqueId} ${vscodeExtsFolderName}/${e.vscodeExtUniqueId}-${(lib.findSingle (ext: ''${ext.publisher}.${ext.name}'' == e.vscodeExtUniqueId) "" "m" mutableExtensions ).version}
-      '') mutExtsDrvs} 
+    ${lib.concatMapStringsSep "\n" (ePath : ''
+      if [ ! -d ${ePath.target} ]; then
+        cp -a ${ePath.origin} ${ePath.target}
+        chmod -R u+rwx ${ePath.target}
+      fi
+      '') mutableExtsPaths} 
   '';
 in
   writeShellScriptBin "code" ''
     if ! [[ "$@" =~ "--list-extension" ]]; then 
-      mkdir -p ${vscodeExtsFolderName} 
+      mkdir -p "${vscodeExtsFolderName}" 
       ${rmExtensions}
       ${cpExtensions}
     fi
-    ${vscode}/bin/code --extensions-dir ${vscodeExtsFolderName} "$@"
+    ${vscode}/bin/code --extensions-dir "${vscodeExtsFolderName}" ${ 
+      lib.optionalString (user-data-dir != "") ''--user-data-dir ${user-data-dir }''
+      } "$@"
   ''
diff --git a/pkgs/misc/vscode-extensions/wakatime/default.nix b/pkgs/misc/vscode-extensions/wakatime/default.nix
index da8d940f71c..30b2f94f1a5 100644
--- a/pkgs/misc/vscode-extensions/wakatime/default.nix
+++ b/pkgs/misc/vscode-extensions/wakatime/default.nix
@@ -8,8 +8,8 @@ in
     mktplcRef = {
       name = "vscode-wakatime";
       publisher = "WakaTime";
-      version = "2.2.1";
-      sha256 = "18hdmx993wvhcv13z9p8ylp3lf480axv4lyl0qx52pw2y2jgj1z8";
+      version = "4.0.0";
+      sha256 = "0bwxz8dg00k8frnvkvcngll5yaf9k7z13dg309vmw8xbdgkiyid4";
     };
 
     postPatch = ''