Flexible Haskell - a new plugin for JetBrains IDEs

New Release: Flexible Haskell 2026.1.6

New Features:

  • HLS Code Actions via Alt+Enter: import missing symbols, apply HLint fixes, insert type signatures, and other refactors
  • Inlay Hints: inferred types and parameter names shown inline (toggle in Settings > Editor > Inlay Hints)
  • Code Lenses: inferred type signatures displayed above bindings, click to insert
  • Cross-file Find Usages via HLS
  • 4 New Intention Actions: add type annotation, add LANGUAGE pragma, toggle explicit import list, add deriving clause
  • Auto-closing Pairs: {-# #-} pragmas, (# #) unboxed tuples, [qq| |] quasiquote brackets
  • HLint diagnostics now tagged with [HLint: rule] prefix and rendered as weak warnings



I focused on convenience functions for this. Code actions, inlay hints, code lenses, cross-file find usages, all wired up now. Alt+Enter on a missing import and it gets added. Inferred type signatures show up above your bindings and you can click to insert them. Find Usages searches across files. All of this works with HLS or without (based on PSI lookups, which should be faster in many cases).

Also added four intention actions for common tasks like adding type annotations or LANGUAGE pragmas, and auto-closing pairs for pragmas, unboxed tuples, and quasiquote brackets. Small things that add up.

@develop7: Thanks for the continued push on LSP feature parity.

1 Like

Holy cow, these I missed the most so far!

1 Like

Sweet - moving in the right direction then :slight_smile:

1 Like

@madppiper How do you prefer to receive bug reports?

I’ll report here for now that, when opening a Haskell project, I get each time this error/warning:

java.lang.Throwable: Synchronous execution on EDT: /Users/myuser/.ghcup/ghc/9.14.1/bin/ghc --version, see com.intellij.execution.process.OSProcessHandler#checkEdtAndReadAction() Javadoc for resolutions
	at com.intellij.openapi.diagnostic.Logger.error(Logger.java:375)
	at com.intellij.execution.process.OSProcessHandler.checkEdtAndReadAction(OSProcessHandler.java:165)
	at com.intellij.execution.process.OSProcessHandler.waitFor(OSProcessHandler.java:102)
	at com.intellij.execution.process.CapturingProcessRunner.runProcess(CapturingProcessRunner.java:62)
	at com.intellij.execution.process.CapturingProcessRunner.runProcess(CapturingProcessRunner.java:51)
	at com.intellij.execution.process.CapturingProcessHandler.runProcess(CapturingProcessHandler.java:57)
	at com.ilscipio.language.haskell.sdk.HaskellSdkDetector.getGhcVersion(HaskellSdkDetector.java:336)
	at com.ilscipio.language.haskell.lsp.HaskellEnvironmentWidget.refresh(HaskellEnvironmentWidget.java:81)
	at com.ilscipio.language.haskell.lsp.HaskellEnvironmentWidget.install(HaskellEnvironmentWidget.java:67)
	at com.intellij.openapi.wm.impl.status.IdeStatusBarImpl.addWidgetToSelf$intellij_platform_ide_impl(IdeStatusBarImpl.kt:476)
	at com.intellij.openapi.wm.impl.status.IdeStatusBarImpl$doInit$2.invokeSuspend(IdeStatusBarImpl.kt:411)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
	at com.intellij.openapi.application.TransactionGuardImpl$2.run(TransactionGuardImpl.java:221)
	at com.intellij.openapi.application.impl.NonBlockingFlushQueue.runNextEvent$lambda$4(NonBlockingFlushQueue.kt:358)
	at com.intellij.concurrency.ThreadContext.resetThreadContext(threadContext.kt:294)
	at com.intellij.openapi.application.impl.NonBlockingFlushQueue.runNextEvent(NonBlockingFlushQueue.kt:357)
	at com.intellij.openapi.application.impl.NonBlockingFlushQueue.flushNow(NonBlockingFlushQueue.kt:305)
	at com.intellij.openapi.application.impl.NonBlockingFlushQueue.FLUSH_NOW$lambda$0(NonBlockingFlushQueue.kt:167)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:323)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:732)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:711)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.kt:720)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.kt:573)
	at com.intellij.ide.IdeEventQueue.dispatchEvent$lambda$0$0$0(IdeEventQueue.kt:377)
	at com.intellij.ide.IdeEventQueueKt.performActivity$lambda$0(IdeEventQueue.kt:1110)
	at com.intellij.openapi.application.TransactionGuardImpl.performActivity(TransactionGuardImpl.java:106)
	at com.intellij.ide.IdeEventQueueKt.performActivity(IdeEventQueue.kt:1110)
	at com.intellij.ide.IdeEventQueue.dispatchEvent$lambda$0(IdeEventQueue.kt:375)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.kt:415)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:92)
1 Like

Another issue is that I can’t get alt (or rather, opt on Mac) + enter to trigger any HLS contextual actions:

There’s a hlint suggestion on this line:

Pressing opt+enter on the line does nothing. Right-click opens this menu:

Choosing “Show Context Actions” pops up this:

I don’t see any lines printed to idea.log when doing these actions.

It would be great if you added both to github - that’s easier for me to track. (but it is great that you are messaging me regardless)

Can you also tell me the version you are running on?

I’ll add them to GitHub, thanks. I’m running 2026.1.7.

1 Like

Thank you so much. I am already looking with my colleague Jenni who uses a Mac as well.

2 Likes

(I added GitHub issues: Can't run HLS actions · Issue #12 · ilscipio/flexible-haskell-jetbrains-plugin · GitHub and java.lang.Throwable: Synchronous execution on EDT when opening a Haskell project · Issue #11 · ilscipio/flexible-haskell-jetbrains-plugin · GitHub)

2 Likes

You are amazing, thank you!

1 Like

No worries, it’s very easy for me to support a project to make IDEA a better editor for functional languages and Haskell especially. :slightly_smiling_face: I have some insight into the application framework and language analysis tooling it uses, and I do wish it was more widely used/understood, besides the mono-ecosystem of LSP/VSCode we’ve ended up in.

2 Likes

You are great! And I obviously agree - having options is never a bad thing. And in case of JetBrains, the PSI structure really does have some benefits over LS at some point. Just needs some time and effort…

So thank you for being such a support!

2 Likes

New Release: Flexible Haskell 2026.1.10

New Features:

  • Improved Syntax Highlighting: better fallback to language defaults (#14)
  • Semantic Highlighting: function names, record fields, and exported names in module headers now colored following IntelliJ conventions



Based on lots of @wolverian 's feedback, we are jumping ahead by a few releases. The major new addition is improved highlighting colors. Colors now fall back to your IDE’s language defaults properly, so custom themes work without needing Haskell-specific overrides. Also added semantic highlighting for function names, record fields, and exported names in module headers.

@wolverian: Thanks for flagging the language defaults support (#14).

2 Likes

New Release: Flexible Haskell 2026.1.11

New Features:

  • Smarter Extend Selection (Ctrl+W): now expands through parens, function applications, if/case/let/do/lambda, case alternatives, and function clauses instead of jumping straight from word to whole function (#16)

Keeping it short for this one: @develop7 asked me to improve the extend selection, so here it is - Ctrl+W now expands in sensible steps.

@develop7: Thanks for the detailed feature request with the exact expansion steps mapped out (#16).

3 Likes