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

Change Hsimport to use configured Formatter on import #1167

Merged
merged 2 commits into from
Apr 18, 2019

Conversation

fendor
Copy link
Collaborator

@fendor fendor commented Apr 8, 2019

Closes #1115

Adds a function to get the configured formatter plugin.
Configures HsImport to use the configured formatter.

Add PluginCommands to format lines of text for Birttany and Floskell.
Add FormatTextCmdParams for the Cmd.

TODO:

  • [ ] Formatting Options should be honored. Will not be adressed in this PR.

@fendor fendor force-pushed the hsimport-use-formattingprovider branch 2 times, most recently from 647f45b to 90268c5 Compare April 8, 2019 21:26
@fendor fendor requested review from lukel97, alanz and wz1000 April 8, 2019 21:26
src/Haskell/Ide/Engine/Plugin/HsImport.hs Outdated Show resolved Hide resolved
-- ---------------------------------------------------------------------

getFormattingPlugin :: Config -> IdePlugins -> Maybe (PluginDescriptor, FormattingProvider)
getFormattingPlugin config plugins = do
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this happen inside R so Config and IdePlugins don’t need to be passed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hardly, since IdeGhcM does not implement R, or can execute R, so other plugins would have no access to it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see, I didn't notice it was being called elsewhere outside of LspStdio.hs. I feel like this should be moved into PluginIdeMonads.hs though, and made polymorphic over MonadIde, which should have access to both. We'll need to figure out how to give R access to it though

getFormattingPlugin :: Config -> IdePlugins -> Maybe (PluginDescriptor, FormattingProvider)
getFormattingPlugin config plugins = do
let providerName = formattingProvider config
fmtPlugin <- Map.lookup providerName (ipMap plugins)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is actually wrong, since we look up the name, but the Plugins Map is of Type Map PluginId PluginDescriptor

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But it works, since due to some lucky coincidence pluginId == pluginName.

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 think it would be better if PluginId would be a newtype.

src/Haskell/Ide/Engine/Plugin/Brittany.hs Outdated Show resolved Hide resolved
src/Haskell/Ide/Engine/Plugin/HsImport.hs Outdated Show resolved Hide resolved
-- ---------------------------------------------------------------------

getFormattingPlugin :: Config -> IdePlugins -> Maybe (PluginDescriptor, FormattingProvider)
getFormattingPlugin config plugins = do
Copy link
Collaborator

Choose a reason for hiding this comment

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

I see, I didn't notice it was being called elsewhere outside of LspStdio.hs. I feel like this should be moved into PluginIdeMonads.hs though, and made polymorphic over MonadIde, which should have access to both. We'll need to figure out how to give R access to it though

@fendor fendor requested a review from lukel97 April 10, 2019 19:26
@fendor fendor mentioned this pull request Apr 10, 2019
3 tasks
@fendor fendor force-pushed the hsimport-use-formattingprovider branch 2 times, most recently from d2cd15e to 3d77363 Compare April 11, 2019 10:11
@lukel97
Copy link
Collaborator

lukel97 commented Apr 11, 2019

@fendor I've created a PR for your PR on your fork, it changes HsImport to use the formatting providers directly, by applying TextEdits to TextEdits

@fendor
Copy link
Collaborator Author

fendor commented Apr 12, 2019

Dont merge, yet, did a mistake while rebasing.

@fendor fendor force-pushed the hsimport-use-formattingprovider branch from d0ac0d2 to f441449 Compare April 12, 2019 11:59
@fendor
Copy link
Collaborator Author

fendor commented Apr 13, 2019

Ok, that was awkward. Although these are not clean commits, I think everything should be as expected now...

let (range, selectedContents) = case typ of
FormatDocument -> (fullRange contents, contents)
FormatRange r -> (r, extractRange r contents)
result = reformat config (uriToFilePath uri) (BS.fromStrict (T.encodeUtf8 selectedContents))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why use uriToFilePath and not the file variable?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No particular reason, it was like that when I found it.

@fendor fendor force-pushed the hsimport-use-formattingprovider branch from 3e97f32 to e5713e0 Compare April 13, 2019 18:07
@fendor fendor force-pushed the hsimport-use-formattingprovider branch from 70baa51 to 7ef6e4b Compare April 13, 2019 18:37
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.

One small comment but otherwise I think looks fine. @bubba should give it his approval first.

-> Uri
-> FormattingType
-> FormattingOptions
-> m (IdeResult [TextEdit])
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you use this at another type of than IdeM?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No. It is an abstraction, so it might be used in another type, but not yet. Afaik, by using another Monad, it might be possible to either wait for a response or to get it immediately.
If this is bad style, we can drop it, though.

Copy link
Collaborator

@lukel97 lukel97 left a comment

Choose a reason for hiding this comment

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

Sorry it took me a while to get to this, this is great!

-> FormattingType -- ^ How much to format
-> FormattingOptions -- ^ Options for the formatter
-> IdeDeferM (IdeResult [TextEdit]) -- ^ Result of the formatting or the unchanged text.
-> IdeM (IdeResult [TextEdit]) -- ^ Result of the formatting or the unchanged text.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This used to be IdeDeferM because brittany needs the GHC parsed source to work. Now that it is IdeM, will be potentially lose formatting under some circumstances?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Brittany's FormattingProvider doesn't use ifCachedModule/withCachedModule on master at the moment, so it looks like it wouldn't have been waiting for the parsed source

provider :: FormattingProvider
provider uri formatType opts = pluginGetFile "brittanyCmd: " uri $ \file -> do
confFile <- liftIO $ getConfFile file
mtext <- readVFS uri
case mtext of
Nothing -> return $ IdeResultFail (IdeError InternalError "File was not open" Null)
Just text -> case formatType of
FormatRange r -> do
res <- liftIO $ runBrittany tabSize confFile $ extractRange r text
case res of
Left err -> return $ IdeResultFail (IdeError PluginError
(T.pack $ "brittanyCmd: " ++ unlines (map showErr err)) Null)
Right newText -> do
let textEdit = J.TextEdit (normalize r) newText
return $ IdeResultOk [textEdit]
FormatDocument -> do
res <- liftIO $ runBrittany tabSize confFile text
case res of
Left err -> return $ IdeResultFail (IdeError PluginError
(T.pack $ "brittanyCmd: " ++ unlines (map showErr err)) Null)
Right newText ->
return $ IdeResultOk [J.TextEdit (fullRange text) newText]
where tabSize = opts ^. J.tabSize

It looks like I moved it from IdeGhcM to IdeM in this commit, and in retrospect I should have given a second thought as to why it was In IdeGhcM in the first place.
runBrittany just runs in IO: does it access the same ghc-mod instance as HIE?

Copy link
Collaborator

Choose a reason for hiding this comment

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

runBrittany just runs in IO: does it access the same ghc-mod instance as HIE?

Good question. I think once my HaRe update to use the new hie-bios is done we will have a clearer view of the API, and can ask brittany to expose something that makes use of the module caching

If it does not, then IdeDeferM makes no difference.

@fendor
Copy link
Collaborator Author

fendor commented Apr 18, 2019

In my opinion, this is ready to merge.

@alanz alanz merged commit 93718bd into haskell:master Apr 18, 2019
@alanz alanz added this to the 2019-04 milestone May 4, 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.

importModule always formats with brittany
4 participants