Help setting up yazi file opener

Hi all, I could really use some help with this. I’m trying to setup the default text opener in yazi (file manager), however due to the syntax of the configuration, nix keeps processing it wrong. To set the editor to nvim for example, you do run = 'nvim "$@"' under text openers inside the toml config for yazi. When I try to set the same in the nix config like so run = 'micro "$@"', obviously this returns an error since ' cant be used like this in nix, so I tried instead to do run = ''micro "$@"'' to make it all a string, nixos accepts this, however it breaks yazi itself, as when the config is generated as a toml, it is translated to run = "micro "$@"". This again obviously wont work as it’ll be considered two separate strings. Sorry if my explanation has been a bit convoluted and very long, but I don’t really know how else to explain it, though I’m sure there is a simpler way. Any help would be appreciated!

Try

{
  programs.yazi.settings.<path_to_run> = "'micro \"$@\"'";
}

See string escaping here.

Also, you might get an error from yazi along the lines of “micro is not found”. Make sure that yazi actually has micro in its $PATH or reference micro binary by its full path like so:

{ lib, pkgs, ... }:
{
  programs.yazi.settings.<path_to_run> = "'${lib.getExe pkgs.micro} \"$@\"'"; # or "${pkgs.micro}/bin/micro" instead of "lib.getExe pkgs.micro", roughly same thing
}

Thanks for your reply, I looked at the string escaping, and tried your solution, I have added the getExe aswell. There still seems to be a problem with how the settings are being converted to toml as the output in the toml file is:

[opener.text]
run = "(path to micro) \"$@\"'"

For reference the toml should look like this:

[opener]
text = [
	{ run = 'micro "$@"', block = true },
]

There also seems to be a problem with the way the entire line settings.opener.text.run = "'${lib.getExe pkgs.micro} \"$@\"'"; is being processed. Yazi doesn’t seem to have any documentation on changing settings in nix, so iI just looked at examples from myNixOS. I’m thinking that there’s just something wrong with the way its trying to translate this to toml, so I might just try writing the config as a toml and using nix to symlink it to XDG_HOME.

[opener]
text = [
	{ run = 'micro "$@"', block = true },
]

This looks like a nested attribute set. Also, quick skim of the yazi options in nixpkgs shows that settings.yazi.opener should be used like so:

            programs.yazi = {
              enable = true;
              settings.yazi.opener.text = [
                {
                  run = "'${lib.getExe pkgs.micro} \"$@\"'";
                  block = true;
                }
              ];
            };

Home-manager version is slightly different.

so I might just try writing the config as a toml and using nix to symlink it to XDG_HOME.

Yeah, that’s always an option. Nixpkgs module effectively takes the attribute set, converts it into toml and writes it to /etc/ (code).

1 Like

I looked at the home manager link you sent (should have mentioned i am using hm), and the packages source. The settings attribute is using tomlFormat.type, i looked a little bit but couldn’t really find too much on how to write this. The solution you’ve sent seems very close, i tested the example from the package, and your suggestion slightly changed for the hm package.

settings = {
	opener.text = [{
		run = "'${lib.getExe pkgs.micro} \"$@\"'";
	}];
	
    manager = {
	    show_hidden = false;
	    sort_by = "modified";
	    sort_dir_first = true;
	    sort_reverse = true;
	};
};

Weirdly the output seems to group opener and text attributes together, and even though the square brackets should be encasing the run test, it instead surrounds the opener.text again:

[manager]
show_hidden = false
sort_by = "modified"
sort_dir_first = true
sort_reverse = true

[[opener.text]]
run = "'(path to micro) \"$@\"'"

I’m just going to go with the symlink, this seems like its more trouble than its worth just to set a single option in a config. Thanks for you help and time, this community is great!

Thought I’d just leave how I’ve done it here in case anyone needs it:

# yazi.nix

{...}: {
	programs.yazi = {
		enable = true;
		enableZshIntegration = true;
	};

	xdg.configFile."yazi/yazi.toml".source = ./yazi.toml;
}
# yazi.toml

[opener]
text = [
	{ run = 'micro "$@"', block = true },
]

This should be working, as it is equivalent to:

opener.text = [{
  run = "..."
}]

The [[opener.text]] syntax indicates the table is a member of the opener.text list (TOML is weird…)