nushell

How to manage PATH


I'd like to be able to easily/often change my PATH environment variable interactively. In other shells, this is really easy; eg, appending with Zsh:

path+=/some/path

With Nushell, the docs say the equivalent is:

$env.PATH = ($env.PATH | split row (char esep) | append '/some/path')

That's kinda crazy to have to type for an interactive shell. But this also seems to work, and is almost reasonable:

let-env PATH = ($env.PATH|append /some/path)

(BTW, why do docs mention both $env.PATH = ... and let-env PATH = ... approaches? Which is preferred and why?)

To make it more reasonable, it feels something like this is needed (in my config.nu), but I'd like to know: is this approach fine for appending to PATH?

def-env path-append [d] { let-env PATH = ($env.PATH | split row (char esep) | append $d) }
...
path-append /some/path

Additionally, is this the right way to remove an entry from PATH?

$env.PATH # see that entry 37 is unwanted
let-env PATH = ($env.PATH|drop nth 37) # remove 37th entry

# so then this is even better (also in my config.nu)?
def-env path-drop [n] { let-env PATH = ($env.PATH|drop nth $n) }
path-drop 37

BONUS: Zsh has vared to interactively edit things like PATH. Is there any such equivalent in Nu?


Solution

  • Note that the docs you are referring to for adding to the Path are assuming that you are doing it at startup, via env.nu. The docs also mention that the reason for the split row (char esep) step is:

    because in env.nu, the environment variables inherited from the host process are still strings. The conversion step of environment variables to Nushell values happens after reading the config files (see also the Environment section).

    And I'm separating out the most important sentence here:

    After that, for example in the Nushell REPL when PATH/Path is a list , you can use append/prepend directly.

    So, interactively (a.k.a., "in the Nushell REPL"), you can shorten it to:

    $env.PATH = ($env.PATH | append '/some/path')
    

    why do docs mention both $env.PATH = ... and let-env PATH = ... approaches? Which is preferred and why?

    If there's a section of the docs that still refers to let-env, you should open an issue against that (or a PR), since let-env has been removed from Nushell in recent releases. $env was made mutable, so there is no reason for let-env any longer.

    is this approach fine for appending to PATH?

    For interactive use, remove the split... portion as mentioned above. Also use $env:

    def-env path-append [d] { $env.PATH = ($env.PATH | append $d) }
    

    is this the right way to remove an entry from PATH?

    Sure, that will work, assuming you make the same modifications as above ($env instead of let-env).

    You might get fancier if you'd like with something like:

    def-env path-remove [d] {
        $env.PATH = ( $env.PATH | 
            each {|p|
                if $p != $d { $p }
            }
        )
    }
    

    Then you could call path-remove /some/path

    Zsh has vared to interactively edit things like PATH. Is there any such equivalent in Nu?

    Not that I can think of. $env.PATH | explore would give you a nice read-only view, but not really any improvement in this case over the default table-view. However, there's no equivalent that I can think of for editing.