-
-
Notifications
You must be signed in to change notification settings - Fork 378
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Coherence of command-line formatters versus formatter plugins #411
Comments
Oh, another irritation of HLS directly picking a version of the formatter is that then the "canonical" formatting of my codebase changes with the version of HLS. I can't pin |
I wonder if it would be possible to take this one step further and make more functionality available via the command line. For example, if I want to apply some fix everywhere in my code, it is often more convenient to automate from the command line than to try to coerce a GUI into doing it (or doing it everywhere manually). But maybe this is a completely separate issue. |
This could be ameliorated with the coming plugin architecture, which is specifically aimed at allowing a given user to configure exactly what plugins they want to use. In time this should lead to a formatter publishing the appropriate plugin descriptor for use in HLS, then this becomes a simple matter of using the same version in both places. |
How would the plugin API help here? Would the formatter provider have to provide N different plugins for N different versions? Or would they be loaded dynamically somehow so the user can choose which one? It seems difficult to make this work in the model where HLS statically depends on a particular formatter (at a particular version). |
Given the plugin descriptor is just a set of callbacks, depending on the separately provided haskell-language-server/exe/Main.hs Lines 38 to 64 in b43a8cd
hls-plugin-api used in the underlying hls, and then allows you to precisely specify which version you want.
|
Okay, but I'd still need to recompile |
I also note that any solution which involves re-compiling a Haskell program rather defeats our attempt to distribute static binaries! |
I think we will end up shipping the binary for the "all included" version (and maybe the ghcide-only version), and leave it up to each site to build their own versions with custom plugin sets. It's more about providing the capability. |
See also cachix/git-hooks.nix#55 |
I was thinking about this again today. I wonder if a compromise solution would be to provide more options. I can think of two ways to do that:
|
Easy said, but I don’t think this is really a simple matter. For example, in order for the CI to use exactly the same formatter, it would have to do the following steps:
This does not align with e.g. my goal of having a linting phase <1 minute. what if, instead, I could do:
This would solve the mismatch problem. |
I politely disagree. Formatting is a fundamental part of writing good, modern Haskell code, and having a formatting check in CI is a very important requirement for any non-hobbyist codebase. Thus, saying “we just provide the capability, but it is up to the user to find out about it and actually figure out how to use that capability” is not really helpful for setting best practices for Haskell developers. What I’d like to see is HLS take a bold step towards encouraging best practices, which includes making CI integration easy to set up. |
Coming back to this, there's already a bit of abstraction over formatting plugins in |
I'd love to see this. I've actually been thinking about this problem for a while, and I'm glad to see I'm not the only one. I'd been meaning to add a "use CLI" option to the Fourmolu plugin, but something more general would obviously be even better. It would help greatly in situations like that described in #2649 (comment), where I want to be able to use the latest version of Fourmolu on a GHC-8.10 codebase, but can't because of dependency conflicts out of Fourmolu's control. |
To be clear this implement's OP's option 1, for Fourmolu only for now. |
I actually meant the reverse in that comment! I meant something like: if we have a formatting plugin, then the plugin could provide a subcommand to HLS so that you can do:
And it would run the formatter "as if" you had called That way you would be sure they line up wrt configuration options, passing in extension flags from HLS, etc. But I also like your approach! |
Ah, my bad for not reading thoroughly. I assumed you were thinking the same thing as me since I saw "HLS would have to call the executable", but I see we're not talking about the same executable. |
Note that the argument about passing the right options to tools applies to other things, e.g. it might be convenient to have |
I found #2763 which apparently added a configuration flag to use the CLI Does someone know if this is possible please? 🙏 |
I don't believe so. It should be pretty straightforward to adapt the Fourmolu plugin's CLI code for Ormolu. |
Other to |
Each project has its own separate requred formatting tool (which is usually provided in the project's nix shell). Formatting is a matter of conformity to a project, not of personal preference, so my editor's "default" formatter is totally irrelevant. These rules were often put in place before HLS existed, and may be more specific than HLS is able to fully support - e.g. I may need not just fourmolu, but specifically fourmolu version 0.12. The "environment follows HLS" option might be useful for some who are adopting new style rules or willing to change them, especially if HLS can do anything that other tools can't do, but it would be useless for most of my work. I like HLS being an optional tool and I don't want to force my colleagues to use it, nor do I want to run it in CI. It's hard to imagine, for comparison, a Java developer who runs IntelliJ in a github action to do style checks? I think there really needs to be invented some standard way (I know, I know) for a repo to specify its formatter, including an option to just point to an executable, that an editor plugin will simply run. However, I do not think that editor plugin should be HLS, because HLS takes so long to load. I am perpetually getting "there is no formtter installed" popups in VSCode when I try to format a file that HLS is still compiling. This should not be necessary; formatters can run without the slow heavyweight analysis that loading into HLS requires. |
That sounds like a separate bug, can you open a ticket? I'm surprised that that happens, since I'd have thought we only need the parsed module. |
Related to haskell#411
Related to haskell#411
Related to haskell#411
#3788 is possibly an example of where HLS can do a "better" job of formatting with fourmolu than the exact same CLI version because it knows more fixities. Of course, in this case having "better" formatting is annoying because they don't line up. This makes me still want |
About the original question: IMHO no matter what, HLS must provide a way to use external binaries, so option 1.
As a rule of thumb, an editor, LSP or really any tool should never be invasive: it must always elegantly coexist with people who don't use it. Otherwise HLS would be closing the ecosystem, preventing non-HLS users to collaborate with HLS users on the same code base. Option 2 can be provided additionally on top of option 1, though in my opinion it is not a good idea:
|
Related to #411 Co-authored-by: Michael Peyton Jones <[email protected]>
As many people do, I have a gate in my CI that ensures that code passes a formatter before it is merged. That formatter (in this case
stylish-haskell
) is run as an executable.If I also use HLS, I can format my code with
stylish-haskell
via the formatter plugin. But this will use the version ofstylish-haskell
that HLS was compiled with, not the one that I have (elsewhere) specified for use in CI.This makes the in-editor formatting useless to me, as I will typically have to reformat with the executable version before my change will pass CI.
I can see two ways to keep things consistent.
Ultimately I think this would mean that HLS would have to call the executable. I understand that this is undesirable since the current model allows us to use the nicer Haskell interfaces to tools and test them easily.
Perhaps we could have some way to format "as-if" using one of the HLS formatting plugins. For example:
haskell-language-server --format --formatter ormolu Foo.hs
.The text was updated successfully, but these errors were encountered: