Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto detect added dependencies #1113

Closed
ChrisPenner opened this issue Sep 12, 2019 · 19 comments
Closed

Auto detect added dependencies #1113

ChrisPenner opened this issue Sep 12, 2019 · 19 comments

Comments

@ChrisPenner
Copy link

Currently ghcide doesn't notice when I update either package.yaml or *.cabal; so I need to restart it, up till now I've been closing and re-opening my editor, but now I just run killall ghcide; it picks up on the changes when it restarts.

It'd be nice if it could detect changes to those files and restart itself automagically.

Thanks for all the work you do!

@ndmitchell
Copy link
Collaborator

This is super easy to add on the ghcide side once we get the necessary information out of hie-bios. I raised a ticket for that: haskell/hie-bios#35

@domenkozar
Copy link
Contributor

Trickier part will be to report when cradle can't build as per #710

@domenkozar
Copy link
Contributor

@ndmitchell is there some kind of watching api for file changes in ghcide or did you plan to use notify?

@ndmitchell
Copy link
Collaborator

@domenkozar there is an LSP API for file watching which we should use.

@sofusmortensen
Copy link

bump

(this would be really helpful)

@jinwoo
Copy link
Contributor

jinwoo commented Jan 31, 2020

Now that hie-bios provides the information about cradle dependencies (haskell/hie-bios#35), can someone implement this? Some editor plugins can stop/restart the LSP server but others don't, and it's really annoying to quit and restarting the editor whenever this happens.

@ndmitchell
Copy link
Collaborator

Should be easy to implement when someone has the time. Patch welcome, but otherwise it's waiting for someone to have this at the top of their queue.

I also requested restarting in #979, I agree it would be super useful.

@jinwoo
Copy link
Contributor

jinwoo commented Feb 1, 2020

Agreed that #979 would be quite useful as an escape hatch.

Can you give me some hints on how this can be implemented? I have a vague idea that the file watching should be used (either using the LSP API if the client supports it, or ghcide's own support otherwise), and then the language server must be restarted somehow if a file being watched is updated or created. But I'm not quite sure how/where it should be hooked into existing code.

@ndmitchell
Copy link
Collaborator

I think the approach would involve the code at https://github.com/digital-asset/ghcide/blob/master/exe/Main.hs#L204-L207. You get a cradle back, then in the Action monad you need to do something like need files_it_used to add the dependency on them.

@jinwoo
Copy link
Contributor

jinwoo commented Feb 2, 2020

Thanks, Neil! I'll give it a shot.

@jinwoo
Copy link
Contributor

jinwoo commented Feb 3, 2020

@ndmitchell , when you said need, did you mean the needOnDisk in https://github.com/digital-asset/ghcide/blob/master/src/Development/IDE/Core/Shake.hs#L652? And I need to call defineOnDisk (https://github.com/digital-asset/ghcide/blob/master/src/Development/IDE/Core/Shake.hs#L623) to define rules for watching those dependency files?

Or did you mean something else?

@ndmitchell
Copy link
Collaborator

I just mean the normal Development.Shake.need. It's possible that those are better because they get tracking through the file watching, but I'm not familiar enough to know if they'd work better.

@jinwoo
Copy link
Contributor

jinwoo commented Feb 4, 2020

Using need doesn't seem to work because when files like package.yaml or *.cabal change, getCompilerOption from hie-bios must be called again to retrieve the new compile options. But getCompilerOptions is called from cradleToSession, which is memoized from loadSession and we continue to use the old options/session.

So it seems we need a way to invalidate the memoization cache. Whenever any dependency files change, we invalidate the cache, and call getCompilerOption and create a new GHC session. Do you think I'm on the right track?

@ndmitchell
Copy link
Collaborator

Ah, good point - you probably need to switch from memoIO to newCacheIO from Shake, which works at the level of Action, and thus can have need called at the right place. See https://hackage.haskell.org/package/shake-0.18.5/docs/Development-Shake.html#v:newCacheIO

Unfortunately, there's an issue around newCacheIO which is why I went for memoIO in the first place ndmitchell/shake#725. Maybe it needs to be lifted into an oracle? I suspect these complexities were why I didn't do it last time I thought about it...

@jinwoo
Copy link
Contributor

jinwoo commented Feb 4, 2020

Hm.. Not only that. Now I realize that we need to restart the whole language server when files like *.cabal change because loadSession should be called again to have it use a new HscEnvEq that is created from the new GHC options.

Which means we need to add a way to stop the current language server and restart it. This is getting out of hand 😱

@ndmitchell
Copy link
Collaborator

No need to restart the language server - you just have to move the setting up of loadSession onto the Shake graph and it should replace the environment when things change. Not necessary straightforward though.

@jinwoo
Copy link
Contributor

jinwoo commented Feb 5, 2020

All right. Following what you suggested, I made it work barring a few problems. Let me clean it up and hopefully I can send a PR soon.

@jinwoo
Copy link
Contributor

jinwoo commented Feb 21, 2020

I think this can be closed now.

@ndmitchell
Copy link
Collaborator

Thanks for your work on this @jinwoo

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants