haskell / haskell-ide-engine

The engine for haskell ide-integration. Not an IDE
BSD 3-Clause "New" or "Revised" License
2.38k stars 210 forks source link

Format imports #492

Closed domenkozar closed 6 years ago

domenkozar commented 6 years ago

I'm missing a way to format imports. This would save me some time. For example:

import qualified Data.Text  as T
import qualified Data.ByteString.Lazy.Char8 as BS
import Servant.Server
import Servant.Generic
import Servant.Swagger
import Servant.Swagger.UI
import Control.Monad.Reader (ask, liftIO)

To become

import           Control.Monad.Reader       (ask, liftIO)
import qualified Data.ByteString.Lazy.Char8 as BS
import qualified Data.Text                  as T
import           Servant.Generic
import           Servant.Server
import           Servant.Swagger
import           Servant.Swagger.UI
alanz commented 6 years ago

This could be implemented as a command, executed via runPluginCommand (See https://github.com/haskell/haskell-ide-engine/blob/master/src/Haskell/Ide/Engine/Transport/LspStdio.hs#L586), to return a workspaceEdit.

lspitzner commented 6 years ago

Brittany already has a PR (that really is 99% done and I do a really bad job as a maintainer to not have done the remaining 1% and merging.) that does this. See https://github.com/lspitzner/brittany/pull/83, which should be considered open still (github does not like me reorganizing branches).

lspitzner commented 6 years ago

@domenkozar The PR is now about to be merged and released. brittany would format your example as

import           Control.Monad.Reader           ( ask
                                                , liftIO
                                                )
import qualified Data.ByteString.Lazy.Char8    as BS
import qualified Data.Text                     as T
import           Servant.Generic
import           Servant.Server
import           Servant.Swagger
import           Servant.Swagger.UI

and you can try other examples at https://hexagoxel.de/brittany/, which I have updated to the PR's branch already. Feedback welcome if you find any examples that are formatted in some unfortunate fashion.

alanz commented 6 years ago

@lspitzner Is there any way to tweak that?

Because having the itemised import stuff way off on the right looks really odd to me.

lspitzner commented 6 years ago

@alanz using IndentPolicyLeft has an effect; with that all "hanging indentation" is avoided. But otherwise there is no configuration (yet). What layouting would you prefer? Iirc stylish haskell is rather similar, only it uses "paragraph fill" instead of "one line per item".

alanz commented 6 years ago

I feel myself descending into bikeshedding, so I will put one response then refrain further.

I would personally prefer something more like

import           Control.Monad.Reader
                   ( ask
                   , liftIO
                   )

Or even a paragraph fill type thing, but at that indentation.

lspitzner commented 6 years ago

Oh, right! the column is configurable, using lconfig_importColumn in the config file. We discussed the best default a bit and ended up changing the default from 60 to 50. I had not really considered to put it as low as 20, but that should work like you have it there. (Cannot test right now because I cabal updated and now I have to rebuild half the world, will report in a bit.)

lspitzner commented 6 years ago

with lconfig_importColumn = 21 you'd get

import           Control.Monad.Reader
                   ( ask
                   , liftIO
                   )
import qualified Data.ByteString.Lazy.Char8
                  as BS
import qualified Data.Text
                  as T
import           Servant.Generic
import           Servant.Server
import           Servant.Swagger
import           Servant.Swagger.UI

Btw I don't mind the bikeshedding - a formatter's design is mostly about the bikeshed's default colour after all. Only perhaps this thread is the wrong place for it. But feedback over at https://github.com/lspitzner/brittany/pull/124 is certainly welcome.

domenkozar commented 6 years ago

@alanz so all this needs is brittany bump? :)

lspitzner commented 6 years ago

@domenkozar I'd need to release a new brittany version first :-)

lspitzner commented 6 years ago

and that will probably happen in the next days (there is one other PR lined up to be reviewed, but otherwise it is ready).

alanz commented 6 years ago

And I guess you can't do

import           Control.Monad.Reader
                   ( ask
                   , liftIO
                   )
import qualified Data.ByteString.Lazy.Char8 as BS
import qualified Data.Text                  as T
import           Servant.Generic
import           Servant.Server
import           Servant.Swagger
import           Servant.Swagger.UI

?

lspitzner commented 6 years ago

No, not yet. The config setting currently affects the column for both the explicit-list-items and for the as. But this seems to be a trivial addition, I'll look into it later.

alanz commented 6 years ago

@lspitzner I understand that you will manage the release of the new brittany, and then make a PR on hie.

If not, let me know when/if I need to do something.

domenkozar commented 6 years ago

Just waiting on brittany release - thank you!

lspitzner commented 6 years ago

See #505.

@alanz I have implemented the option to format like

import           Control.Monad.Reader
                   ( ask
                   , liftIO
                   )
import qualified Data.ByteString.Lazy.Char8 as BS
import qualified Data.Text                  as T
import           Servant.Generic
import           Servant.Server
import           Servant.Swagger
import           Servant.Swagger.UI

see "alternative" at https://github.com/lspitzner/brittany/blob/master/doc/showcases/Module.md

alanz commented 6 years ago

Can we close this now?