haskell / haskell-language-server

Official haskell ide support via language server (LSP). Successor of ghcide & haskell-ide-engine.
Apache License 2.0
2.72k stars 367 forks source link

graphical editor not detecting ghc/cabal/stack due to incomplete $PATH in the init config file #236

Closed dreamsmasher closed 10 months ago

dreamsmasher commented 4 years ago

I'm having some issues with getting the extension to work right - currently, my Cabal installation is from ghcup, and Stack is built from Cabal (GHC 8.8.3). When loading projects in VSCode, I keep getting the error Project requires Cabal but it isn't installed. Stack projects give me the same error but with Stack, and the installation link just takes me to the ghcup page.

I've tried downloading the binary from the releases page and manually adding it to my configuration, as well as building it from source. No luck whatsoever, and using ghcide with the haskell-language-server-wrapper doesn't work either.

System: Arch Linux, i5-7600k, 16GB RAM, GHC 8.8.3

hie.yaml:

cradle:
  cabal:
    - path: "src/Main.hs"
      component: "mmvm:exe:mmvm"

    - path: "src/LibBinary.hs"
      component: "mmvm:exe:mmvm"

    - path: "src/Parse.hs"
      component: "mmvm:exe:mmvm"

    - path: "test"
      component: "mmvm:test:test"

    - path: "src"
      component: "mmvm:test:test"

settings.json:


{
    "editor.fontSize": 16,
    "editor.fontLigatures": true,
    "editor.fontFamily": "Hasklig", 
    "editor.fontWeight": "normal",
    "debug.console.fontFamily": "Terminus (TTF)",
    // "editor.suggestSelection": "first",
    // "vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue",
    "editor.cursorStyle": "block",
    "python.jediEnabled": false,
    "editor.suggestSelection": "first",
    "terminal.integrated.shell.linux": "/bin/zsh",
    "terminal.integrated.fontFamily": "Hack", 
    "terminal.integrated.fontSize": 14,
    "vscode-neovim.neovimPath": "/usr/bin/nvim",
    "vscode-neovim.neovimInitPath": "~/.config/nvim/init.vim",
    "terminal.integrated.fontWeight": "normal",
    "terminal.integrated.fontWeightBold": "bold",
    "python.pythonPath": "/bin/pypy3",
    "workbench.colorTheme": "Wal",
    "haskell.enable": true,
    "haskell.hlintOn": true,
    "C_Cpp.clang_format_path": "/usr/bin/clang",
    "telemetry.enableTelemetry": false,
    "telemetry.enableCrashReporter": false,
    "window.zoomLevel": 2,
    "haskell.logFile": "/home/normie/Documents/misc/hs-hls.log",
    "haskell.trace.server": "messages",
    "haskell.formattingProvider": "brittany"

}

Any help would be appreciated, I'm currently doing fine with ALE/neovim but I'd like to be able to use an IDE for larger projects. Thanks!

lukel97 commented 4 years ago

This is a bit of a silly question, but have you made sure that cabal/stack are on the PATH from VS Code? I.e. can you open up a terminal in VS Code and type cabal repl/stack repl is it able to find it?

dreamsmasher commented 4 years ago

Yes, both cabal repl and stack repl work in the VSCode terminal.

lukel97 commented 4 years ago

Hmm then perhaps that the PATH VS Code is launched with is different from whatever your shell is set as. Were you launching Code from a graphical shell? Is it able to find the binaries if you instead launch Code from your shell via code .?

cronokirby commented 4 years ago

This project:

https://github.com/cronokirby/reg-viz/tree/679ed7e7f25b67d1fc96ef4bba11e7c3c759ede2

Exhibits this error as well, at least on my Linux (Manjaro) machine.

cabal and ghc are available on the PATH, installed through ghcup, and available in the integrated terminal inside VSCode. The project builds fine as well. What's odd is that it was working fine when I started working on the project (before there were any haskell files, just a cabal file), and kept working until I reloaded VSCode, now it doesn't work regardless of if I launch VSCode in a terminal with code . or just open it as a desktop application.

gwils commented 4 years ago

I get this as well, also on Arch Linux. I got my GHC and cabal from ghcup. edit: The version I get is Project requires GHC but it isn't installed

lukel97 commented 4 years ago

@gwils @cronokirby @dreamsmasher Can you try cloning this branch of the extension and running it locally, and see what the PATH error message says? https://github.com/haskell/vscode-haskell/tree/path-debug You should be able to open the project in vscode and just click the run button in the run sidebar, and it should open up another vs code window from which you can open a haskell project or the like

dreamsmasher commented 4 years ago

Sure thing, I’m out of town for a few days but I’ll update when I’m back. Thank you for the help so far.

(also code . didn’t work for me)

gwils commented 4 years ago

The PATH I get from the extension is:

PATH: /opt/google-cloud-sdk/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl

in bash/zsh I get

echo $PATH
/home/george/.cabal/bin:/home/george/.ghcup/bin:/home/george/.cabal/bin:/home/george/.ghcup/bin:/opt/google-cloud-sdk/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl

Note the extra entries on the front - they are added in my .bashrc and .zshrc, courteous of the ghcup installation script.

Edit: By the way, I tried code . from within my shell, and it seems to make it work correctly. I'll use that as a workaround for now!

gwils commented 4 years ago

I've found a better fix for this - rather than adding /home/george/.ghcup/bin and /home/george/.cabal/bin in my .bashrc and .zshrc, I add them in /etc/profile. If I do this, then VSCode/Haskell Language Server will happily pick up the necessary executables and run correctly.

I suspect this fix will work for others on Arch Linux and its derivatives such as Manjaro.

yousefvand commented 4 years ago

Maybe this is related to vscode-oss which is the official package on Arch. Path:

/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl

georgefst commented 4 years ago

I've found a better fix for this - rather than adding /home/george/.ghcup/bin and /home/george/.cabal/bin in my .bashrc and .zshrc, I add them in /etc/profile.

This is the solution. You could also use .profile rather than /etc/profile to set for just the one user. The integrated terminal reads .bashrc, but you wouldn't really expect VScode itself to do so.

I'm not sure there's anything for HLS to do here, except maybe add this info to the README? Since it is admittedly easy to hit, and potentially frustrating.

georgefst commented 4 years ago

Having said that, actually, there may be reasons to not want to add ghc to PATH in .profile.

Perhaps HLS should just provide the option to set the path to ghc explicitly.

dreamsmasher commented 4 years ago

New release of HLS stopped the error from occurring anymore. Thank you to everyone who gave advice!

grizwako commented 4 years ago

Hey, I am on Manjaro/Arch Linux and just ran into this issue today. Did not have anything Haskell related installed until now. Used only ghcup to install everything. When it did not work on the first go, tried cabal new-install Cabal cabal-install too.

Not my first time trying to trick "haskell IDE stuff" into actually working, so I kept digging and finally ran into this issue.

Newcomers might get discouraged by this easily, especially since "cabal and IDE story is fixed now". Adding options to set paths in Extension Settings is good and probably what should be done. Adding info about PATH issues on some distros is OK too, or perhaps even modifying ghcupso it tosses some symlinks to some of the */bin directories.

georgefst commented 4 years ago

New release of HLS stopped the error from occurring anymore. Thank you to everyone who gave advice!

What changed? I'm not sure this is really resolved, as evidenced by @grizwako's issues.

Another option we have would be, rather than polluting the README, to modify messages like Project requires Cabal but it isn't installed to something like Cabal binary not found. If it is installed then perhaps add it to your path in ~/.profile.

Also, do we know if this is actually symptomatic of Arch (or possibly VScode OSS?)? What is e.g. Ubuntu doing differently?

georgefst commented 4 years ago

Actually, seeing as everyone here seems to have come from ghcup, perhaps the real solution is for ghcup to offer to add its paths in .profile rather than .bashrc/.zshrc.

@hasufell Is there any reason not to do this? (To précis the above, certain editors will read only .profile, and so HLS fails to find ghc and cabal on PATH.)

georgefst commented 4 years ago

perhaps the real solution is for ghcup to offer to add its paths in .profile rather than .bashrc/.zshrc

Come to think of it, I believe this is what rustup does anyway.

hasufell commented 4 years ago

Actually, seeing as everyone here seems to have come from ghcup, perhaps the real solution is for ghcup to offer to add its paths in .profile rather than .bashrc/.zshrc.

Clarification: ghcup doesn't do that (and never will). The bootstrap script does that (the thing that runs when you do the curl command).

@hasufell Is there any reason not to do this? (To précis the above, certain editors will read only .profile, and so HLS fails to find ghc and cabal on PATH.)

The bootstrap script tries to not guess too much and keep editing user files to an absolute minimum. This can always go wrong, even if you print 20 warnings to the user. They'll just press enter and then something is messed up, because we couldn't anticipate every possible configuration.

That said, .profile is only used by a couple of shells: Korn Shell, Bourne Shell (the old one, not bash), dash... anything else? The shell detection logic would have to be extended: https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/bootstrap-haskell#L233 That is possible.

However, I don't know exactly what VSCode is doing here anyway. We don't want to edit files "just in case".

georgefst commented 4 years ago

Clarification: ghcup doesn't do that (and never will). The bootstrap script does that

Apologies - that is indeed what I meant.

That said, .profile is only used by a couple of shells

Ah, I hadn't realised that bash only reads .profile if .bash_profile doesn't exist. That is admittedly a slight complication.

georgefst commented 4 years ago

Note that haskell/ghcide#577 is essentially the same issue as this.

jneira commented 4 years ago

reopen, as it would need at least some documentation (change ghcup would be an option?)

hasufell commented 4 years ago

reopen, as it would need at least some documentation (change ghcup would be an option?)

What change exactly?

tom-sherman commented 4 years ago

I'm still seeing this issue even after adding ghc and ghcup directories to my path in ~/.profile and starting code from the my shell. ghc is available in $PATH on every shell I have installed on my system but I still get the error in VSCode. Have I missed out a step?

EDIT: Setting my login shell to fish in the MacOS user settings and restarting solved the issue for me 🤷

jneira commented 4 years ago

@hasufell i wanted to refer this comment:

The shell detection logic would have to be extended: https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/bootstrap-haskell#L233 That is possible.

But i was not sure if it could be a way to solve (or workaround) the issue

hasufell commented 4 years ago

But i was not sure if it could be a way to solve (or workaround) the issue

I still don't know what shell is even in use. And if it's not shell specific, how would we detect the environment?

dreamsmasher commented 3 years ago

Update: got the error again suddenly, adding /home/<username>/.ghcup/bin and /home/<username>/.cabal/bin to /etc/profile fixed it.

jneira commented 3 years ago

issue suggesting add a section about the environment setup in linux: #785

Eugleo commented 3 years ago

The workaround doesn't work for me on MacOS.

PATH="/Users/eugen/.ghcup/bin:/Users/eugen/.cabal/bin:$PATH"

if [ -x /usr/libexec/path_helper ]; then
        eval `/usr/libexec/path_helper -s`
fi

if [ "${BASH-no}" != "no" ]; then
        [ -r /etc/bashrc ] && . /etc/bashrc
fi

And still, opening a .hs file gives me the "Project requires Cabal but it isn't installed" error.

What does work is opening VS Code from terminal. Any pointers why that might be? Probably not HIE issue, but should be documented somewhere.

l8l commented 3 years ago

Not sure if this helps anybody but for me (Arch Linux, 64bit, stack, GHC installed via stack, VS Code) the issue is solved when adding a hie.yaml into my stack project directory containing only the lines

cradle:
  stack:

However, I am somewhat confused that this is necessary because I thought hie stands for haskell-ide-engine and not haskell-language-server. Perhaps someone could help me to clarify why this works and if this is really what I'd like to do?

