HLS Render Plugin Demo

I’ve been working on a haskell-language-server plugin.

It’s is conceptually very similar to (and cribs heavily from) hls-eval-plugin.

However, unlike hls-eval-plugin, it’s not triggered by doctest comments, instead it takes a “configuration” file, containing a number of Haskell functions, and for each combination of “value in the current module” and “function in the config”, if the result of applying the function to the value is IO () it generates a code lens which runs that result.

It’s still at the Proof of Concept stage, but I think it’s demoable.

20 Likes

This is pretty cool!

I’ve never really liked the eval plugin, because I don’t like writing non-trivial code in comments, where it isn’t type checked etc.

I’d probably use this a lot if you added either keyboard-based triggers or rerun-on-save.

3 Likes

This is very very cool, especially the waterfall-cad integration demo. Have you got any updates on the PR? Maybe you could add a link here.

Cheers!

3 Likes

Hi, the PR is here

3 Likes

perhaps this should be named hls-render-commands-plugin as the purpose is to expose user-defined commands (in the lsp paralance)? it may also be useful to allow the set of allowable commands to be restricted by name via a pragma of some sort – i.e. just because the type matches, it doesn’t mean a particular action is semantically valid for a given definition.

additionally, what does editor integration for these commands look like? e.g. in emacs, I’d want the ability to trigger elisp from these commands and I’m not that sure what it’d look like – presumably, I’d want to register hooks for new commands I’ve defined. maybe I just attach a new handler for the command to the lsp client?

lastly, how do imports work for this extra module? can I rely on definitions from in-scope cabal packages? could someone publish a standard set of extensible commands to hackage?

1 Like

perhaps this should be named hls-render-commands-plugin as the purpose is to expose user-defined commands (in the lsp paralance)?

This is a great suggestion, I think having some word that implies “command” or “action” in the plugin name would go a long way to making it more obvious what it’s for.

it may also be useful to allow the set of allowable commands to be restricted by name via a pragma of some sort

Interesting idea, I’m curious what exactly you’re thinking this would look like?

– i.e. just because the type matches, it doesn’t mean a particular action is semantically valid for a given definition.

We’re Haskell developers; if it typechecks, it should work, right?

additionally, what does editor integration for these commands look like? e.g. in emacs, I’d want the ability to trigger elisp from these commands and I’m not that sure what it’d look like – presumably, I’d want to register hooks for new commands I’ve defined. maybe I just attach a new handler for the command to the lsp client?

I’m not very familiar with using the LSP in emacs, at the moment the commands show up as code-lenses.

lastly, how do imports work for this extra module? can I rely on definitions from in-scope cabal packages? could someone publish a standard set of extensible commands to hackage?

This is exactly right, you can import modules from any package that’s available in the current project, so a package with a common set of commands would be a great idea.

I think I’d like to get to the point where you can configure the plugin with extra packages that aren’t available in the current project: it seems like a shame that you’d need to add a dependency to your project just to get extra IDE functionality, but I think I’m a ways away from working on that

1 Like

Having them available as code actions rather than code lenses would be great, since eglot (emacs built in lsp client) does not support code lenses. I think hls recently merged code-actions support for the eval-plugin as well actually.

4 Likes

It’s like a Jupyter notebook

1 Like

I also personally have a slight preference for code actions over code lenses. If I could, I would probably turn off all code lenses since I prefer a less noisy textual environment.

What I find quite annoying is the fact that for some reason there appears to be some huge split in LSP regarding what can be a code action and a code lens - for a lot of the stuff in HLS (or actually everything that I can recall) - make import explicit, add type sig to signatureless binding, etc - they could just as well be code actions. I don’t really know if this is an HLS design choice to not expose everything as both a code lens and a code action, or if this is some inherent limitation to LSP

EDIT:

Sorry for hijacking a bit to complain about LSP, but I do want to say - this plugin looks extremely cool!

3 Likes

I don’t really know if this is an HLS design choice to not expose everything as both a code lens and a code action

It’s purely a question of what people have implemented. There is a ticket somewhere saying “it would be great if every code lens was also a code action”. PRs welcome! Especially if someone comes up with a nice interface so the code actions get added automatically!

I’d probably use this a lot if you added either keyboard-based triggers or rerun-on-save.

At Zurihac I was discussing this with someone and I think it would be neat to expand the eval plugin with

  1. The ability to trigger on line-comments, so you could stick them on the end of lines
  2. A different evaluation herald that meant “constantly evaluate”, either by writing it into the file or possibly with an inlay hint