Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

hls-render-plugin: Proof of Concept for a mechanism for customizable type driven "Actions"#4604

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
joe-warren wants to merge1 commit intohaskell:master
base:master
Choose a base branch
Loading
fromjoe-warren:render-plugin

Conversation

joe-warren
Copy link
Contributor

@joe-warrenjoe-warren commentedMay 29, 2025
edited
Loading

Hi, new contributor here

I'm opening this as much as a proof of concept as anything.

This PR adds a new plugin, which 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 isIO () it generates a code lens which runs that result.

There's a lot of duplication between this and the eval plugin, and I'd be open to adding this behaviour to the eval plugin instead, but my thought process was that a standalong plugin is more modular, and people might want to turn this off, and not the eval plugin,

I've recorded a demo of the plugin in use,which I've uploaded here


There are a handful of things that I think make this un-mergable as is:

The big one is the mechanism by which I'm evaluating the configuration file; I'm doing this withrunDecls (after parsing out any imports).

This seems to me to be inferior to compiling the file as a module, and then importing it qualified. As there's currently a risk of naming collisions (and the code I have for separating out imports is incomplete, and requires each import to take exactly one line).

I'm also open to changing the name "hls-render-plugin". I didn't want to use the word "action", because I'm aware that actions already means something else in the context of the Language Server Protocol.

I'm using thePretty instance onType, to convert the type of the applied "action" to a string in order to compare it toIO (), I highly suspect this isn't the right way to go about that.

The "stylish-haskell" post-commit action doesn't seem to work if modified files contain C++ preprocessor directives?

Finally, this code is completely untested, and I'm more than happy to fix that if you have any suggestions for sensible tests.

fendor, guibou, georgefst, wolverian, and LupusAnay reacted with thumbs up emojiunhammer reacted with rocket emoji
@deemp
Copy link

@joe-warren in thedemo, you state that the current doctests approach isn't very ergonomic because it requires you to write a comment and to import functions that you're going to use.

Not a HLS contributor, but I'd like to discuss the design that you propose.

Local values, result types, types on hover

New plugin

With your plugin, one can write a number of top-level functions that use local values that are unavailable in the configuration file.

One will then be able to run some of these top-level functions using code lenses that callIO () functions.

One will also be able to see the types of expressions on hover.

t = 3f = idf1 = f t

Doctests

When writing doctests, one can also write top-level functions that use local values that are unavailable in the configuration file.

Doctests may produce not onlyIO ().

Unfortunately, one can't interactively view the types of expressions in doctests. Hence, one needs to create auxiliary functions likef1 and Evaluate them.

t = 3f = idf1 = f t-- >>> f1

Unnecessary function imports

New plugin

New plugin avoids imports by loading the configuration file into a GHCi session.

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.

From thedemo:

I'm doing the equivalent of copying and pasting the contents of that file into the GHCi session.

Doctests

Doctests do require imports.

This fact leads to two problems:

  1. If an import isn't used anywhere else apart from doctests, a warning is displayed that this import is unused.
  2. Imports from local modules in the$setup section don't work #4612

After the second problem is resolved, one will be able to write imports that are necessary only for doctests into a$setup section. Hence, it will be possible to resolve the first problem.

Wrong code lenses

New plugin

The new plugin may display code lenses for combinations of render and ordinary functions that don't make sense. Such code lenses may create a lot of visual noise.

Moreover, each part of the codebase may require own set of render functions. It may not be feasible to put all render functions into a single configuration because the visual noise from code lenses will increase even more.

Doctests

When using the doctests approach, one will see Evaluate code lenses above each doctest.
This visual noise seems acceptable.

Relation to a Haskell package

New plugin

It's unclear whether the configuration file should belong to the Haskell package where the file is used (i.e., be listed in the package's.cabal file). Can HLS show types on hover in the configuration file when you're composing that file?

Doctests

Doctests in a module use functions imported from local and non-local modules (e.g. modules from dependencies on Hackage). Local modules and dependencies are tracked in.cabal files. HLS shows types on hover in local modules.

Conclusion

To sum up, the new plugin provides a slightly less verbose way for composing and runningIO () actions using definitions from a special module (a configuration file), but the plugin may introduce significant visual noise and issues with maintainability of the code in the configuration file.

Despite some overhead in the form of comments and auxiliary functions, doctests might be a more general, more precise, and less noisy solution to the problem of quickly composing and runningIO () actions using definitions from local modules when#4612 is fixed.

joe-warren and soulomoon reacted with thumbs up emoji

@joe-warren
Copy link
ContributorAuthor

The new plugin may display code lenses for combinations of render and ordinary functions that don't make sense. Such code lenses may create a lot of visual noise.

I don't know if I'm too concerned about visual noise from render code lenses, because:

  1. the plugin can be disabled (may be disabled by default)
  2. noisy render actions (actions that typecheck when applied to a lot of values, but don't make sense to evaluate), seems more like a hypothetical issue with a bad configuration, rather than a fundamental issue with the approach

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@fendorfendorAwaiting requested review from fendorfendor will be requested when the pull request is marked ready for reviewfendor is a code owner

At least 1 approving review is required to merge this pull request.

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

2 participants
@joe-warren@deemp

[8]ページ先頭

©2009-2025 Movatter.jp