Skip to content

Conversation

@kjkent
Copy link
Contributor

@kjkent kjkent commented Nov 16, 2024

Description

Previously, config.programs.zsh.dotDir prepended strings with $HOME. This caused issues where $HOME is inconsistently resolved in time for the evaluation of the option. The handling of this variable is also inconsistent with how paths are handled elsewhere, including within the same module, where config.programs.zsh.history.path does not mutate the supplied string.

This change prepends config.home.homeDirectory to relative paths, while assigning absolute paths unchanged. Tests for both cases are added.

Closes #5100

Checklist

  • Change is backwards compatible.

  • Code formatted with ./format.

  • Code tested through nix-shell --pure tests -A run.all or nix develop --ignore-environment .#all using Flakes.

  • Test cases updated/added. See example.

  • Commit messages are formatted like

    {component}: {description}
    
    {long description}
    

    See CONTRIBUTING for more information and recent commit messages for examples.

  • If this PR adds a new module

    • Added myself as module maintainer. See example.

Maintainer CC

@github-actions github-actions bot added the shell label Nov 16, 2024
@kjkent kjkent force-pushed the zsh-fix-dotdir-path branch from 97862d4 to 8233815 Compare November 16, 2024 01:12
# Absolute paths are assigned unmutated, relative paths
# are prepended with the user's home directory.
zdotdir = (strings.optionalString (!strings.hasPrefix "/" cfg.dotDir)
config.home.homeDirectory) + escapeShellArg cfg.dotDir;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had dotDir = ".config/zsh"; in my config and I think it generated a ZDOTDIR value of

echo $ZDOTDIR
/home/teto.config/zsh

Copy link
Contributor Author

@kjkent kjkent Nov 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@teto thanks for raising this -- looking at the code, yeah, I can see where I missed that. Curiously, it didn't cause the test to fail, which is doubly concerning -- let me made a change and test and I'll push an update 👍

@rycee
Copy link
Member

rycee commented Dec 13, 2024

Looks like the CI is a bit unhappy with this 🙂 But perhaps not far off from working?

@kjkent
Copy link
Contributor Author

kjkent commented Dec 13, 2024

@rycee yeah -- apologies for the delay on this; I started, then realised there was more to the fix than I anticipated and life got in the way a bit. I'm actually doing nothing right now so will see if I can get it boxed off :)

@kjkent kjkent force-pushed the zsh-fix-dotdir-path branch 5 times, most recently from 484998a to b48c6bf Compare January 1, 2025 03:59
@kjkent kjkent requested a review from teto January 1, 2025 19:03
@kjkent
Copy link
Contributor Author

kjkent commented Jan 1, 2025

@rycee @teto I believe this is good to go. Thanks for your patience with it.

I've been descriptive in the commit messages, but, in addition to original PR description I found that when setting HISTFILE in .zshrc, $HOME was also prepended to any custom programs.zsh.history.path value, if state version was < 20.03 (newer state versions only work with absolute paths), which wasn't conveyed in the description strings. Additionally, state versions >= 20.03 defaulted to the histfile being placed in the home dir while older versions defaulted to ZDOTDIR, which is (in my own view) more logical -- if settings are left at their defaults, it's the same behavior, but if a user makes the choice to move their .z* out of home, it makes little sense to leave this particular one behind (upstream zsh has no default history location -- it's not enabled by default. distros shipping zsh often set/tweak its defaults via a systemwide zshenv.

The first commit removes all reliance on $HOME which should fix the race condition issues seen, and allows both options to accept relative paths (which are interpreted as relative to home.homeDirectory) and absolute paths. The second commit simplifies the history file path handling + restores the sane, pre-20.03 default location.

If the second commit isn't desired I can revert it, otherwise, it poses a minor breaking change to those who have set a custom ZDOTDIR but not a custom HISTFILE location. I'm unsure of the best way to communicate/mitigate this (via state version logic?), though I'd wager those installs are few -- why go to the effort of moving most .z* files out of ~/, but leave one?

@kjkent kjkent changed the title zsh: improve dotDir handling zsh: path handling - remove $HOME reliance & make relative/absolute path logic consistent Jan 1, 2025
@kjkent kjkent force-pushed the zsh-fix-dotdir-path branch from b48c6bf to d219d9d Compare January 15, 2025 02:26
@stale
Copy link

stale bot commented Jun 15, 2025

Thank you for your contribution! I marked this pull request as stale due to inactivity. Please read the relevant sections below before commenting.

If you are the original author of the PR

  • GitHub sometimes doesn't notify people who commented / reviewed a PR previously when you (force) push commits. If you have addressed the reviews you can officially ask for a review from those who commented to you or anyone else.
  • If it is unfinished but you plan to finish it, please mark it as a draft.
  • If you don't expect to work on it any time soon, please consider closing it with a short comment encouraging someone else to pick up your work.
  • To get things rolling again, rebase the PR against the target branch and address valid comments.

If you are not the original author of the PR

  • If you want to pick up the work on this PR, please create a new PR and indicate that it supercedes and closes this PR.

@stale stale bot added the status: stale label Jun 15, 2025
@khaneliman
Copy link
Collaborator

Curious if you're still interested in pursuing this? We've had a bit of refactoring since this was made.