EDIT: Found out that the hie.yaml is not necessary if one runs stack build in the project folder created by stack new projectname BEFORE opening VS Code. Maybe it would be helpful to prevent this issue by modifying the command stack new projectname such that it runs stack build once automatically directly after creating the project folder?

jneira commented 3 years ago

@I8I hi, not sure if your issue was the same as the originally reported: i guess you have stack in path but you have not cabal (it will even not installed?). So the problem is hls was choosing cabal when you wanted use stack (and then you got Project requires Cabal but it isn't installed?) In absence of an explicit config file hie.yaml, the ide tries to guess the tool you want to use using several criteria: existence of cabal.project or stack.yaml, existence of dist-newstyle or .stack-work, etc. It seems it is able to choose stack if the project has the latter. I think it should choose stack if cabal is not in path so maybe is a bug in the discovery process. has your project a cabal.project file?

However, I am somewhat confused that this is necessary because I thought hie stands for haskell-ide-engine and not haskell-language-server. Perhaps someone could help me to clarify why this works and if this is really what I'd like to do?

Yeah the config file for hls is hie.yaml and it comes from the lib used to setup ghc: hie-bios. That library was used by several ide's, ghcide, haskell-ide-engine and the inheritor of both, haskell-language.server. haskell-ide-engine is somewhat a generic name but coincidentally was the name of one concrete "engine".

l8l commented 3 years ago

thanks for the answer @jneira and thanks a lot for resolving my confusion about the hie.yaml.

I do not get the error Project requires cabal but isn't installed. Instead I get Please ensure that ghcide is compiled with the same GHC installation as the project. There is no cabal.project but a projectname.cabal. However, it is automatically generated by stack new projectname.

It is true that the .stack folder is not present before running stack build but when opening VS code, a .stack - folder is automatically created. However, this still does not resolve the issue. Only after running stack build in the project directory, the library files in .stack are correctly linked and only after that it works. That is why I still think that the developers of stack should modify the command stack new such that it runs stack build automatically once after the operations it currently performs. Then the issue would be resolved.

jneira commented 3 years ago

It seems starting code with --force-user-env can help to set the correct PATH within vscode

mkoloberdin commented 3 years ago

I am experiencing a similar problem with stack projects however it does not seem to be related to PATH since I have Arch Linux's stock stack installed as /usr/bin/stack. Here is an excerpt from VSCodium's log (HLS version 1.4.0):

setInitialDynFlags cradle: Cradle {cradleRootDir = "/path-to-my-project", cradleOptsProg = CradleAction: Stack}
Couldn't load cradle for libdir: (CradleError {cradleErrorDependencies = [], cradleErrorExitCode = ExitSuccess, cradleErrorStderr = ["Couldn't execute stack setup --silent"]},"/path-to-my-project",Nothing,Cradle {cradleRootDir = "/path-to-my-project", cradleOptsProg = CradleAction: Stack})

Note the cradleErrorExitCode = ExitSuccess yet cradleErrorStderr = ["Couldn't execute stack setup --silent"].

mkoloberdin commented 3 years ago

The odd thing is that it works fine with an older version of stackage/ghc (lts-16.31/ghc-8.8.4) but fails with the current lts/ghc (lts-18.10/ghc-8.10.7), the second line (the error message "Couldn't load cradle for libdir...") from the above log excerpt just does not appear in this case and hls works fine.

mkoloberdin commented 3 years ago

OK, looks like it's a hie-bios issue:

$ hie-bios check .
hie-bios: CradleError {cradleErrorDependencies = [], cradleErrorExitCode = ExitSuccess, cradleErrorStderr = ["Couldn't execute stack setup --silent"]}
tau-mask commented 3 years ago

Hello, I ran into this issue with ghcup so I'd like to address a few points (feel free to correct if you are a Unix wizard):

I think that the best solution in order to cater to everyone and keep things simple would be to provide a user setting (haskell.ghcupPath?) to manually set the path to ghcup, just like the Rust extension does. And there could be an extra line in the error message to hint people at the existence of that setting.

georgefst commented 3 years ago

I think that the best solution in order to cater to everyone and keep things simple would be to provide a user setting (haskell.ghcupPath?) to manually set the path to ghcup, just like the Rust extension does. And there could be an extra line in the error message to hint people at the existence of that setting.

I like this.

I've just hit this issue again when setting up a new system. It's easy enough to work around when you know how, but the status quo is going to keep tripping up newcomers, GHCUP+VScode+Linux being a very common combination.

jneira commented 3 years ago

Well i think you could forget (or dont know about) to fill the vscode setting like you could forget or dont know about etc/profile. Arguably the vscode setting would be more a little bit discoverable but ideally you should not have to remember or know neither of both.

georgefst commented 3 years ago

Well i think you could forget (or dont know about) to fill the vscode setting

I think this is addressed by:

And there could be an extra line in the error message to hint people at the existence of that setting.

e.g. "ghcup was found on your PATH but not GHC - perhaps you'd like to set haskell.ghcupPath". And I think with VScode the popup can include a link to the setting. Maybe we can even prepopulate it or suggest $HOME/.ghcup.

jneira commented 3 years ago

hmm and the suggestion could not be about fixing etc/profile? could not gcup itself warn it in the installation process? it would fix it for the rest of tools in one go :-) And it would fix it for other graphical editors.

