Repository navigation
Conversation
f146702 to
52a388b
Compare
|
I believe the failure is ghcide test |
|
@mrkkrp Definitely flakey, don't worry about it :) |
| case T.decodeUtf8' out of | ||
| Left _ -> throwError $ PluginInternalError "Tilia printed output that is not valid UTF-8" | ||
| Right after | ||
| | after == contents -> pure Nothing |
There was a problem hiding this comment.
Why do you treat this case specially? makeDiffTextEdit will just not generate a difference any way
There was a problem hiding this comment.
Fair point, I amended the commit.
|
Can you tell us a little bit about tilia? |
Tilia reads the .cabal file: it finds the component the module belongs to and takes the language and extensions from it (evaluating conditionals as Cabal does), so DynFlags' extensions would tell it nothing new for a cabal project. It formats all branches of CPP conditionals rather than one configuration, so the -D flags of one build don't apply either; version macros it takes from the build plan. What it does need is the fixities of imported operators, which it gets by reading dependencies' sources/interface files (for those that are installed) according to the build plan, with a cache. That is where HLS could help, since it already has the interfaces, but it would take a new entry point in Tilia, so I'd leave it for a follow-up. |
HLS could tell tilia about the DynFlags and the fixities, so it could do less work, no need to go rummage for a .cabal and cabal.project file.
Out of curiosity, how does it do that?
This seems to indicate, if
Does this mean tilia looks at the plan.json and then goes and parses the .hi files of used dependencies? |
It first locates the It's been working well in practice. I am currently able to format almost all of Hackage with Tilia, including libraries like
It works in any case, but the first invocation will be slower, because it will ask Cabal to solve a plan via (It can also work without Cabal with an explicit build plan you provide, but that's advanced usage I won't describe here.)
Tilia guarantees resolution of fixities with absolute precision—this is another novelty compared to Ormolu/Fourmolu (they use a hardcoded dump based on Hoogle, which is simple and efficient, but quite often incorrect/incomplete). Build plan informs Tilia of the dependencies involved and we build an index which lists modules of each dependency (again, that's cached). Then there are 3 paths: local modules (there, Tilia correctly takes into account fixities of the project it is currently formatting, even fixities that are local to a particular There is a blog post: https://markkarpov.com/post/announcing-tilia. Back to what you are saying regarding saving work—I agree completely. I just thought we'd land this initial version and then iterate, but maybe we could land the final version right away... In fact, I have this PR mrkkrp/tilia#235 which prepares a bridge so that Tilia will be able to load all the useful knowledge from HLS. That will be both fast and precise. I will need to review it before it lands. I am on vacation right now, but I plan to merge that when I am back, then I will release 0.1.2.0 and amend this PR. I guess I could drop the external mode altogether, unless you think it still useful for something? I mostly mimicked the existing Ormolu/Fourmolu plugins here, not sure how useful having two options really is. |
4ed42b8 to
a4aa435
Compare
|
@fendor I've updated the PR with the new design: source useful information from HLS and fall back to "normal" way of operating if HLS has no GHC session for the file in question. I've removed the "external" mode that calls an external |
Tilia (https://github.com/mrkkrp/tilia) formats a module with the extensions, dependencies and operator fixities of the project it belongs to. The plugin calls Tilia.Editor in process and hands it what HLS's session already knows about the file: the extensions its component puts in force, the versions of the compiler and of the packages it depends on, and the interface of every module it can import, from the project's own modules, compiled already or compiled now, to modules of packages the component cannot import, such as ghc-internal, where base declares most of the operators it reexports. Where HLS has no session for the file, Tilia works the project out with Cabal itself. The plugin formats whole modules and refuses range requests.
|
@fendor Is there anything I can do to help to move this forward? |
|
@mrkkrp Thank you for the ping, PR slipped my mind, will get to it in the next days! |
Tilia (https://github.com/mrkkrp/tilia) formats a module with the extensions, dependencies and operator fixities of the project it belongs to, all of which it works out from the module's path. The plugin calls
Tilia.Editorin process, or withhaskell.plugin.tilia.config.externalrunstilia for-editor FILEwith the buffer on standard input. It formats whole modules and refuses range requests.This whole PR was generated by Claude code (Opus 5.5 1M context). If it comes to it, I believe I can explain every line of it.