nvm icon indicating copy to clipboard operation
nvm copied to clipboard

bash snippet in README.md is very slow - here is a faster alternative

Open akarelas opened this issue 11 months ago • 6 comments

Operating system and version: Linux with bash and perl interpreter

The bash snippet suggested at https://github.com/nvm-sh/nvm?tab=readme-ov-file#bash is tremendously slow - on every single 'cd' the user types, there is a delay before reaching the target dir, regardless of whether the same or a different version of node needs to be used, and this can be counter-productive and annoying.

This is why I wrote the following .bashrc snippet, which can replace the aforementioned. Nevertheless, it uses Perl (even though it's a .bashrc snippet). However, if you do have Perl installed, it is incredibly faster than the (currently) official one.

cdnvm() {
    command cd "$@" || return $?
    eval $(perl <<'END'
        use File::Basename;
        use Cwd;
        use feature 'say';
        
        my $dir = getcwd;
        while (1) {
            if (-f "$dir/.nvmrc") {
                my $current_v = `node -v` =~ s/^v|\s+\z//gr;
                open my $fh, '<', "$dir/.nvmrc" or die "Couldn't read $dir/.nvmrc: $!";
                my $this_v = <$fh> =~ s/^v|\s+\z//gr;
                if ($this_v ne $current_v) {
                    say 'nvm use';
                }
                last;
            }
            last if $dir eq '/';
            $dir = dirname $dir;
        }
END
    )
}

alias cd='cdnvm'
cdnvm "$PWD" || exit

akarelas avatar Jan 11 '25 22:01 akarelas

Given that perl isn't guaranteed to be installed, I'm not sure it makes sense to add this to the readme.

ljharb avatar Jan 12 '25 00:01 ljharb

Maybe someone or some AI can translate it to bash?

akarelas avatar Jan 12 '25 05:01 akarelas

Here's a .bashrc snippet without perl that achieves the same thing (It's AI-generated, since my bash skills aren't good enough):

cdnvm() {
    command cd "$@" || return $?
    eval $(bash <<'END'
        dir=$(pwd)
        while true; do
            if [ -f "$dir/.nvmrc" ]; then
                current_v=$(node -v | sed 's/^v//; s/[[:space:]]*$//')
                this_v=$(cat "$dir/.nvmrc" | sed 's/^v//; s/[[:space:]]*$//')
                
                if [ "$this_v" != "$current_v" ]; then
                    echo "nvm use"
                fi
                break
            fi
            
            if [ "$dir" = "/" ]; then
                break
            fi
            
            dir=$(dirname "$dir")
        done
END
    )
}

alias cd='cdnvm'
cdnvm "$PWD" || exit

akarelas avatar Jan 12 '25 06:01 akarelas

I wouldn't inflict AI output on anyone; if someone who's an expert in both bash and perl can manually translate it, that'd be great - otherwise it's best omitted.

ljharb avatar Feb 03 '25 18:02 ljharb

Given that perl isn't guaranteed to be installed, I'm not sure it makes sense to add this to the readme.

It is a given though, as all modern linux distros and macOS versions include perl installed and available in the system path by default.

SoCuul avatar Mar 06 '25 09:03 SoCuul

nvm works on all posix shells, and perl isn’t guaranteed to be available by posix.

ljharb avatar Mar 06 '25 15:03 ljharb