-
Notifications
You must be signed in to change notification settings - Fork 468
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nushell support #463
Comments
It's enough for basic usage. But if we want |
In the meanwhile - you can get the path edit via: /home/orta> fnm env | lines | split column '"' | first | get Column2
/tmp/fnm_multishells/10174_1623514914978/bin Then the rest of the env vars via:
So to mix it all together: #Update paths
echo $nu.path | append (fnm env | lines | split column '"' | first | get Column2) | config set_into path
# Add env vars
fnm env | str find-replace -a "export " '' | str find-replace -a '"' '' | lines | split column = | rename name value | last 5 | load-env And at least from some current messing around it seems to work |
Nushell added pathvar command for dynamic path updates. To make work fnm in nushell, add these two commands in the startup: #load env variables
fnm env --shell bash | lines | last 5 | str find-replace 'export ' '' | str find-replace -a '"' '' | split column = | rename name value | load-env
#add dynamic fnm path
pathvar add $nu.env.FNM_MULTISHELL_PATH Info: Requires nushell v0.34+ (pathvar command is supported only with v0.34 and above) |
I had to change the path like this: |
Nushell has I made a super quick Go program for this: https://github.com/Southclaws/fnm-nushell Install with |
This is the code I added to my env.nu using nushell 0.61.0 that works:
|
This is my first experience with # FNM
# load env variables
load-env (fnm env --shell bash | lines | str replace 'export ' '' | str replace -a '"' '' | split column = | rename name value | where name != "FNM_ARCH" && name != "PATH" | reduce -f {} {|it, acc| $acc | upsert $it.name $it.value })
# add dynamic fnm path
let-env PATH = ($env.PATH | prepend $"($env.FNM_MULTISHELL_PATH)/bin")
# add fnm with cd
def-env fnmcd [path: string] {
let-env PWD = ($path | path expand)
if (['.node-version' '.nvmrc'] | any? ($env.PWD | path join $it | path exists)) {
fnm use --silent-if-unchanged
}
}
alias cd = fnmcd |
Could you at least add something like |
This is the code I added to my env.nu using nushell 0.64.0 that works on WINDOWS: # FNM for windows
# load env variables
load-env (fnm env --shell cmd | lines | str replace 'SET ' '' | split column = | rename name value | where name != "FNM_ARCH" && name != "PATH" | reduce -f {} {|it, acc| $acc | upsert $it.name $it.value })
# add dynamic fnm path
let-env Path = ($env.Path | prepend $env.FNM_MULTISHELL_PATH) |
Nu has changed a lot. It is better now. Any plan for fnm to have built-in support for Nushell? Current workaround inspired by #463 (comment): # FNM config
# Parse FNM env from other supported shell. It result should looks like this:
# │ FNM_VERSION_FILE_STRATEGY │ local │
# │ FNM_DIR │ /home/user/.fnm |
# Then load these value key pair to Nushell env
load-env (fnm env --shell bash | lines | str replace 'export ' '' | str replace -a '"' '' | split column = | rename name value | where name != "FNM_ARCH" && name != "PATH" | reduce -f {} {|it, acc| $acc | upsert $it.name $it.value })
# Add dynamic FNM path
let-env PATH = ($env.PATH | append [
$"($env.FNM_MULTISHELL_PATH)/bin"
]) |
It seems nushell support is on the way: #801 For the meantime the solution from @azzamsa works for me, but with Nushell has very handy hook feature that can be used to pick node version on directory change. I added this to my let-env config = {
…
hooks: {
env_change: {
PWD: [{|before, after|
if ([.nvmrc .node-version] | path exists | any? ($it == true)) {
fnm use
}
}]
}
}
…
} |
Now that #800 landed in 1.32.0, the setup for nu already got much nicer using the The PR mentions this script:
Personally I use this:
I concatenate the paths as strings, because this is part of my |
Ok so, this is currently in my # FNM
# load env variables
fnm env --json | from json | load-env
# add dynamic fnm path
let-env PATH = ($env.PATH | split row (char esep) | prepend ([$env.FNM_MULTISHELL_PATH "bin"] | path join))
# add fnm with cd
def-env fnmcd [path: string] {
let-env PWD = ($path | path expand)
if (['.node-version' '.nvmrc'] | any ($env.PWD | path join $it | path exists)) {
fnm use --silent-if-unchanged
}
}
alias cd = fnmcd |
Updated the snippet to work under 0.72:
|
Thank you for this, saved me a ton of time. Had to make these small changes for it to work for me on windows, but I can't say if it's correct or not confidently. # FNM
# load env variables
fnm env --json | from json | load-env
# add dynamic fnm path
let-env Path = ($env.Path | split row (char esep) | prepend ([$env.FNM_MULTISHELL_PATH] | path join))
# add fnm with cd
def-env fnmcd [path?: string] {
if ($path == null) {
cd
} else {
cd ($path | path expand)
}
if (['.node-version' '.nvmrc'] | any ($env.PWD | path join $it | path exists)) {
fnm use --silent-if-unchanged
}
}
alias cd = fnmcd |
Update for nushell v0.73: It seems that We might be using too many unstable features of nushell in the script 😂 |
That's why I simply wrote it in Go instead 😂 |
Full fnm script for nu 0.73 # FNM
# load env variables
fnm env --json | from json | load-env
# add dynamic fnm path
let-env PATH = ($env.PATH | split row (char esep) | prepend ([$env.FNM_MULTISHELL_PATH "bin"] | path join))
# add fnm with cd
def-env fnmcd [path?: string] {
if ($path == null) {
cd
} else {
cd ($path | path expand)
}
if (['.node-version' '.nvmrc'] | any {|it| $env.PWD | path join $it | path exists}) {
fnm use --silent-if-unchanged
}
}
alias cd = fnmcd |
On mac I'm getting
How can I solve this? :D |
@sr-mothership You need to have fnm in your PATH first. Add something like |
That is so weird, since I already have |
@sr-mothership It should be in |
Damn that solved it, haha. Thanks 🙂 |
In Nushell 0.77, there is a breaking change related to the use of |
For env_change: {
PWD: [{|before, after|
if ([.nvmrc .node-version] | path exists | any {|it| ($it == true)}) {
fnm use
}
}]
} |
So to summarize:
If you have fnm on every machine, you can leave out the |
For # env.nu
if not (which fnm | is-empty) {
^fnm env --json | from json | load-env
# Checking `Path` for Windows
let path = if 'Path' in $env { $env.Path } else { $env.PATH }
let node_path = if (sys).host.name == 'Windows' {
$"($env.FNM_MULTISHELL_PATH)"
} else {
$"($env.FNM_MULTISHELL_PATH)/bin"
}
$env.PATH = ($path | prepend [ $node_path ])
}
# config.nu
$env.config = {
hooks: {
env_change: {
PWD: [{ |before, after|
if ('FNM_DIR' in $env) and ([.nvmrc .node-version] | path exists | any { |it| $it }) {
fnm use
}
}]
}
}
} |
@hustcer your solution works for me, but I always get this warning:
|
@marcelarie It works for me, However, You can give this PR a try: https://github.com/nushell/nu_scripts/pull/593/files |
use this: above v0.85 nushell load-env (fnm env --shell bash | lines | str replace 'export ' '' | str replace -a '"' '' | split column = | rename name value | where name != "FNM_ARCH" and name != "PATH" | reduce -f {} {|it, acc| $acc | upsert $it.name $it.value })
# Add dynamic FNM path
$env.Path = ($env.Path | append [
$env.FNM_MULTISHELL_PATH
]) then source it in $nu.config-path source /path/to/fnm.nu |
Work for me. But how to config for fnm use on cd? |
For me, this works like a charm: $env.config = {
hooks: {
env_change: {
PWD: [{ |before, after|
let is_node_dir = [.nvmrc .node-version] | path exists | any { |it| $it }
if ('FNM_DIR' in $env) and $is_node_dir {
fnm use # Personally I prefer to use fnm --log-level=quiet use
}
}]
}
}
}
if not (which fnm | is-empty) {
^fnm env --json | from json | load-env
# Checking `Path` for Windows
let path = if 'Path' in $env { $env.Path } else { $env.PATH }
let node_path = if (sys).host.name == 'Windows' {
$"($env.FNM_MULTISHELL_PATH)"
} else {
$"($env.FNM_MULTISHELL_PATH)/bin"
}
$env.PATH = ($path | prepend [ $node_path ])
} |
A slight tweak to the if not (which fnm | is-empty) {
^fnm env --json | from json | load-env
let node_path = if (sys).host.name == 'Windows' {
$"($env.FNM_MULTISHELL_PATH)"
} else {
$"($env.FNM_MULTISHELL_PATH)/bin"
}
# Checking `Path` for Windows
if 'Path' in $env {
$env.Path = ($env.Path | split row (char esp) | prepend $node_path)
} else {
$env.PATH = ($env.PATH | split row (char esp) | prepend $node_path)
}
} Of course, I only tried the Windows side. (And we could probably combine the two if-else blocks together.) Edit: I added the |
Welcome to the club! However, after several hours of setup. Nushell is not ready for daily usage. - [nushell: atuin should not always trigger on ⬆️ · Issue #1025 · atuinsh/atuin](atuinsh/atuin#1025) - [`column_not_found` in Nushell · sxyazi/yazi · Discussion #501](sxyazi/yazi#501) - [Generated .zoxide.nu has incorrect syntax · Issue #661 · ajeetdsouza/zoxide](ajeetdsouza/zoxide#661) - [Nushell support · Issue #463 · Schniz/fnm](Schniz/fnm#463) - Syntax highlighting still requires manual setup. - https://github.com/nushell/tree-sitter-nu/blob/main/installation/neovim.md#manual-installation - nufmt is still very much in beta.
Welcome to the club! However, after several hours of setup. Nushell is not ready for daily usage. - [nushell: atuin should not always trigger on ⬆️ · Issue #1025 · atuinsh/atuin](atuinsh/atuin#1025) - [`column_not_found` in Nushell · sxyazi/yazi · Discussion #501](sxyazi/yazi#501) - [Generated .zoxide.nu has incorrect syntax · Issue #661 · ajeetdsouza/zoxide](ajeetdsouza/zoxide#661) - [Nushell support · Issue #463 · Schniz/fnm](Schniz/fnm#463) - Syntax highlighting still requires manual setup. - https://github.com/nushell/tree-sitter-nu/blob/main/installation/neovim.md#manual-installation - nufmt is still very much in beta.
This could be simplified a bit further, no need for windows patch check in the end. # File: config.nu
use std "path add"
if not (which fnm | is-empty) {
^fnm env --json | from json | load-env
let node_path = match $nu.os-info.name {
"windows" => $"($env.FNM_MULTISHELL_PATH)",
_ => $"($env.FNM_MULTISHELL_PATH)/bin",
}
path add $node_path
}
|
Another tweak to what @marcelarie provided. It seems that the solution was somehow conflicting with my existing config as the banner returned after having been set to False and all of my other custom hooks were no longer taking affect. So I went with this. export-env {
$env.config = ($env.config | upsert hooks {
env_change: {
PWD: ($env.config.hooks.env_change.PWD ++
[{
condition: {|before, after| [.nvmrc .node-version] | path exists | any { |it| $it }}
code: {|before, after|
if ('FNM_DIR' in $env) {
fnm use # Personally I prefer to use fnm --log-level=quiet use
}
}
}]
)
}
})
}
if not (which fnm | is-empty) {
^fnm env --json | from json | load-env
# Checking `Path` for Windows
let path = if 'Path' in $env { $env.Path } else { $env.PATH }
let node_path = if (sys).host.name == 'Windows' {
$"($env.FNM_MULTISHELL_PATH)"
} else {
$"($env.FNM_MULTISHELL_PATH)/bin"
}
$env.PATH = ($path | prepend [ $node_path ])
} |
@gclarkjr5 improvement - sys is deprecated. |
|
# Description The standard library's `path add` function has some surprising side effects that I attempt to address in this PR: 1. Paths added, if they are symbolic links, should not be resolved to their targets. Currently, resolution happens. Imagine the following: ```nu # Some time earlier, perhaps even not by the user, a symlink is created mkdir real-dir ln -s real-dir link-dir # Then, step to now, with link-dir that we want in our PATHS variable use std path add link-dir ``` In the current implementation of `path add`, it is _not_ `link-dir` that will be added, as has been stated in the command. It is instead `real-dir`. This is surprising. Users have the agency to do this resolution if they wish with `path expand` (sans a `--no-symlink` flag): for example, `path add (link-dir | path expand)` In particular, when I was trying to set up [fnm](https://github.com/Schniz/fnm), a Node.js version manager, I was bitten by this fact when `fnm` told me that an expected path had not been added to the PATHS variable. It was looking for the non-resolved link. The user in [this comment](Schniz/fnm#463 (comment)) was likely affected by this too. Shells, such as nushell, can handle path symlinks just fine. Binary lookup is unaffected. Let resolution be opt-in. Lastly, there is some convention already in place for **not** resolving path symlinks in the [default $env.ENV_CONVERSIONS table](https://github.com/nushell/nushell/blob/57452337ff4e228102433e99b4c6000700a9b3b2/crates/nu-utils/src/sample_config/default_env.nu#L65). 2. All existing paths in the path variable should be left untouched. Currently, they are `path expand`-ed (including symbolic link resolution). Path add should mean just that: prepend/append this path. Instead, it currently means that, _plus mutate all other paths in the variable_. Again, users have the agency to do this with something like `$env.PATH = $env.PATH | split row (char esep) | path expand`. 3. Minorly, I update documentation on running tests in `crates/nu-std/CONTRIBUTING.md`. The offered command to run the standard library test suite was no longer functional. Thanks to @weirdan in [this Discord conversation](https://discord.com/channels/601130461678272522/614593951969574961/1256029201119576147) for the context. # User-Facing Changes (Written from the perspective of release notes) - The standard library's `path add` function no longer resolves symlinks in either the newly added paths, nor the other paths already in the variable. # Tests + Formatting A test for the changes working correctly has been added to `crates/nu-std/tests/test_std.nu` under the test named `path_add_expand`. You can quickly verify this new test and the existing `path add` test with the following command: ```nu cargo run -- -c 'use crates/nu-std/testing.nu; NU_LOG_LEVEL=INFO testing run-tests --path crates/nu-std --test path_add' ``` All commands suggested in the issue template have been run and complete without error. # After Submitting I'll add a release note to [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged.
In nushell 0.98.0, I followed the tutorial in # To add entries to PATH (on Windows you might use Path), you can use the following pattern:
# $env.PATH = ($env.PATH | split row (char esep) | prepend '/some/path')
# An alternate way to add entries to $env.PATH is to use the custom command `path add`
# which is built into the nushell stdlib:
# use std "path add"
# $env.PATH = ($env.PATH | split row (char esep))
# path add /some/path
# path add ($env.CARGO_HOME | path join "bin")
# path add ($env.HOME | path join ".local" "bin")
# $env.PATH = ($env.PATH | uniq) I successfully accessed Node by adding the following three lines: fnm env --json | from json | load-env
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.FNM_MULTISHELL_PATH)
$env.PATH = ($env.PATH | uniq) Here, both What confuses me, however, is that the I’m not sure if I missed something in the documentation, and if not, I hope the authors can optimize it. |
NuShell v0.98.0 Windows11 # ~/fnm.nu
use std "path add"
$env.FNM_DIR = "D:/fnm"
$env.FNM_BIN = "D:/fnm/bin"
path add $env.FNM_BIN
$env.FNM_MULTISHELL_PATH = "D:/fnm/nodejs"
path add $env.FNM_MULTISHELL_PATH
Add fnm install 20.17.0
fnm install 22.9.0
fnm use v20.17.0
node -v
v20.17.0
fnm use v22.9.0
node -v
v22.9.0 It's working. However, there is a slight error in the fnm env --json | from json
╭───────────────────────────┬──────────────────────────────────────────────────────────────────╮
│ FNM_MULTISHELL_PATH │ C:\Users\[demo]\AppData\Local\fnm_multishells\1832_1727301725051 │
│ FNM_RESOLVE_ENGINES │ false │
│ FNM_LOGLEVEL │ info │
│ FNM_VERSION_FILE_STRATEGY │ local │
│ FNM_COREPACK_ENABLED │ false │
│ FNM_DIR │ D:/fnm │
│ FNM_ARCH │ x64 │
╰───────────────────────────┴──────────────────────────────────────────────────────────────────╯ [demo]: your username If you want environment variables to display correctly, you need to change the code. // config.rs
- multishell_path: Option<std::path::PathBuf>,
+ pub multishell_path: Option<std::path::PathBuf>,
//env.rs
- let _multishell_path = make_symlink(config)?;
+ let mut multishell_path = make_symlink(config)?;
+ if config.multishell_path.is_some() {
+ multishell_path = config.multishell_path.clone().unwrap();
+ }; cargo build
alias fnm2 = `path/to/fnm/target/debug/fnm.exe`
fnm2 env --json | from json
╭───────────────────────────┬───────────────────────────────────╮
│ FNM_MULTISHELL_PATH │ D:/fnm/nodejs │
│ FNM_DIR │ D:/fnm │
│ FNM_LOGLEVEL │ info │
│ FNM_RESOLVE_ENGINES │ false │
│ FNM_VERSION_FILE_STRATEGY │ local │
│ FNM_ARCH │ x64 │
│ FNM_COREPACK_ENABLED │ false │
╰───────────────────────────┴───────────────────────────────────╯ Enjoy it. |
Using @constneo 's example, I was able to get a minimal working setup using nushell on Windows 10 via Windows Terminal by adding:
fnm env --json | from json | load-env
use std "path add"
$env.FNM_BIN = $"($env.FNM_DIR)/bin"
path add $env.FNM_BIN
$env.FNM_MULTISHELL_PATH = $"($env.FNM_DIR)/nodejs"
path add $env.FNM_MULTISHELL_PATH This works with the |
Now that nushell has an eval-like mechanism for setting environment variables, I’d like to open this feature request to also add support for it.
Via the
load-env
command, one can set multiple environment variables, see here:nushell/nushell#3481
Is that enough to make it possible or is something missing?
The text was updated successfully, but these errors were encountered: