Dmenu not showing programs installed via nix on Guix system

I use guix home to configure my home environment on Guix system and I am using home-zsh-service-type to configure my shell of choice.

Here is my home-zsh-service-type configuration,

    (service home-zsh-service-type
             (home-zsh-configuration
              (xdg-flavor? #t)
              (environment-variables
               `(("HISTFILE" . "$XDG_STATE_HOME/zsh/history")
                 ("HISTSIZE" . "10000")
                 ("SAVEHIST" . "10000")))
              (zshenv
               (list
                (local-file "files/shell/zsh/zshenv")))
              (zprofile
               (list
                (local-file "files/shell/zsh/zprofile")))
              (zshrc
               (list
                ;; (local-file "files/shell/zsh/config")
                (local-file "files/shell/zsh/completions")
                (mixed-text-file "zshrc"
                                 #~(string-append
                                    "# direnv hook zsh\n"
                                    "_direnv_hook() {\n"
                                    "  trap -- '' SIGINT;\n"
                                    "  eval \"$(\"" #$(file-append (specification->package "direnv")
                                                                   "/bin/direnv")"\" export zsh)\";\n"
                                                                   "  trap - SIGINT;\n"
                                                                   "}\n"))
                (local-file "files/shell/zsh/direnv")
                (local-file "files/shell/zsh/fzf")
                (local-file "files/shell/zsh/keybinds")
                (local-file "files/shell/zsh/prompt")
                (local-file "files/shell/zsh/source")
                (local-file "files/shell/zsh/startup")
                (local-file "files/shell/functions")
                (mixed-text-file
                 "zshrc"
                 #~(string-append
                    "source "
                    #$(file-append (specification->package "zsh-syntax-highlighting")
                                   "/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" "\n")))
                (mixed-text-file
                 "zshrc"
                 #~(string-append
                    "source "
                    #$(file-append (specification->package "zsh-history-substring-search")
                                   "/share/zsh/plugins/zsh-history-substring-search/zsh-history-substring-search.zsh" "\n")))
                (mixed-text-file
                 "zshrc"
                 #~(string-append
                    "fpath+=\"${0:A:h}"
                    #$(file-append (specification->package "zsh-completions")
                                   "share/zsh/site-functions/\"" "\n")))
                (mixed-text-file
                 "zshrc"
                 #~(string-append
                    "source "
                    #$(file-append (specification->package "zsh-autosuggestions")
                                   "/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh" "\n")))
                (mixed-text-file
                 "zshrc"
                 #~(string-append
                    "source "
                    #$(file-append (specification->package "zsh-autopair")
                                   "/share/zsh/plugins/zsh-autopair/zsh-autopair.zsh")))))))

Here I use a local-file for zshenv and zprofile,

              (zshenv
               (list
                (local-file "files/shell/zsh/zshenv")))
              (zprofile
               (list
                (local-file "files/shell/zsh/zprofile")))

Here are the contents of zshenv file,

# Guix
# GUIX_PROFILE="/home/apoorv/.config/guix/current" . "$GUIX_PROFILE/etc/profile"

# Load the nix profile
if [ -f "/run/current-system/profile/etc/profile.d/nix.sh" ]; then
    source /run/current-system/profile/etc/profile.d/nix.sh
fi

if [ -f "$HOME/.profile" ]; then
    source "$HOME"/.profile
fi

xrdb -merge ~/.Xresources

As you can see I am sourcing the nix.sh script to load the nix profile but dmenu doesn’t show the programs installed via nix for some reason, though I can launch them from terminal just fine.

It was all fine when I was not managing my home environment with guix BTW, this only started happening after I started using guix home to manage my home environment.

Also in another thread I mentioned this, Guix shell not showing mentioned program inside the shell environment - #11 by apoorv569

Guix auto-generates .zprofile file with these contents,

as@guix-virt ~$ cat .zprofile
# Honor system-wide environment variables
source /etc/profile

# Merge search-paths from multiple profiles, the order matters.
eval "$(guix package --search-paths \
-p $HOME/.config/guix/current \
-p $HOME/.guix-profile \
-p /run/current-system/profile)"

# Prepend setuid programs.
export PATH=/run/setuid-programs:$PATH

it worked fine as well when I was not using guix home to manage my home environment, but if I put the eval part in zprofile file that I am using right now, none of the programs installed via guix home also don’t show up in dmenu either.

Here is my current zprofile file,

# Merge search-paths from multiple profiles, the order matters.
# eval "$(guix package --search-paths \
# -p $HOME/.config/guix/current \
# -p $HOME/.guix-profile \
# -p /run/current-system/profile)"

# Prepend setuid programs.
export PATH=/run/setuid-programs:$PATH

As you can see I have commented it out for now.

I am using my custom build of dmenu BTW, ~apoorv569/nebula (master): nebula/packages/suckless.scm - sourcehut git

I tried commenting out the if condition,

# Guix
# GUIX_PROFILE="/home/apoorv/.config/guix/current" . "$GUIX_PROFILE/etc/profile"

# Load the nix profile
# if [ -f "/run/current-system/profile/etc/profile.d/nix.sh" ]; then
source /run/current-system/profile/etc/profile.d/nix.sh
# fi

# if [ -f "$HOME/.profile" ]; then
source "$HOME"/.profile
# fi

xrdb -merge ~/.Xresources

and ran guix home reconfigure, after reconfigure was done, dmenu started showing programs installed via nix, but then I rebooted and I again don’t see them in dmenu.

If dmenu looks for .desktop files, it can find them in paths listed in XDG_DATA_DIRS. See if the nix startup script extends this variable - it should point to $HOME/.nix-profile/share or the system-wide equivalent.

1 Like

This is the script that is being sourced,

if [ -n "$HOME" ] && [ -n "$USER" ]; then

    # Set up the per-user profile.

    NIX_LINK="$HOME/.nix-profile"
    if [ -n "${XDG_STATE_HOME-}" ]; then
        NIX_LINK_NEW="$XDG_STATE_HOME/nix/profile"
    else
        NIX_LINK_NEW="$HOME/.local/state/nix/profile"
    fi
    if [ -e "$NIX_LINK_NEW" ]; then
        NIX_LINK="$NIX_LINK_NEW"
    else
        if [ -t 2 ] && [ -e "$NIX_LINK_NEW" ]; then
            warning="\033[1;35mwarning:\033[0m"
            printf "$warning Both %s and legacy %s exist; using the latter.\n" "$NIX_LINK_NEW" "$NIX_LINK" 1>&2
            if [ "$(realpath "$NIX_LINK")" = "$(realpath "$NIX_LINK_NEW")" ]; then
                printf "         Since the profiles match, you can safely delete either of them.\n" 1>&2
            else
                # This should be an exceptionally rare occasion: the only way to get it would be to
                # 1. Update to newer Nix;
                # 2. Remove .nix-profile;
                # 3. Set the $NIX_LINK_NEW to something other than the default user profile;
                # 4. Roll back to older Nix.
                # If someone did all that, they can probably figure out how to migrate the profile.
                printf "$warning Profiles do not match. You should manually migrate from %s to %s.\n" "$NIX_LINK" "$NIX_LINK_NEW" 1>&2
            fi
        fi
    fi

    # Set up environment.
    # This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix
    export NIX_PROFILES="/nix/var/nix/profiles/default $NIX_LINK"

    # Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work.
    if [ -e /etc/ssl/certs/ca-certificates.crt ]; then # NixOS, Ubuntu, Debian, Gentoo, Arch
        export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
    elif [ -e /etc/ssl/ca-bundle.pem ]; then # openSUSE Tumbleweed
        export NIX_SSL_CERT_FILE=/etc/ssl/ca-bundle.pem
    elif [ -e /etc/ssl/certs/ca-bundle.crt ]; then # Old NixOS
        export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt
    elif [ -e /etc/pki/tls/certs/ca-bundle.crt ]; then # Fedora, CentOS
        export NIX_SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt
    elif [ -e "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" ]; then # fall back to cacert in Nix profile
        export NIX_SSL_CERT_FILE="$NIX_LINK/etc/ssl/certs/ca-bundle.crt"
    elif [ -e "$NIX_LINK/etc/ca-bundle.crt" ]; then # old cacert in Nix profile
        export NIX_SSL_CERT_FILE="$NIX_LINK/etc/ca-bundle.crt"
    fi

    # Only use MANPATH if it is already set. In general `man` will just simply
    # pick up `.nix-profile/share/man` because is it close to `.nix-profile/bin`
    # which is in the $PATH. For more info, run `manpath -d`.
    if [ -n "${MANPATH-}" ]; then
        export MANPATH="$NIX_LINK/share/man:$MANPATH"
    fi

    export PATH="$NIX_LINK/bin:$PATH"
    unset NIX_LINK NIX_LINK_NEW
fi

Its appending to $PATH looks like… Though I don’t think the issue is with the script or something. As I mentioned in the original post, it used to work when I was not using guix home to manage this.

If you don’t want to manage these variables, you can try adding glib package to the profile.

Here’s me asking about this on reddit, but for guix profiles.

So if you add glib:bin to a guix profile the correct vars get exported. Try this with a nix profile (does glib:bin even exist in nix?)

If you don’t want to manage these variables

Which variables?

I tried adding glib:bin to my guix home packages and when trying to guix home reconfigure, I get this error,

guix home: error: profile contains conflicting entries for glib
guix home: error:   first entry: glib@2.72.3 /gnu/store/ysm0jjyr6d356q4rw2f9a9gm73jk93s0-glib-2.72.3
guix home: error:   second entry: glib@2.72.3 /gnu/store/ym79jzgq1aq1nqskwg6mwa0qyg0k5f5c-glib-2.72.3
guix home: error:    ... propagated from python-pygobject@3.42.2
guix home: error:    ... propagated from udiskie@2.4.2
hint: Try upgrading both `glib' and `udiskie', or remove one of them from the profile.

I don’t know if it’s necessary to source that file. Just add the nix profile bin to PATH and the share to XDG_DATA_DIRS like sound suggested.

I add the nix profile bin to PATH and don’t bother with XDG_DATA_DIRS, but in ~/.profile. Maybe try that. I think zshenv is the wrong place to do it.

also note, dmenu_run and dmenu_path are shell scripts using sh in the shebang, so I don’t think zshenv would be involved.

I don’t know if it’s necessary to source that file. Just add the nix profile bin to PATH and the share to XDG_DATA_DIRS like sound suggested.

Is that the suggested way?

Because according to GNU Guix Reference Manual

You have to source that script only.

also note, dmenu_run and dmenu_path are shell scripts using sh in the shebang, so I don’t think zshenv would be involved.

No, zsh is my user/login shell, I am just using it to source stuff for me on startup, including the nix script.

Try sourcing that file in ~.profile then. I don’t know if having zsh as the user shell in /etc/passwd means zsh will be used for scripts with sh, my understanding is sh uses bash with a special option, so it’s not going to see anything provided by zshenv.

If you look at profile.d/nix.sh being sourced, the only thing it does is add the nix profile bin to PATH and share/man to MANPATH (and moving ~/.nix-profile if it exists to ~/.local/state/nix/profile and certificates I guess). If you want dmenu to see desktop files, you’ll need to add the nix profile share to XDG_DATA_DIRS anyway.

Try sourcing that file in ~.profile then. I don’t know if having zsh as the user shell in /etc/passwd means zsh will be used for scripts with sh, my understanding is sh uses bash with a special option, so it’s not going to see anything provided by zshenv.

I see, but as I mentioned in the original post, it used to work fine when I was not managing these files (shell configuration files and all) via guix home.

BTW ~/.profile is already (by default) a symlink to a /gnu/store item, how do I add something to ~/.profile without breaking the symlink?

If you look at profile.d/nix.sh being sourced, the only thing it does is add the nix profile bin to PATH and share/man to MANPATH (and moving ~/.nix-profile if it exists to ~/.local/state/nix/profile and certificates I guess). If you want dmenu to see desktop files, you’ll need to add the nix profile share to XDG_DATA_DIRS anyway.

I can try doing it manually, but it should work the “official” way (?)

Maybe I there is something else I am doing, that could be causing issues?

There’s home-shell-profile-service that can be extended with a list of file-likes for when guix home makes .profile.

(simple-service 'nix-profile-service home-shell-profile-service
		(list (mixed-text-file "nix-shell-profile"
				       ...)))

I’m not running xwindows, so I can’t easily reproduce it, but see this thread:
[Solved] User scripts not being detected by xinitrc or dmenu

Because you are setting your new $PATH in a configuration file for an interactive shell and dmenu is not being started from such a shell.
You should set $PATH from a configuration file for a login shell so the variable is set when you start the X server and inherited by all subsequent processes.
https://wiki.archlinux.org/index.php/Ba … tion_files
So yes, ~/.profile would be correct as this is a configuration file for both interactive and login shells.

Presumably, you’re using keybindings to call dmenu?

Additionally:
Arch wiki: dmenu

Arch wiki: Light DM#X Session

Seems to depend on your desktop manager, use ~/.profile ~/.xinitrc, ~/.xsession to set the paths or source the script. I’d suggest ~/.profile so you’re not accidentally setting it twice.

I see, interesting.

So I moved,

if [ -f "/run/current-system/profile/etc/profile.d/nix.sh" ]; then
    source /run/current-system/profile/etc/profile.d/nix.sh
fi

from zshenv to zprofile (managing via guix home only) and I see programs installed via nix in dmenu.

Noticed that David also sets this in his bash-profile file, dotfiles/daviwil/systems/common.scm at e1f05290894ecb67c7be9d53a5393bb60220f253 · daviwil/dotfiles · GitHub

Its where I got this from, perhaps I got confused between shell files, zshenv is more for interactive shell only I guess.

Though I am still curious as to why it used to work when I was not using guix home to manage these files files.

He does also does this for flatpak apps, dotfiles/daviwil/systems/common.scm at e1f05290894ecb67c7be9d53a5393bb60220f253 · daviwil/dotfiles · GitHub

which I do the same, but I don’t see the flatpak apps in dmenu either. Though I don’t use flatpak that much, I prefer using nix…

Can simplify it even further using the guix packages to point directly to the file in the store.

(mixed-text-file "flatpak-shell-profile"
		 "source " flatpak "/etc/profile.d/flatpak.sh")

(mixed-text-file "nix-shell-profile"
		 "source " nix "/etc/profile.d/nix.sh")

What do you mean? Like generate zprofile using these mixed-text-file objects?

Something like,

              (zprofile
               (list
                (local-file "files/shell/zsh/zprofile")
                (mixed-text-file "flatpak-shell-profile"
                                 #~(string-append "source " #$(file-append (specification->package "flatpak") "/etc/profile.d/flatpak.sh" "\n")))
                (mixed-text-file "nix-shell-profile"
                                 #~(string-append "source " #$(file-append (specification->package "nix") "/etc/profile.d/nix.sh" "\n")))))

?

Yeah, if you’re just using a mixed-text-file you don’t have to bother with the g-exps. The example in the docs is:

(mixed-text-file "profile"
                 "export PATH=" coreutils "/bin:" grep "/bin")

Works. I have marked your answer above as solution. Thanks for the help.

EDIT: BTW, I added this,

              (zprofile
               (list
                (local-file "files/shell/zsh/zprofile")
                (mixed-text-file "flatpak-shell-profile"
                                 "source " flatpak "/etc/profile.d/flatpak.sh" "\n")
                (mixed-text-file "nix-shell-profile"
                                 "source " nix "/etc/profile.d/nix.sh" "\n")))

it adds this to the zprofile file,

source /gnu/store/2p06n3dyiia1yql2xkh432hz93ng251f-flatpak-1.14.4/etc/profile.d/flatpak.sh

source /gnu/store/070dq5xkdwjkilqjg99a2iyb9px6xi5h-nix-2.16.1/etc/profile.d/nix.sh

nix one works, I see programs installed via nix in dmenu, though flatpak ones still don’t show up, but it doesn’t matter I don’t use flatpak that much and the original issue is solved.

Also I didn’t know that I don’t need gexp in mixed-text-file, it helped clean up a lot of my guix home configuration.

Thanks again.

1 Like