haskell / haskell-language-server

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

Should ignore `.hs` and other source files under system temporary directory (those opened to view Git history etc.) #2360

Open complyue opened 2 years ago

complyue commented 2 years ago

Your environment

Output of haskell-language-server --probe-tools or haskell-language-server-wrapper --probe-tools:

haskell-language-server version: 1.4.0.0 (GHC: 8.10.4) (PATH: /Users/cyue/.ghcup/bin/haskell-language-server-wrapper-1.4.0) (GIT hash: 253547816ee216c53ee7dacc0ad3cac43e863d30)
Tool versions found on the $PATH
cabal:      3.2.0.0
stack:      2.7.3
ghc:        8.8.4

Which OS do you use: MacOS

Which lsp-client do you use: VSCode

Describe your project (alternative: link to the project): any

Contents of hie.yaml: N/A

Steps to reproduce

Open [Git History] view Select a commit Locate a changed .hs file, click the [Previous] link to show diffs to previous version in editor

Expected behaviour

Continue working as usual.

Actual behaviour

Git plugin would create some .hs file from git history, within some folder under system TMP directory, and open it in editor.

HLS would then get triggered "indexing..." forever to figure out settings wrt such temp .hs files, normal IDE features like navigation and formatting will all pend execution. Even after all of the temp file editing tabs closed, and VSCode restarted, the "indexing..." status can not be avoided. Only after those temp files manually deleted, and VSCode restarted/reloaded, it can return to normal operations.

Include debug information

N/A

complyue commented 2 years ago

A workaround: use this extension to clear VSCode's workspace cache

https://marketplace.visualstudio.com/items?itemName=MamoruDS.workspace-cacheclean

But you lose all workspace layout and toggles, which is not really nice.


So seems it is VSCode that keep trying persuade hls (as the language server) to analyze those temp files, even after their editor tabs closed by user.

complyue commented 2 years ago

The temp folder to contain such .hs files resides in somewhere like:

$ echo $TMPDIR
/var/folders/mz/mgxdtrgj3v1372vjd7tt6l_00000gn/T/

While /var/folders/ contains many system daemon related folders giving no read permission to the user account, maybe hls would search some sibling folders for Haskell project files there, and keep retrying upon folder listing / file reading denied?

fendor commented 2 years ago

So seems it is VSCode that keep trying persuade hls (as the language server) to analyze those temp files, even after their editor tabs closed by user.

I think this happens because we can never make sure that you don't want to see diagnostics some time later on, thus we still try to typecheck them...

This seems like an issue other Language Servers should have as well, maybe we should look at them for guidance how to best handle these cases?

maybe hls would search some sibling folders for Haskell project files there

We have no logic to search any other folders, we only load what build-tools give us (e.g. your project configuration). The only exception is that we automatically try to load a file that has just been opened.

complyue commented 2 years ago

We have no logic to search any other folders, we only load what build-tools give us (e.g. your project configuration). The only exception is that we automatically try to load a file that has just been opened.

I suspect that's the embedded build-tools (implicit-hie probably?) doing that search, looking for some project configuration covering a triggering temp file, while there can be no project configuration for it in temp dirs. I don't think it'll search sibling folders for sure, but parent folders to look for project cfg is quite reasonable.

fendor commented 2 years ago

implicit-hie probably?

hie-bios is actually the work-force.

looking for some project configuration covering a triggering temp file, while there can be no project configuration for it in temp dirs.

Right, it will ask the build-tool of the project whether it knows this file, the build-tools says basically, "no", but we try to load it anyway to avoid loops. It causes loops since the client asks us again and again whether there are diagnostics available for this file, and until we load it, we can't say no or yes.

I don't think it'll search sibling folders for sure, but parent folders to look for project cfg is quite reasonable.

If the project has been established already (e.g. you can successfully work in your project), then we perform no search whatsoever, we only ask the build-tool what to do with this file (and the build-tool may perform more searches).

complyue commented 2 years ago

Is there some cmd line against hie-bios I can try to quickly reproduce the result?

If with such a reprod I think I can submit an issue there, even no fully reprod, it may give some clue in its log for why hls would keep "indexing..." ever since then.

fendor commented 2 years ago

Is there some cmd line against hie-bios I can try to quickly reproduce the result?

No, since the combination of HLS and hie-bios cause this issue. LSP asks HLS to typecheck a file. HLS asks hie-bios, do you know that file? Hie-bios says no. HLS loads that file anyway, because otherwise, LSP will ask HLS to typecheck the file again, and we will repeat this process until the end of time.

complyue commented 2 years ago

Hie-bios says no.

I have a bad feeling that hie-bios may even have hit a bottom so that pending to give the "no" answer, thus the hang. Can we exclude that possibility?

fendor commented 2 years ago

Yeah, you can install the executable hie-bios and execute hie-bios debug <name-of-the-file> from your project working directory to see the result.

complyue commented 2 years ago

I'm in a multi-componets project, the cmd line just fail fast:

$ bin/hie-bios debug /var/folders/mz/mgxdtrgj3v1372vjd7tt6l_00000gn/T//8c82658cdcd0406437a563a5bfc1d1a5f06193c21637664530532tmp-4061cmMKfjkFkV2u.hs/Comput.hs

Cradle failed to load
Exit Code: ExitFailure 1
Stderr: Failed to parse result of calling stack

