zdharma-continuum / fast-syntax-highlighting

Feature-rich syntax highlighting for ZSH

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Very low speed on WSL2

opened this issue · comments

After installing the plugin typing in the shell became very slow. There is a delay after each typed letter. zsh-syntax-highlighting has the same issue.

Details:

Yeah, I have the same issue particularly with large blocks of code. This type of issue is actually pretty common with WSL, and it usually comes back to path lookups, by default (you can disable it) the windows system path is added to WSLs $PATH, this adds effectively a networked drive with several folders containing a large number of files, this drastically slows down PATH lookups. Often a simple solution is to remove all folders starting with /mnt/c from the path when the user is running WSL (can check for WSL_DISTRO_NAME), for programs that do not need to search windows paths.

This is a little bash snippet to remove the slow windows paths, not sure how useful it will be in the context of this script, but removing those paths does fix the speed.

PATH=$(echo $PATH | sed s/:/\\n/g | grep -v '/mnt/c' | sed ':a;N;$!ba;s/\n/:/g')

Thank you for your reply and sorry for noticing so late. Will defenitely try this and tell you about the result when I have some free time.

Thanks! It helped!

Great, but that was really just an example, WSL actually has a built-in option to disable adding windows PATHs to WSL's PATH, but this isn't really ideal as accessing windows executables via PATH is often useful. Ideally, this would be built into fast-syntax-highlighting somehow.

I suppose an alternative for the end-user is to disable adding windows PATHs and instead to use a whitelist approach and create aliases pointing to the windows executables that you want to access. A benefit of this approach is that it would solve the slow path issue for all affected applications.

commented

Great, but that was really just an example, WSL actually has a built-in option to disable adding windows PATHs to WSL's PATH, but this isn't really ideal as accessing windows executables via PATH is often useful. Ideally, this would be built into fast-syntax-highlighting somehow.

I suppose an alternative for the end-user is to disable adding windows PATHs and instead to use a whitelist approach and create aliases pointing to the windows executables that you want to access. A benefit of this approach is that it would solve the slow path issue for all affected applications.

Can you talk about how to disable it?
I also encountered this problem on wsl2.

commented

@BigTear

In /etc/wsl.conf (create if it doesn't exist) add:

[interop]
appendWindowsPath=false

Afterwards run wsl --shutdown and open a new session for the changes to take effect. Note that this will mean Windows executables are no longer in your PATH, e.g., commands like code will no longer work. I think this is better anyway bc it unclutters your WSL PATH and could prevent any problems arising from using the Windows version of something accidentally when you meant to use the Linux version. However, you will manually need to re-add all the Windows executables you care about, like code either:

by creating an alias for the executable

alias code="/mnt/c/[your vscode installation directory]/bin/code"

or by creating a new script that redirects code to the executable

#!/usr/bin/env bash

/mnt/c/[your vscode installation directory]/bin/code "$@"

Also if you do that latter, remember you need to run chmod +x on it and make it available in your PATH for it to be executable from anywhere.

e.g.

# assuming "$HOME/.local/bin" exists and is on your PATH...
echo -e '#!/usr/bin/env bash\n/mnt/c/[your vscode installation directory]/bin/code "$@"' > "$HOME/.local/bin/code"
chmod +x "$HOME/.local/bin/code"

You could also just re-add the executable directory to your PATH variable, but I think that defeats the purpose of cleaning /mnt/* entries from your PATH.

**2018-05-25**
Hash holding paths that shouldn't be grepped (globbed) – blacklist for slow disks, mounts, etc.:
```zsh
typeset -gA FAST_BLIST_PATTERNS
FAST_BLIST_PATTERNS[/mount/nfs1/*]=1
FAST_BLIST_PATTERNS[/mount/disk2/*]=1
```

This setting should help you, although I haven't tested it yet.
It looks similar to zsh-syntax-highlighting.ZSH_HIGHLIGHT_DIRS_BLACKLIST.

I've also been experimenting with disabling windows paths as @strawhat-dev showed and while it's a bit more work is at least a universal solution.
I went down the path of using symlinks for the windows executables instead, as it's simple and then they're available globally. e.g.

sudo ln -s /mnt/c/Windows/System32/cmd.exe /usr/local/bin/cmd.exe

I've also created this little function to still allow me to easily run windows executables. It could also be made into a bash script executable.

# facilitate windows executable interop
function exe {
    target=$(wslpath "$(awk -F$'\r' 'NR == 1 {printf "%s", $1}' <<< $(/mnt/c/Windows/System32/cmd.exe /c where $1 2>/dev/null))")
    if [[ "$target" == "." ]]; then
      echo "Command '$1' not found."
    else
        $target ${@:2}
    fi
}

Now, I can run anything from the windows path, with the following.

exe powershell -nop -c echo Hello World

It's worth noting that accessing windows exe's like this you have to pay the 130ms+ cost of resolving the path, using the full path or a link to the executable is going to be faster, but this is great for one-offs.

This setting should help you, although I haven't tested it yet. It looks similar to zsh-syntax-highlighting.ZSH_HIGHLIGHT_DIRS_BLACKLIST.

Nice, that looks like what we've been looking for, I'll have to give it a try as well.