Closed predragnikolic closed 2 years ago
I’m trying to manually set PATH
with settings but this seems to not be working. Similar configuration (where I manually adjust PATH
) works for SublimeLinter.
Node path is not available on PATH
by default (I’m running different Node versions with nvm so I manually switch them in every shell). It works when I start from terminal with added Node path.
{
"clients": {
"LSP-typescript": {
"env": {
"PATH": "~/.nvm/current/bin:$PATH"
}
}
}
}
Why don't you just follow setup mentioned in the guide? It even mentions the nvm
case.
I was following explanation for nvm
but it didn’t work.
If I set that path explicitly in .bash_profile
in export PATH="..."
statement and open editor from terminal, binary folder is correctly picked up and Node executable is recognized.
If I remove it from PATH
in .bash_profile
and add it to JSON configuration which I wrote in comment, Node executable is not picked up.
I want to avoid adding Node on every shell startup, so adding it through JSON configuration is excellent choice. I was under the impression that this will be used as PATH
for that particular LSP implementation. For example, this is how it works for SublimeLinter configuration:
{
"linters": {
"eslint": {
"selector": "text.html.svelte, text.html.vue, source.js - meta.attribute-with-value",
"env": {
"PATH": "~/.nvm/current/bin:$PATH"
}
},
"stylelint": {
"env": {
"PATH": "~/.nvm/current/bin:$PATH"
}
},
"shellcheck": {
"selector": "source.shell"
}
}
}
Try this but in LSP-typescript settings (Preferences: LSP-typescript settings
from the Command Palette).
{
"env": {
"PATH": "~/.nvm/current/bin"
}
}
I'd still recommend doing as the documentation explains and make nvm init script run from .bash_profile
or .zprofile
. Then you don't need to customize all those settings and you have universal solution that works across all ST packages.
Note that modifying .bash_profile
requires re-login for the changes to be picked up (on Linux at least).
Try this but in LSP-typescript settings (
Preferences: LSP-typescript settings
from the Command Palette). …
I did that already and it doesn’t work. So basically what this should do is append/prepend env.PATH
to current Sublime PATH
(probably sourced from .bash_profile
), but without changing it globally (reffering to the comment)? What’s the best way to debug this so I can see what’s the final PATH
used to locate Node executable? Also, I’m on macOS so maybe that should also count, but it’s *nix system in the way that these basic shell things should work (I guess).
I'd still recommend doing as the documentation explains and make nvm init script run from
.bash_profile
or.zprofile
. Then you don't need to customize all those settings and you have universal solution that works across all ST packages.Note that modifying
.bash_profile
requires re-login for the changes to be picked up (on Linux at least).
This is exactly what I’m trying to avoid, so I was expecting it to work just like with SublimeLinter when setting environment with settings. I mentioned that in previous comment.
OK, I've tried that and indeed that doesn't work. That's because we try to install the node dependencies before starting the sever and that already requires node to be in the PATH (or a LSP-local one to be used).
I guess if we would want to address that case then the fix would have to be in the https://github.com/sublimelsp/lsp_utils and it would need to allow specifying your own path to the node runtime.
OK, I've tried that and indeed that doesn't work. That's because we try to install the node dependencies before starting the sever and that already requires node to be in the PATH (or a LSP-local one to be used).
OK, so I guess I’m not crazy 😅
It isn’t possible to first modify PATH
and then try to install depenndencies?
I guess if we would want to address that case then the fix would have to be in the sublimelsp/lsp_utils and it would need to allow specifying your own path to the node runtime.
So I guess this will be new option for nodejs_runtime
option, or if it’s not system
or local
, just use value verbatim and assume that’s the path where node
and npm
are located?
Or maybe add support for env.PATH
to lsp_utils.sublime-settings
so it’s aligned with other implementations, and count for the value of env.PATH
when resolving system
value for nodejs_runtime
? This means updating global PATH
though since system
lookup expectes that Node and npm are available in PATH
.
What's the best way for now to not loose the server ? stop package control from upgrading the plugin (lsp-pyright, ...) ?
What's the best way for now to not loose the server, stop package control from upgrading the plugin (lsp-pyright, ...) ?
Package Control has this setting (in Package Control.sublime-settings
):
{
// Packages to not auto upgrade
"auto_upgrade_ignore": [],
}
yes I already did that, my question is whether that's the best way.
Hmm, I experienced something strange since yesterday. Previously, LSP could find Node.js in $PATH. But now it can't. On the other hand, LSP has no problem with rust-analyzer.
The changes I made earlier only changed my Desktop Environment. There shouldn't be any effect right?
What is the error exactly when it can't find node?
Sorry, I was not clear. The warning is more or less like the title of this isue.
All LSP-* packages that depend on Node.js, cannot be used.
Can you also check the ST console for related message? I think it might be complaining about version of Node being too old.
Ideally use Node 14 if you have something older.
Oh I'm sorry. Turns out I forgot to install npm. It's fine now.
Thank you very much.
I suddenly ran into this issue as well. Moving the nvm init script from ~/.zshrc
to ~/.zprofile
as suggested above fixed it. Not entirely sure why it was working before? (helpful background on ST PROFILE handling in general here).
fwiw it seems a confusion is that many nvm install instructions (brew info
, nvm README etc.) suggest .zshrc
as a first choice for the init script rather than .zprofile
.
My solution was to just add
os.environ["PATH"] = os.pathsep.join(set(os.environ["PATH"].split(os.pathsep) + ["/usr/local/bin"]))
Near the top of every *.py file containing either os.getenv("PATH")
or os.environ["PATH"]
.
It's heavy handed, clunky, and gross, but it worked. (sort of, now LSP doesn't always start on open... and I cannot seem to start it manually)
Prior to that I duplicated my dotfiles to the appropriate profile
/rc
versions.
I think the fundamental issue is that Sublime's OS implementation is not reading the path from /etc/pass
and doesn't look for dotfiles. Can't speak for Linux for n00b reasons, but almost everything on OSX gets linked into /usr/local/bin
. You can't add links to the places on python's path variable with sudo
, ime.
It would probably be better if you wouldn't suggest such, as you called it, "gross" solutions. There are already solutions that are clean and work so not sure why they wouldn't for you.
ST on macOS prints something like:
environment variables loaded using: /bin/zsh -l
in its console on start. If that doesn't error out then it does work as long as you've extended the PATH in the proper file (as described in LSP documentation linked in the initial comment).
I've never seen that message before at all. Up until a handfull of reinstalls and manual clearances ago, I'd get ~20 lines in the console about watch activity, but never saw anything about environment variables. Now it's back to "normal" (more like I'm used to on windows) but still don't see anything about variables. Doesn't show up in a text search either.
The problem, before now, was that the LSP plguins simply would not start (for any of the dozen or so servers I'd installed. Trying to access through context menus was idempotent. Sometimes it would randomly start up, but disappear again as soon as I'd restart ST.
After a completely formatting all traces of ST under AppSupport and reinstalling (RIP my hotly exited notes, lol), it now seems to be behaving itself. We'll see how it goes (I think it's because I started with subl
command).
... I want to avoid adding Node on every shell startup, so adding it through JSON configuration is excellent choice. I was under the impression that this will be used as
PATH
for that particular LSP implementation. ...
@niksy I have the exact same concern. I'm using nvm and none of the solutions worked for me. Adding the init as recommended to my shell rc file slows its startup time considerably:
# Taken from nvm repo (https://github.com/nvm-sh/nvm#install--update-script)
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
Before getting into sublime, it's important to say I had this function defined in my shell to address the slow init issue (NVM_DIR was already exported in my .profile equivalent):
# Set nvm
unalias setnvm 2>/dev/null
setnvm () {
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
}
Now, what fixed the issue with Sublime LSP-* for me was defining a wrapper function around subl
(below the setnvm
definition). Zsh users, this is my solution:
unalias subl 2>/dev/null; unset -f subl 2>/dev/null
subl() {
if command -v nvm &>/dev/null; then
PATH=$PATH $(whence -p subl) "$@"
else
setnvm
PATH=$PATH $(whence -p subl) "$@"
fi
}
Caveats: It probably won't work if you open sublime through a graphical interface (like clicking on a desktop[¹] menu or files in a file manager). I use a terminal for most things, so that "half" solution is enough for me.
Bash users, you can try this on your .bashrc or equivalent. No guarantees though:
unalias setnvm 2>/dev/null
setnvm () {
if [ -z ${NVM_DIR+x} ]; then
export NVM_DIR="${XDG_DATA_HOME:-"$HOME/.local/share"}/nvm"
export NVM_SYMLINK_CURRENT=true
fi
if [ -z ${NPM_CONFIG_USERCONFIG+x} ]; then
export NPM_CONFIG_USERCONFIG="${XDG_CONFIG_HOME:-"$HOME/.config"}/npm/npmrc"
fi
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
}
unalias subl 2>/dev/null; unset -f subl 2>/dev/null
subl() {
if command -v nvm &>/dev/null; then
PATH="$PATH" "$(type -P subl)" "$@"
else
setnvm
PATH="$PATH" "$(type -P subl)" "$@"
fi
}
@condekind yeah, that’s what I was thinking of doing, but I end up doing nothing and just making sure that Node is available in PATH
on starting Sublime Text from terminal. It’s error prone, but I got muscle memory by now 😄
It would be great to have this natively!
@niksy I'm not planning on adding such option to lsp_utils. If you want to hardcode the path without using the nvm
init script then it's as easy to do that in .zprofile
as it would be in a dedicated lsp_utils option. And the latter would require a lot more changes to handle that.
@rchl understandable!
This happens because for some reason the LSP developers decided to manage the installation of these tools.
You can see throughout the code base that they have class methods for storage_path
and binary_path
as in they expect to be managing these paths...
None of this would be a drama if instead:
command $EXPECTED_BINARY_NAME
from the following order: cwd of the currently open file, the root of the current folder project, where ever subl
was executed fromasdf-vm
Currently, all the LSP tools only work if I execute subl
from the root of the project directory first.
If for some reason all the windows close (like when i logout of the desktop) and login again, launch sublime from desktop launcher, all the previously open windows (that had working scoped instances of LSP) now have broken instances of LSP because the CWD is different.
It's pretty annoying.
Another reason why LSP and co shouldn't be managing the installation or making assumptions about where the binaries are is that every project will use different versions of these tools (precisley the value proposition of asdf). LSP forces you to use incorrect versions of the tools across your projects.
change my mind.
change my mind.
I'm unsure if I can because it sounds like you're set in your ways, but I'll bite.
You can see throughout the code base that they have class methods for storage_path and binary_path as in they expect to be managing these paths...
Experience has shown that the majority of users enjoy this VSCode-esque level comfort.
If for some reason all the windows close (like when i logout of the desktop) and login again, launch sublime from desktop launcher, all the previously open windows (that had working scoped instances of LSP) now have broken instances of LSP because the CWD is different.
I'm fairly confused on what the problem is here. The current working directory should not matter for language servers.
If you want some kind of virtual-env-esque thing you should probably define custom client overrides in a .sublime-project or write your client config entirely in a .sublime-project file.
Another reason why LSP and co shouldn't be managing the installation or making assumptions about where the binaries are is that every project will use different versions of these tools (precisley the value proposition of asdf). LSP forces you to use incorrect versions of the tools across your projects.
It depends on the programming language whether that's a problem. Some language runtimes like Deno or Dart package the language server along with the runtime, which the ST package will then take care of. Others like LSP-typescript adapt to your typescript version of your project transparently. There has been some discussion about running things in docker containers which remains unresolved.
What server are we talking about here?
You can always manage things yourself by writing your client config in LSP.sublime-settings.
None of this would be a drama if instead:
There's really not much drama from my experience.
Yo, not sure if I posted this here or not (sure I did on the sublimetext forums) but there's a plugin that fixes this issue on MacOS/OSX. It's called [ProjectEnvironment]() - it's also on package control. It's a shame to need an additional plug in for this, but I guess that's just the kind of suffering we signed up for when choosing sublime on mac... switched to linux about a week after finding this though lol
Here's a settings object. (the important bit is settings.osx
)
// ProjectEnvironment.sublime-settings
// Settings in here override those in "/ProjectEnvironment/ProjectEnvironment.sublime-settings",
{
// If true some debugging information will be preinted on console
"print_output": false,
// If true some variables available in Sublime's API, will be exposed as
// standard environment variables.
// these are:
// "project_path", "project", "project_name", "project_base_name", "packages"
"set_sublime_variables": false,
// It may be useful to add a prefix to those variables so that they don't confict with yours
"sublime_variables_prefix": "",
// those variables can be all capitalised if you wish. "project" will become "PROJECT"
"sublime_variables_capitalized": false,
// files with this extensions will be run through source_vars(.bat|.sh)
// DON'T FORGET THE DOT!
"command_line_to_wrap_extensions": [
".bat",
".sh"
],
// This is only for windows, since Mac and Linux can use shebang:
"execute_ext_with": {
".py": "python",
".zsh": "zsh",
".sh": "zsh",
".bash": "bash"
},
"settings": {
"project_environment": {
"env": {},
"env_file": "",
"windows": {},
"osx": {
"PATH": "$PATH:/usr/local/bin",
"env_file": "~/.zshenv"
},
"linux": {}
}
}
}
but yeah, this should allow your environment to persist across sessions.
sorry, I think I used the wrong link before but my connection is so slow that I can't even edit my last post. Here's the ProjectEnvironment repo: https://bitbucket.org/daniele-niero/sublimeprojectenvironment
@kendfss,
For global PATH adjustments all you have to do is carefully read https://lsp.sublimetext.io/troubleshooting/#updating-the-path-used-by-lsp-servers
For per-project PATH adjustments, there's already a facility in LSP that can handle that. You can adjust the "env"
key in the client configuration in your .sublime-project: https://lsp.sublimetext.io/guides/client_configuration/#client-configuration
@rwols, cool, so why is this still open?
It's a sticky issue to guide people.
To be fair it can be closed and pinned. But maybe it should be just unpinned because with a lot of confusion that is going through the comments it might be more confusing than helpful.
Fyi, if you are using ZSH with oh-my-zsh, you may only have a ~/.zshrc
file and not a ~/.zprofile
.
What fixed this for me was to manually create an empty ~/.zprofile
file with only the bits needed to adjust thePATH
, as described in the guide.
This might be a root cause of confusion for people?
I had the same problem. I solved it by downloading Node.js without NVM and making sure that both "node" and "npm" binaries are accessible from my PATH (the LSP plugin looks for both). This way no additional configuration is needed in Sublime Text.
This is just a guide on how to handle this issue.
If you get a popup saying:
Could not start LSP-* due to not being able to find Node.js runtime on the PATH. Press the "Install Node.js" button to install Node.js automatically (note that it will be installed locally for LSP and will not affect your system otherwise).
Depending if you already have Node.js installed on your system the fix is the following:
You don't have node installed on your system.
a) Press the
Install Node.js
button and LSP will automatically install the Node Runtime locally(Node V12 will be installed at the time of writing). It won't install Node globally!b) You manually download and install Node.js. Keep in mind that there are some servers that don't work with specific versions of Node. (an error message will be printed in ST console(ctrl+`) if that is the case. For example
LSP-intelephense: Error: Ignoring system Node.js runtime due to an error. Node.js version requirement failed. Expected minimum: 10.0.0, got 8.17.0.
)You have Node install on your system.
If you still see this popup "Could not start LSP-* due to not being able to find Node.js runtime on the PATH" but you have Node in your $PATH, that means that Sublime Text didn't pick up your $PATH. See https://lsp.sublimetext.io/troubleshooting/#updating-the-path-used-by-lsp-servers on how to resolve this.
Feel free to make suggestions to improve this guide. :)