-
Notifications
You must be signed in to change notification settings - Fork 206
Do plugins the same way as GHC #1
Comments
I think the main thing would be to define what plugin hooks exist, and how separate plugins interact with each other. Another mental model would be closer to a container with shared services for accessing the GHC session and loaded code, as well as access to the iDE |
As an alternative approach we can consider XMonad as a different architecture. |
I think XMonad (and yi) use https://hackage.haskell.org/package/dyre |
Looks like dyre is inspired by XMonad, but XMonad does not use it. Expressing your configuration as a Haskell file can indeed be powerful, but is it really what we want here? I imagine that having more knobs than just "Use these plugins" could easily lead to compatibility issues. For example, it would be unfortunate to need to change your configuration in order to support a particular editor. |
I see project automatic upgrades as one of possible applications, for example GHC 7.8.4 to GHC 7.10.2 or Parsec2 to Parsec3. This application possibly requires rather complicated config to handle all the configuration edge cases. |
Personally I think dynamic reconfiguration is unnecessary. Many (some) editors require a restart to update packages, e.g. spacemacs. Also, since haskell-ide will probably run as a daemon, changing config and Having a simple config format that is more in line with industry standards On Fri, Oct 23, 2015 at 7:56 AM, Gracjan Polak notifications@github.com
|
I've taken a swing at the basics of plugins. Check it out on this branch: https://github.com/haskell/haskell-ide/tree/cli-and-plugins Here's how to use it:
This tells it to load up an example plugin which just consists of a putStrLn. The "app/Main.hs" is passed as a target, which gets used to intiialize a ghc-mod session, but . Here's the expected output: Initializing plugins It turned out to be pretty straightforward to do this plugins stuff. However, I'm a bit concerned that it's a brittle way to do things. You need to compile the plugin against the exact same haskell-ide library that the binary is built against. I think this is likely why things like "hs-plugins" never really caught on. As @gracjan, maybe it makes sense to take the XMonad approach, and have the user compile their own haskell-ide by having a small haskell file which imports the tools they want, and compiles them all together. Here are some positive benefits:
Downsides:
So, we can start using this runtime plugins stuff if people want to, but I think it makes more sense to:
|
By "custom Ide.hs" approach do you mean the XMonad one suggested by @gracjan? Just for completeness, the plugin model could end up being defined as a set of internal service APIs and Pros
Cons
This might be good to take as a very early approach to clarify what interfaces are needed, and then to break it out to the plugin architecture. There is also the middle ground of using the XMonad approach, but then generating the config haskell file from a setup config that is deliberately simple, perhaps just a list of plugins to include, similar to As a tool writer it is appealing to be able to provide the getPluginInfo :: PluginInfo Here the |
It just struck me that Android has a very mature ecosystem for allowing individual apps (== plugins) to coexist and make use of shared infrastructure, including defining new shared infrastructure to be used by other applications. See http://developer.android.com/guide/components/fundamentals.html#ActivatingComponents It may be possible to reuse some of these concepts |
Agreed! I'm thinking this approach might be the main way to do it for quite a while. I should probably explain why the current plugins approach is error-prone: The issue is that you'll need to build your haskell-ide plugins with the haskell-ide package version which corresponds to your installed executable. For example, if you've built a locally modified version, this means you need to know to do one of the following:
Also, when haskell-ide is executed, it will need to know the package-dbs to use to find the installed plugins. These might be different than the package-dbs involved in building the user's code. Building the tools statically into haskell-ide, via the "XMonad.hs" approach, means that there's no potential for version mismatch, and you don't need to know anything about the package DBs used for building the tooling. |
I think that initially we should try to get a handle on how plugins fit together into haskell-ide, and how they share comms to the external IDE, and how those comms are wrapped. This can be explored without going for a complex plugin architecture initially. In fact, the less onerous the better, so we can easily test options for the comms In other words, initial plugins are shims that expose the working part of the thing being plugged in, e.g. HaRe. |
Yup, I'm just saying even in the long run it is likely good to avoid any sort of plugin architecture. It seems quite hard to make it work well for users. |
Ok, I think we are in agreement then. I interpret a plugin as something that complies with a set of internal interfaces and can be easily inserted by someone who does not otherwise know much about haskell-ide |
@mgsloan can you explain a bit more why you think this is the case? |
Presumably your plugin will call into |
Closing this as we have a way of doing it in master now, which is simply adding a library and configuring it in. Nothing dynamic |
Change TypeMap implementation
I'm thinking that a good way to implement plugins is by emulating ghc's plugin system, perhaps even calling functions from it. Based on a quick look at the DynamicLoading module, it seems like it'd be a good approach to just copy+modify the loadPlugin function.
It makes sense to have something similar to the Plugin datatype, and have a field per "callback". Perhaps this is getting into details too early, but maybe these callbacks should be wrapped in Maybes, like the aptly named Hooks datatype. It's informative to know which things a particular plugin hooks into.
The text was updated successfully, but these errors were encountered: