Dynamically change file content created with home.file?

I have the following code for configurating wezterm and tmux:

{ pkgs, config, ... }:

with config.lib;

{
  home.packages = with pkgs; [ wezterm tmux ];

  xdg.configFile = {
    "wezterm/" = {
      source = file.mkOutOfStoreSymlink "../../dotfiles/wezterm";
    };
  };

  home.file = {
    ".tmux.conf" = {
      source = file.mkOutOfStoreSymlink "../../dotfiles/.tmux.conf";
    };
  };
}

And I will be launching tmux directly from wezterm. This setup is alright, but I cannot make shell that will be run by tmux dynamic, which is controlled by this line at the end of config in .tmux.conf:

set -g default-shell /run/current-system/sw/bin/zsh

How can I make this dynamic(and get path of another shell, if I pass it into this module as argument)? Can I append string like this to a file(.tmux.conf) from nix?

There are a few ways you could do this, albeit not with symlinks (those are directly symlinked, after all, so you can’t dynamically edit them - they are by definition exactly the same as the ones in your dotfiles).

If you want to append, the easiest way is:

home.file = {
    ".tmux.conf" = {
      text = (builtins.readFile ../../dotfiles/.tmux.conf) + ''
        set -g default-shell ${pkgs.zsh}/bin/zsh
      '';
    };
  };

Alternatively you could build the file as a package, and use Nixpkgs 23.11 manual | Nix & NixOS, use the string replacement functions from nix directly, or convert your tmux config to home-manager configuration and use their extraArgs.

1 Like

Also, while I’m reading some of your code, have a read through this: https://nix.dev/anti-patterns/

:slight_smile:

1 Like

Thank you so much for your advice on this! I give it a try today, and I end up have this right now. So far so good.

https://github.com/winston0410/universal-dotfiles/blob/852175d2143c9caeba83faa5e9d4d9f66a793607/options/terminal.nix#L118-L123

And yes, I don’t realize I have committed so many sins when I write my Nix. I guess I have a long way to go.