jneira commented 3 years ago

That said, i am not against a config option to set ghcup as it could be useful in its own, so pr's would be welcomed.

jneira commented 2 years ago

This affects all graphical editors as it is directly caused on how linux windows managers handle the user environment. Windows does not have this problem, afaics.

jneira commented 2 years ago

This seems to be a common issue bewteen vscode and other graphical editors unsing the lsp protocol. See this generic so question: https://stackoverflow.com/questions/43983718. There are several answer which could be useful.

jneira commented 2 years ago

Hi, the last version of the vscode extension just released lets you set a specific environment for the lsp server wrapper, so you can set a specific $PATH in the extension itself writing in .vscode/settings,json:

{ "haskell.serverEnvironment":
  { "PATH": "/path/to/hls:/path/to/ghc:/path/to/cabal" }
}

@georgefst would that also work as an acceptable workaround?

I think this is essentially a issue in the interacion between the editor and the linux/macos window manager and we can only provide workarounds like the mentioned one. So i am inclined to close this one as blocked upstream if nobody disagree

georgefst commented 2 years ago

@georgefst would that also work as an acceptable workaround?

Yes, that's one solution. At the very least, I think HLS should prompt the user toward filling in that setting, whenever it fails to find GHC.

georgefst commented 2 years ago

Hi, the last version of the vscode extension just released lets you set a specific environment for the lsp server wrapper, so you can set a specific $PATH in the extension itself writing in .vscode/settings,json:

This isn't making any difference for me on a new M1 Mac. And unfortunately, neither are any of the other suggestions in this thread.

I always get "Project requires GHC but it isn't installed".

EDIT: at some point this just started working, and I can't work out what changed.

bakuhatu commented 2 years ago

I'm on void linux and tried adding that PATH snippet, but I also get "Project requires GHC but it isn't installed". I tried adding the path of the language server in the "Haskell: Server Executable Path" setting, and the "GHC isn't installed" warning goes away, but still doesn't work.

sepehr500 commented 2 years ago

Having the exact same problem as @bakuhatu

hasufell commented 2 years ago

https://github.com/haskell/vscode-haskell/pull/547 will fix this in the following way:

  1. ghcup can manage all your toolchain via VSCode
  2. if you let ghcup manage your toolchain, all the extension needs is the binary (if it doesn't find it, you can set haskell.ghcupExecutablePath). The extension will then make sure that HLS, cabal, ghc, etc. are also in PATH automatically.
  3. alternatively you can add this to your settings: "haskell.serverEnvironment": { "PATH": "${HOME}/.ghcup/bin:${PATH}" }
deividrvale commented 2 years ago

It seems starting code with --force-user-env can help to set the correct PATH within vscode

That solved it for me. So does that mean vscode doesn't use the user env by default?