anvil-editor: init at 0.4
[NixPkgs.git] / pkgs / applications / editors / vscode / generic.nix
blob352c25fe1720017b4f96d71b257c1ac99b86e401
1 { stdenv
2 , lib
3 , copyDesktopItems
4 , makeDesktopItem
5 , unzip
6 , libsecret
7 , libXScrnSaver
8 , libxshmfence
9 , buildPackages
10 , at-spi2-atk
11 , autoPatchelfHook
12 , alsa-lib
13 , mesa
14 , nss
15 , nspr
16 , xorg
17 , systemd
18 , fontconfig
19 , libdbusmenu
20 , glib
21 , buildFHSEnv
22 , wayland
23 , libglvnd
24 , libkrb5
26   # Populate passthru.tests
27 , tests
29   # needed to fix "Save as Root"
30 , asar
31 , bash
33   # Attributes inherit from specific versions
34 , version
35 , src
36 , meta
37 , sourceRoot
38 , commandLineArgs
39 , executableName
40 , longName
41 , shortName
42 , pname
43 , updateScript
44 , dontFixup ? false
45 , rev ? null
46 , vscodeServer ? null
47 , sourceExecutableName ? executableName
48 , useVSCodeRipgrep ? false
49 , ripgrep
52 stdenv.mkDerivation (finalAttrs:
53 let
55   # Vscode and variants allow for users to download and use extensions
56   # which often include the usage of pre-built binaries.
57   # This has been an on-going painpoint for many users, as
58   # a full extension update cycle has to be done through nixpkgs
59   # in order to create or update extensions.
60   # See: #83288 #91179 #73810 #41189
61   #
62   # buildFHSEnv allows for users to use the existing vscode
63   # extension tooling without significant pain.
64   fhs = { additionalPkgs ? pkgs: [ ] }: buildFHSEnv {
65     # also determines the name of the wrapped command
66     name = executableName;
68     # additional libraries which are commonly needed for extensions
69     targetPkgs = pkgs: (with pkgs; [
70       # ld-linux-x86-64-linux.so.2 and others
71       glibc
73       # dotnet
74       curl
75       icu
76       libunwind
77       libuuid
78       lttng-ust
79       openssl
80       zlib
82       # mono
83       krb5
84     ]) ++ additionalPkgs pkgs;
86     extraBwrapArgs = [
87       "--bind-try /etc/nixos/ /etc/nixos/"
88     ];
90     # symlink shared assets, including icons and desktop entries
91     extraInstallCommands = ''
92       ln -s "${finalAttrs.finalPackage}/share" "$out/"
93     '';
95     runScript = "${finalAttrs.finalPackage}/bin/${executableName}";
97     # vscode likes to kill the parent so that the
98     # gui application isn't attached to the terminal session
99     dieWithParent = false;
101     passthru = {
102       inherit executableName;
103       inherit (finalAttrs.finalPackage) pname version; # for home-manager module
104     };
106     meta = meta // {
107       description = ''
108         Wrapped variant of ${pname} which launches in a FHS compatible environment.
109         Should allow for easy usage of extensions without nix-specific modifications.
110       '';
111     };
112   };
116   inherit pname version src sourceRoot dontFixup;
118   passthru = {
119     inherit executableName longName tests updateScript;
120     fhs = fhs { };
121     fhsWithPackages = f: fhs { additionalPkgs = f; };
122   } // lib.optionalAttrs (vscodeServer != null) {
123     inherit rev vscodeServer;
124   };
126   desktopItems = [
127     (makeDesktopItem {
128       name = executableName;
129       desktopName = longName;
130       comment = "Code Editing. Redefined.";
131       genericName = "Text Editor";
132       exec = "${executableName} %F";
133       icon = "vs${executableName}";
134       startupNotify = true;
135       startupWMClass = shortName;
136       categories = [ "Utility" "TextEditor" "Development" "IDE" ];
137       keywords = [ "vscode" ];
138       actions.new-empty-window = {
139         name = "New Empty Window";
140         exec = "${executableName} --new-window %F";
141         icon = "vs${executableName}";
142       };
143     })
144     (makeDesktopItem {
145       name = executableName + "-url-handler";
146       desktopName = longName + " - URL Handler";
147       comment = "Code Editing. Redefined.";
148       genericName = "Text Editor";
149       exec = executableName + " --open-url %U";
150       icon = "vs${executableName}";
151       startupNotify = true;
152       startupWMClass = shortName;
153       categories = [ "Utility" "TextEditor" "Development" "IDE" ];
154       mimeTypes = [ "x-scheme-handler/vs${executableName}" ];
155       keywords = [ "vscode" ];
156       noDisplay = true;
157     })
158   ];
160   buildInputs = [ libsecret libXScrnSaver libxshmfence ]
161     ++ lib.optionals (!stdenv.hostPlatform.isDarwin) [ alsa-lib at-spi2-atk libkrb5 mesa nss nspr systemd xorg.libxkbfile ];
163   runtimeDependencies = lib.optionals stdenv.hostPlatform.isLinux [ (lib.getLib systemd) fontconfig.lib libdbusmenu wayland libsecret ];
165   nativeBuildInputs = [ unzip ]
166     ++ lib.optionals stdenv.hostPlatform.isLinux [
167     autoPatchelfHook
168     asar
169     copyDesktopItems
170     # override doesn't preserve splicing https://github.com/NixOS/nixpkgs/issues/132651
171     # Has to use `makeShellWrapper` from `buildPackages` even though `makeShellWrapper` from the inputs is spliced because `propagatedBuildInputs` would pick the wrong one because of a different offset.
172     (buildPackages.wrapGAppsHook3.override { makeWrapper = buildPackages.makeShellWrapper; })
173   ];
175   dontBuild = true;
176   dontConfigure = true;
177   noDumpEnvVars = true;
179   installPhase = ''
180     runHook preInstall
181   '' + (if stdenv.hostPlatform.isDarwin then ''
182     mkdir -p "$out/Applications/${longName}.app" "$out/bin"
183     cp -r ./* "$out/Applications/${longName}.app"
184     ln -s "$out/Applications/${longName}.app/Contents/Resources/app/bin/${sourceExecutableName}" "$out/bin/${executableName}"
185   '' else ''
186     mkdir -p "$out/lib/vscode" "$out/bin"
187     cp -r ./* "$out/lib/vscode"
189     ln -s "$out/lib/vscode/bin/${sourceExecutableName}" "$out/bin/${executableName}"
191     # These are named vscode.png, vscode-insiders.png, etc to match the name in upstream *.deb packages.
192     mkdir -p "$out/share/pixmaps"
193     cp "$out/lib/vscode/resources/app/resources/linux/code.png" "$out/share/pixmaps/vs${executableName}.png"
195     # Override the previously determined VSCODE_PATH with the one we know to be correct
196     sed -i "/ELECTRON=/iVSCODE_PATH='$out/lib/vscode'" "$out/bin/${executableName}"
197     grep -q "VSCODE_PATH='$out/lib/vscode'" "$out/bin/${executableName}" # check if sed succeeded
199     # Remove native encryption code, as it derives the key from the executable path which does not work for us.
200     # The credentials should be stored in a secure keychain already, so the benefit of this is questionable
201     # in the first place.
202     rm -rf $out/lib/vscode/resources/app/node_modules/vscode-encrypt
203   '') + ''
204     runHook postInstall
205   '';
207   preFixup = ''
208     gappsWrapperArgs+=(
209         ${ # we cannot use runtimeDependencies otherwise libdbusmenu do not work on kde
210           lib.optionalString stdenv.hostPlatform.isLinux
211           "--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ libdbusmenu ]}"}
212       # Add gio to PATH so that moving files to the trash works when not using a desktop environment
213       --prefix PATH : ${glib.bin}/bin
214       --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations}}"
215       --add-flags ${lib.escapeShellArg commandLineArgs}
216     )
217   '';
219   # See https://github.com/NixOS/nixpkgs/issues/49643#issuecomment-873853897
220   # linux only because of https://github.com/NixOS/nixpkgs/issues/138729
221   postPatch = lib.optionalString stdenv.hostPlatform.isLinux ''
222     # this is a fix for "save as root" functionality
223     packed="resources/app/node_modules.asar"
224     unpacked="resources/app/node_modules"
225     asar extract "$packed" "$unpacked"
226     substituteInPlace $unpacked/@vscode/sudo-prompt/index.js \
227       --replace "/usr/bin/pkexec" "/run/wrappers/bin/pkexec" \
228       --replace "/bin/bash" "${bash}/bin/bash"
229     rm -rf "$packed"
231     # without this symlink loading JsChardet, the library that is used for auto encoding detection when files.autoGuessEncoding is true,
232     # fails to load with: electron/js2c/renderer_init: Error: Cannot find module 'jschardet'
233     # and the window immediately closes which renders VSCode unusable
234     # see https://github.com/NixOS/nixpkgs/issues/152939 for full log
235     ln -rs "$unpacked" "$packed"
236   '' + (
237     let
238       vscodeRipgrep =
239         if stdenv.hostPlatform.isDarwin then
240           if lib.versionAtLeast version "1.94.0" then
241             "Contents/Resources/app/node_modules/@vscode/ripgrep/bin/rg"
242           else
243             "Contents/Resources/app/node_modules.asar.unpacked/@vscode/ripgrep/bin/rg"
244         else
245           "resources/app/node_modules/@vscode/ripgrep/bin/rg";
246     in
247     if !useVSCodeRipgrep then ''
248       rm ${vscodeRipgrep}
249       ln -s ${ripgrep}/bin/rg ${vscodeRipgrep}
250     '' else ''
251       chmod +x ${vscodeRipgrep}
252     ''
253   );
255   postFixup = lib.optionalString stdenv.hostPlatform.isLinux ''
256     patchelf \
257       --add-needed ${libglvnd}/lib/libGLESv2.so.2 \
258       --add-needed ${libglvnd}/lib/libGL.so.1 \
259       --add-needed ${libglvnd}/lib/libEGL.so.1 \
260       $out/lib/vscode/${executableName}
261   '';
263   inherit meta;