Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Add window/progress reporting for typechecking #1190

Merged
merged 14 commits into from
May 4, 2019

Conversation

lukel97
Copy link
Collaborator

@lukel97 lukel97 commented Apr 22, 2019

Todo

  • Add test
  • haskell-lsp[-types] upload
  • Update vscode-hie-server

Depends on a couple of tweaks with the VS code extension

@lukel97 lukel97 requested review from lorenzo, alanz and fendor April 22, 2019 11:56
lf <- lift $ asks ideEnvLspFuncs
withIndefiniteProgress' lf t f

withIndefiniteProgress' :: MonadIO m => Maybe (Core.LspFuncs Config) -> T.Text -> m a -> m a
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't get this to type check with withIndefiniteProgress = lift . withIndefiniteProgress, this is a workaround. Open to suggestions to make this nicer

Copy link
Collaborator

@fendor fendor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides tests, I think it would be nice to have examples on how to integrate them into a plugin. E.g. some plugins might want to be able to report progress as well. Will that be possible?
Otherwise, great job, the diff is clean and easy to follow!

@@ -344,14 +344,15 @@ data IdeEnv = IdeEnv
}

-- | The class of monads that support common IDE functions, namely IdeM/IdeGhcM/IdeDeferM
class Monad m => MonadIde m where
class MonadIO m => MonadIde m where
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess IO is needed to actually send the message back?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

@alanz
Copy link
Collaborator

alanz commented Apr 22, 2019

What changes are needed for the vscode extension? How portable is this to other clients?

@lukel97
Copy link
Collaborator Author

lukel97 commented Apr 22, 2019

What changes are needed for the vscode extension? How portable is this to other clients?

Mainly updating the client library and enabling the proposed features, haskell/vscode-haskell#150
Since there is a ClientCapabilities for the window/progress notifications, haskell-lsp won't send them unless the client declares it so it should be backwards compatible with other clients

@lukel97
Copy link
Collaborator Author

lukel97 commented Apr 22, 2019

Besides tests, I think it would be nice to have examples on how to integrate them into a plugin. E.g. some plugins might want to be able to report progress as well. Will that be possible?
Otherwise, great job, the diff is clean and easy to follow!

Yup! Since withIndefiniteProgress is inside IdeM, any plugin can just wrap their computations inside it to start a progress session. Are there any long running plugins at the moment we can add this to?

@alanz
Copy link
Collaborator

alanz commented Apr 22, 2019

Are there any long running plugins at the moment we can add this to?

Possibly the liquid haskell one

@lukel97
Copy link
Collaborator Author

lukel97 commented Apr 22, 2019

@alanz @fendor an example:

let progTitle = "Running Liquid Haskell on " <> T.pack (takeFileName file)
tid <- withIndefiniteProgress progTitle $
liftIO $ async $ generateDiagnosics cb uri file


withProgress' :: MonadIO m => Maybe (Core.LspFuncs Config) -> T.Text -> ((Core.Progress -> m ()) -> m a) -> m a
withProgress' lspFuncs t f =
let mWp = Core.withProgress <$> lspFuncs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't it be better to pass the actual Core.withProgress instead of getting it here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the passed in function could be of the form a -> IO (), so obviating the need for MonadIO too.

Copy link
Collaborator Author

@lukel97 lukel97 Apr 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lorenzo currently there is the possibility that lspFuncs returns Nothing, so it would have to be a Maybe, I think this is due to the existence of the JSON transport. I think this also asks the question, should we just give plugins full access to lsp funcs?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either give full access, or make the progress reporting function available to them by default, as in my earlier comment. I think we already do something similar with accessibility to the VFS stuff. I would have to take a look though.

I am very much in favour of constraining what plugins/monads can do, so we do not get weird stuff happening

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reworked the class in 8d1925d, so only the functions that require MonadIO have the constraint. @lorenzo is it ok if once JSONStdio is gone and there is the guarantee of LspFuncs (#1105) I can revisit this to directly pass it instead?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that makes sense

-- 'withProgress' @title f@ wraps a progress reporting session for long running tasks.
-- f is passed a reporting function that can be used to give updates on the progress
-- of the task.
withProgress :: T.Text -> ((Core.Progress -> m ()) -> m a) -> m a
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be ore clear to name this withProgressReport

@mpickering
Copy link
Collaborator

One thing we noticed on IRC is that the type of withProgress needs to be modified so the continuation is of type Progress -> IO (). Otherwise you can't use these functions to pass the callback into GHC for example.

@lukel97
Copy link
Collaborator Author

lukel97 commented Apr 22, 2019

@mpickering see haskell/lsp#154

@lukel97 lukel97 requested review from lorenzo, alanz and fendor and removed request for lorenzo April 23, 2019 19:01
@lukel97 lukel97 marked this pull request as ready for review April 23, 2019 19:09
Copy link
Collaborator

@lorenzo lorenzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

tid <- liftIO $ async $ generateDiagnosics cb uri file
let progTitle = "Running Liquid Haskell on " <> T.pack (takeFileName file)
tid <- withIndefiniteProgress progTitle $
liftIO $ async $ generateDiagnosics cb uri file
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't right. The progress report needs to go inside the call to async and if you do that, you'll discover that the types for withIndefiniteProgress are not quite right still..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You’re right, this completely slipped by me! I was testing it by adding a threadDelay 10000000

@mpickering
Copy link
Collaborator

I don't think this is quite right yet. It's weird that the haskell-lsp functions are all parameterised over MonadIO but the other ones in haskell-lsp aren't. Once you fix those types to IO then you can provide a polymorphic interface in hie-plugin-api by using UnliftIO.

@mpickering
Copy link
Collaborator

mpickering commented Apr 24, 2019

@lukel97
Copy link
Collaborator Author

lukel97 commented Apr 25, 2019

I don't think this is quite right yet. It's weird that the haskell-lsp functions are all parameterised over MonadIO but the other ones in haskell-lsp aren't. Once you fix those types to IO then you can provide a polymorphic interface in hie-plugin-api by using UnliftIO.

You're right: I got ahead of myself and was thinking of withProgress being used in the context of IdeM etc., I agree that haskell-lsp functions should remain in IO.
I'll update this PR and haskell-lsp to cherry-pick in your changes, and I imagine the MonadUnliftIO instance can be used in lots of other places in HIE

Copy link
Collaborator

@mpickering mpickering left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still looks like a few things need cleaning up.

@mpickering
Copy link
Collaborator

You should use the lifted-async package to fix the liquid haskell progress report rather than define the *IO variant.

@lukel97
Copy link
Collaborator Author

lukel97 commented Apr 29, 2019

@mpickering lifted-async worked a charm!

@alanz
Copy link
Collaborator

alanz commented May 1, 2019

@bubba there are now conflicts here

@lukel97
Copy link
Collaborator Author

lukel97 commented May 1, 2019

Will this be merged in time for #1227 ?

@alanz
Copy link
Collaborator

alanz commented May 1, 2019 via email

@lukel97 lukel97 requested a review from mpickering May 2, 2019 22:31
@alanz
Copy link
Collaborator

alanz commented May 4, 2019

@bubba @mpickering Can you guys refresh this so we can merge?

Copy link
Collaborator

@mpickering mpickering left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job.

@alanz alanz merged commit c121eb2 into haskell:master May 4, 2019
@alanz alanz added this to the 2019-05 milestone Jun 1, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants