Creating Symlinks in NixOS

Hey,

As per my understanding, the default terminal and system monitor in GNOME are hard-coded. On my Fedora machine, I used the following commands to create symlinks:

sudo mv /usr/bin/gnome-terminal /usr/bin/gnome-terminal.bak
sudo ln -s /usr/bin/kitty /usr/bin/gnome-terminal

However, this approach doesn’t work with NixOS. I tried the following configuration:

environment.etc = {
    "${pkgs.gnome-console}/bin/gnome-console".source = "${pkgs.kitty}/bin/kitty";
    "${pkgs.gnome.gnome-system-monitor}/bin/gnome-system-monitor".source = "${pkgs.resources}/bin/resources";
};

This results in the following error:

error: the string `/nix/store/.../gnome-console` is not allowed to refer to a store path (such as `!out...`)

Could you please provide guidance on how to correctly create these symlinks in NixOS?

Thank you!

Looks like they implemented a new standard: Add support for xdg-terminal-exec for handling desktop applications using 'Terminal=true' (!2839) · Merge requests · GNOME / GLib · GitLab

You should be able to change the defaults with this module: NixOS Search

Doing what you wanted to do would likely involve some messy overrides. I’m glad someone got around to fixing the underlying problem.

1 Like

thanks,

The following should be the working solution for anyone wondering, it doesn’t provide the “feature” that a symlink does, so the default “open terminal here” in Nautilus won’t work because it invokes the gnome terminal, so it doesn’t really answers my question, but it should change the default application.

    xdg.terminal-exec.enable = true;
    environment.variables.XDG_TERMINAL = "${pkgs.kitty}/bin/kitty";
    environment.variables.XDG_SYSTEM_MONITOR = "${pkgs.resources}/bin/resources";

Hm, that’s odd, nautilus should be using terminal-exec too from what I read. Maybe this helps? NixOS Search

Looking at the implementation, the configuration should probably actually be:

xdg.terminal-exec = {
  enable = true;
  settings = {
    default = [ "kitty.desktop" ];
  };
}

No idea why that option doesn’t show up in the search results.

hmm, doesn’t seem to make a difference. The option “Open in Console” is still not available.

When I exclude the gnome-console from the excludePackages, so that I have kitty and gnome-console installed, the “Open in Console” appears again, but opens gnome-console

There is this extension: GitHub - Stunkymonkey/nautilus-open-any-terminal as a workaround but that’s not really the solution I’m looking for

There is no such thing as default terminal emulator¹ or system monitor².

This would have effect on any references to those programs using absolute paths or using just the program name and relying on PATH lookup. We cannot really do much about the former (but then it would not work on NixOS anyway, since we do not have /usr/bin) but for the latter, it will be sufficient to install another package with the same program and higher priority:

environment.systemPackages =
  let
    fakeGnomeTerminal = pkgs.runCommand "fake-gnome-terminal" { } ''
      mkdir -p "$out/bin"
      ln -s "${pkgs.kitty}/bin/kitty" "$out/bin/gnome-terminal"
    '';
  in [
    (lib.hiPrio fakeGnomeTerminal)
  ];

Slight obstacle might be if some packages do hardcode the gnpme-terminal path (e.g. to fix absolute /usr/bin paths or to make the package more self-contained). Then you might need to override each dependent package individually:

(nautilus.override {
  gnome-terminal = fakeGnomeTerminal;
})

Or even replace the offending package globally using an overlay:

(final: prev: {
  gnome-terminal = fakeGnomeTerminal;
})

But note that the last two options might result in breakage if any of the dependents expects anything from the package other than the gnome-terminal executable in /bin. And every option will be problematic if the dependent calls the program with a CLI option not supported by kitty.


  1. The xdg-terminal-exec thing is currently only a proposal, not a widely supported, so the name is confusing. There is also a intent-apps specification proposal which is more versatile and appears to have more support.
  2. This even less so, intent-apps spec might make something like that possible. But I do not think that makes much sense, except perhaps to find a process corresponding to a WM window to kill it, which I do not think is a feature GNOME has.
2 Likes

The GLib change is only for launching desktop files – Nautilus relies directly on GNOME Console’s D-Bus API:

So you would need to create a dummy D-Bus service that would relay the Open call to kitty