@stale stale bot removed the status: stale label Jul 11, 2025
@khaneliman khaneliman force-pushed the zsh-fix-dotdir-path branch 2 times, most recently from 3041638 to 9962d77 Compare July 14, 2025 04:18
Previously, `config.programs.zsh.dotDir` prepended strings with `$HOME`.
This caused issues like nix-community#5100, where `$HOME` is
inconsistently resolved in time for the evaluation of the option. The handling
of this variable is also inconsistent with how paths are handled elsewhere,
including within the same module, where `config.programs.zsh.history.path`
does not mutate the supplied string.

To preserve backwards compatibility, this change prepends
`config.home.homeDirectory` to relative paths, while assigning absolute paths
unchanged. Tests for both cases are added.

Signed-off-by: Austin Horstman <[email protected]>
@khaneliman khaneliman force-pushed the zsh-fix-dotdir-path branch from 9962d77 to 3b6e4fd Compare July 14, 2025 04:19
Previously, a stateVersion check for 20.03 determined whether or not the input to
`programs.zsh.history.path` would be prepended with `$HOME`. However, this was not
communicated in the documentation, which stated the version check determined whether
the default histfile location would be in `programs.zsh.dotDir` or
`home.homeDirectory`.

The current change simplifies matters and brings path handling in-line with that of
the preceding work on dotDir path handling. If a relative path is provided, it is
parsed as being relative to `home.homeDirectory`. Both absolute and relative paths
are supported, and are cleaned before being passed to other functions.

Tests have been rewritten for the new logic, with case handling for reusability.

Signed-off-by: Austin Horstman <[email protected]>
@khaneliman
Copy link
Collaborator

khaneliman commented Jul 14, 2025

Rebased on master and resolved all the merge conflicts and fixed some issues that were caught in newer tests.

@khaneliman khaneliman merged commit 9fca491 into nix-community:master Jul 25, 2025
6 checks passed
@andrevmatos
Copy link

andrevmatos commented Jul 27, 2025

Just FYI, this broke usecases where users had environment variables in programs.zsh.history.path; e.g. I used to have \${XDG_STATE_HOME:-$HOME/.local/state}/zsh/history in there, but this now adds some ' single quotes plus wrong variable expansion inside, which end up creating a path like /home/user/\'/home/user/.local/state/zsh/history\'
Fix is to use ${config.xdg.stateHome} (or other xdg path) interpolated directly

@gepbird
Copy link
Contributor

gepbird commented Jul 28, 2025

Same, after updating with programs.zsh.history.path = "$ZDOTDIR/.zsh_history"; (which now renders to HISTFILE="'/home/gep/$ZDOTDIR/.zsh_history'"), this directory structure gets creates when running zsh:

~/foo ❯ find
.
~/foo ❯ zsh
~/foo ❯ find
.
./'
./'/home
./'/home/gep
./'/home/gep/home
./'/home/gep/home/gep
./'/home/gep/home/gep/.config
./'/home/gep/home/gep/.config/zsh
./'/home/gep/home/gep/.config/zsh/.zsh_history'

I agree with this simpler handling, but some warning, release note or hiding it behind a new stateVersion would be nice.

gepbird added a commit to gepbird/dotfiles that referenced this pull request Jul 28, 2025
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
@khaneliman
Copy link
Collaborator

khaneliman commented Jul 28, 2025

@andrevmatos @gepbird thanks for identifying those issues, created #7561 to handle that better. Would be helpful to test with your previous config to verify it works, as expected.

khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
happy-dude added a commit to happy-dude/dotfiles that referenced this pull request Jul 28, 2025
ref: nix-community/home-manager#6089

Default zsh config in home-manager creates a `$HOME/.zshenv` now with
home-manager session vars initialized and will conflict with file trying
to be linked to that location.

Add contents of my own `.zshenv` into `envExtra` section.

Signed-off-by: Stanley Chan <[email protected]>
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
khaneliman added a commit to khaneliman/home-manager that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
khaneliman added a commit that referenced this pull request Jul 28, 2025
Give a news entry about change for path handling work done in
#6089.

Signed-off-by: Austin Horstman <[email protected]>
@lzpreslav
Copy link

JFYI a trailing slash in my homeDirectory path caused a zsh initialization failure.

My nix-darwin configuration:

users.users."${currentSystemUser}".home = "/Users/${currentSystemUser}/";

After updating and rebuilding I got this .zshenv file which failed zsh initialization with "job table full or recursion limit exceeded":

❯ cat ~/.zshenv        
source /Users/lzpreslav/.zshenv

Removing the trailing slash from the path fixed the issue.

auscyber pushed a commit to auscyber/home-manager that referenced this pull request Aug 29, 2025
Give a news entry about change for path handling work done in
nix-community#6089.

Signed-off-by: Austin Horstman <[email protected]>
elim added a commit to elim/dotfiles that referenced this pull request Sep 25, 2025
This change adapts the zsh configuration to follow the recent updates
in home-manager (specifically PR
nix-community/home-manager#6089 and
nix-community/home-manager#7561).

With this update, the `programs.zsh.dotDir` option now primarily
expects an absolute path, though relative paths remain supported for
the time being for backward compatibility.

My hard-coded path for `.config/zsh` has been replaced with the
`config.xdg.configHome` value. As a result, the manually defined
`zdotdir` variable became redundant and has been removed, simplifying
the overall configuration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: home manager zsh option "dotDir" is mangling zdotdir path and causing ".config/zsh" to be created in any directory the user is in

7 participants