* * * * * * * *
The main module to load is ambiguous. Candidates are: 
1. Package `dedh' component dedh:exe:dedh with main-is file: /fw/m3cyue/edh-universe/e-wrks/dedh/host.hs/repl/Main.hs
2. Package `dedh' component dedh:exe:rundedh with main-is file: /fw/m3cyue/edh-universe/e-wrks/dedh/host.hs/runfile/Main.hs
3. Package `eas' component eas:exe:eas with main-is file: /fw/m3cyue/edh-universe/e-wrks/eas/host.hs/repl/Main.hs
4. Package `edh' component edh:exe:edh with main-is file: /fw/m3cyue/edh-universe/e-wrks/edh/host.hs/repl/Main.hs
5. Package `edh' component edh:exe:edhm with main-is file: /fw/m3cyue/edh-universe/e-wrks/edh/host.hs/runmodu/Main.hs
6. Package `edh' component edh:exe:runedh with main-is file: /fw/m3cyue/edh-universe/e-wrks/edh/host.hs/runfile/Main.hs
7. Package `els' component els:exe:els with main-is file: /fw/m3cyue/edh-universe/e-wrks/els/host.hs/server/Main.hs
8. Package `ghci-code' component ghci-code:exe:ghci-code-tutor with main-is file: /fw/m3cyue/edh-universe/complyue/GHCiCode/ghci-code/tutor/Main.hs
9. Package `hasdim' component hasdim:exe:hasdim with main-is file: /fw/m3cyue/edh-universe/e-wrks/hasdim/host.hs/repl/Main.hs
10. Package `hasdim' component hasdim:exe:rundim with main-is file: /fw/m3cyue/edh-universe/e-wrks/hasdim/host.hs/runfile/Main.hs
11. Package `hasdim' component hasdim:exe:rundimm with main-is file: /fw/m3cyue/edh-universe/e-wrks/hasdim/host.hs/runmodu/Main.hs
12. Package `haskit' component haskit:exe:hski with main-is file: /fw/m3cyue/edh-universe/e-wrks/haskit/host.hs/hski/Main.hs
13. Package `nedh' component nedh:exe:nedh with main-is file: /fw/m3cyue/edh-universe/e-wrks/nedh/host.hs/repl/Main.hs
14. Package `nedh' component nedh:exe:runnedh with main-is file: /fw/m3cyue/edh-universe/e-wrks/nedh/host.hs/runfile/Main.hs
15. Package `sedh' component sedh:exe:forage with main-is file: /fw/m3cyue/edh-universe/e-wrks/sedh/host.hs/forage/Main.hs
16. Package `sedh' component sedh:exe:gwd with main-is file: /fw/m3cyue/edh-universe/e-wrks/sedh/host.hs/gwd/Main.hs
17. Package `sedh' component sedh:exe:swarmcc with main-is file: /fw/m3cyue/edh-universe/e-wrks/sedh/host.hs/swarmcc/Main.hs
18. Package `trade-poc' component trade-poc:exe:wb with main-is file: /fw/m3cyue/edh-universe/frp/trade-poc/host.hs/hski/Main.hs
19. Package `trade-poc' component trade-poc:exe:wo with main-is file: /fw/m3cyue/edh-universe/frp/trade-poc/host.hs/gwd/Main.hs
20. Package `typing' component typing:exe:hst with main-is file: /fw/m3cyue/edh-universe/complyue/typing.hs/src/Main.hs
You can specify which one to pick by: 
 * Specifying targets to stack ghci e.g. stack ghci dedh:exe:dedh
 * Specifying what the main is e.g. stack ghci --main-is dedh:exe:dedh
 * Choosing from the candidate above [1..20]
* * * * * * * *

<stdin>: hGetLine: end of file

$ 

Run from TMPDIR gives:

cymp:/ cyue% cd $TMPDIR
cymp:mgxdtrgj3v1372vjd7tt6l_00000gn/T cyue% /fw/m3cyue/edh-universe/bin/hie-bios debug /var/folders/mz/mgxdtrgj3v1372vjd7tt6l_00000gn/T//8c82658cdcd0406437a563a5bfc1d1a5f06193c21637664530532tmp-4061cmMKfjkFkV2u.hs/Comput.hs

Root directory:      /private/var/folders/mz/mgxdtrgj3v1372vjd7tt6l_00000gn/T
Component directory: /private/var/folders/mz/mgxdtrgj3v1372vjd7tt6l_00000gn/T
GHC options:         
System libraries:    /Users/cyue/.ghcup/ghc/8.8.4/lib/ghc-8.8.4
Config Location:     No explicit config found
Cradle:              Cradle {cradleRootDir = "/private/var/folders/mz/mgxdtrgj3v1372vjd7tt6l_00000gn/T/8c82658cdcd0406437a563a5bfc1d1a5f06193c21637664530532tmp-4061cmMKfjkFkV2u.hs", cradleOptsProg = CradleAction: Default}
Dependencies:        
cymp:mgxdtrgj3v1372vjd7tt6l_00000gn/T cyue% 
fendor commented 2 years ago

For the former, you probably have to generate a hie.yaml file via gen-hie > hie.yaml (https://github.com/Avi-D-coder/implicit-hie). hie-bios on its own doesn't generate one. Sorry, forgot about that.

The latter is correct, but I don't think that is what is going to be executed, since your project type is already identified as a stack project. Does it show errors such as No Prefix matches?

complyue commented 2 years ago

Ah, with an explicitly generated hie.yaml, it won't hang! (hie-bios then give Stderr: Multi Cradle: No prefixes matched instead of exit 1).

But lately (since hls 1.2 or some version), gen-hie > hie.yaml is only necessary when I don't open the project root folder (who directly contains stack.yaml), thanks to implicit-hie integrated with hls.

I always open the project root folder as the first folder for the VSCode workspace nowadays, and it works like a charm, but now temp files would ruin that!