rikvdkleij / intellij-haskell

IntelliJ plugin for Haskell
https://rikvdkleij.github.io/intellij-haskell/
Apache License 2.0
1.31k stars 94 forks source link

Specify -fobject-code when launching intero #386

Closed chrisdone closed 5 years ago

chrisdone commented 5 years ago

Hi @rikvdkleij

One optimisation that Intero for Emacs uses is to set -fobject-code when launching intero so that only those modules that have changed are recompiled; this scales well for large projects. With the default -fbyte-code all modules are reloaded every time with :load.

(:reload will load just the recent module, but switching modules causes a big reload of everything. So that's a trade-off)

Setting -fdefer-type-errors helps get more type info be available, at the cost of slightly slower compile due to GHC.

Just wanted to add that in case it wasn't known.

rikvdkleij commented 5 years ago

Thanks for your feedback!

Some time again I experimented with that option. The drawback is that :browse! *moduleName does not work anymore. Plugin needs that info to give code completion with type info. The plugin it's parser is not smart enough :smile: I do not see alternative solution for that kind of info.

(:reload will load just the recent module, but switching modules causes a big reload of everything. So that's a trade-off)

The plugin has a preference to call :reload. When user goes to another module, first :load is called. Did not experience issues with that but of course quick loads would help very much the user experience because the REPL can handle only 1 request at a time (within one component).

Setting -fdefer-type-errors helps get more type info be available, at the cost of slightly slower compile due to GHC.

My opinion is that it is worth it.

rikvdkleij commented 5 years ago

About your feedback on Reddit Haskell of using stack build intero --copy-compiler-tool

Can I used that command every time a project is started? So it only builds when intero is not yet build for GHC version of project?

How to manage intero updates? Let's say one project is using LTS13.1 and a new project is using LTS13.6 in which intero is updated. Does intero gets rebuild when latter project is opened?

chrisdone commented 5 years ago

Here's how it works in Intero for Emacs:

It uses the stack path --compiler-tools-bin command which outputs a directory for where, in this project for the GHC version in use, the intero binary should be if it's installed.

chris@precision:~$ stack path --compiler-tools-bin
/home/chris/.stack/compiler-tools/x86_64-linux/ghc-8.6.3/bin

The Emacs package runs that to produce the string $COMPILER_PATH/intero. It runs $COMPILER_PATH/intero --version and checks against its expected version, e.g. 0.1.38, of Intero.

chris@precision:~$ $(stack path --compiler-tools-bin)/intero --version
Intero 0.1.38

If they do not match, or if intero is not installed for this version of GHC, it runs stack build --copy-compiler-tool intero-0.1.38. This is run at the start of a project.

This way you always have the right version of intero for your plugin, and installed against the right GHC for the current project.

rikvdkleij commented 5 years ago

Thanks!

So the latest version of intero has to be defined in the plugin?

Do you know an alternative solution for :browse! *moduleName when -fobject-code is enabled?

chrisdone commented 5 years ago

It's possible to temporarily :set -fbyte-code and :reload to get information for the current module then :set -fobject-code back afterward. Intero does that if it uses :info and doesn't get anything back. It's definitely a matter of figuring out what works for you at this point.

rikvdkleij commented 5 years ago

Done in beta45, https://github.com/rikvdkleij/intellij-haskell/releases/tag/v1.0.0-beta45. Also uploaded to the JB plugin repo but can take some days before they have approved.

Created alternative solution for :browse! *moduleName by using the parser and type info.

REPL switches to byte-code when info is requested.