-
Notifications
You must be signed in to change notification settings - Fork 97
Conversation
The caching issue is a bit tricky. We want completions to come instantly, and therefore we use There are many ways to solve this problem:
My preference would be for 3 or 2. 1 is a non solution. |
Note (3), we append and do not overwrite. We just happen to overwrite if we have a invalid cache. Another option for caching problem would be to always prepend the new item. For example,
would become, say,
This option can be agnostic to It feels like we should just go with (2), and solve the performance problems. The above solutions are not complete and will lead to unnecessary noise and user frustration. |
Sorry I wasn't more clear. Assuming we want to extend an import declaration with the identifier
Yes, duplicate inserts, if the same completion is used twice in quick succession, will lead to a duplicate identifier in the import list. But this does not constitute a compilation error and hlint will highlight it.
Definitely, (2) is worth exploring. But the end result will be slower completions in some cases, whereas (3) will not impact the performance properties. |
@pepeiborra I chose option (3), and that setup of TextEdit seems to work (wonder why that works though. Is that part of the LSP spec)? Either ways, that approach worked. The only other wart is when starting from an empty list and caching strikes. Here is an example,
After first insert we have, say
Now say, before cache is refreshed, if the user types
Do you see a way to solve this? Update: With the suggestions below, I was able to resolve this issue by adding a trailing comma. |
It seems Haskell permits trailing comma at the end of import list. So, just always prepending, right after |
Interesting. Thanks for pointing that out. |
Haskell permits it, but it's not common style - I would be a bit upset if my IDE automatically changed my code for me, but then I had to go and adjust it back to follow common style. |
To me this is a minor deal. As long as automated formatting tools can parse the modified import list it's ok: I use format-diff-on-save. |
I agree. To be honest, I realised this spec when I used |
I have made all the changes with the assumption that we can add a trailing Looks like the only alternative solution would be to by pass caching. |
We can always do that in a follow-up change if people find the extra commas too annoying. |
Format on save is not common in the Haskell community. In Rust, it inserts imports badly and then format on save fixes them, and it's a bit of a pain. I think we've going to need to remove the trailing commas sooner or later, to improve user experience. |
We should not insert the identifier to the import list directly in some cases, for example: where in A.hs: module I.A where
data Foo = ConsA | ConsB
data Bar = ConsC Neither "render" the identifier with its parent would be enough, because the parent may be already in the import list, thus we should extend it instead. In #916, I try to implement both cases in the code action, just like: and
Actually, extending the imports we do in completions or code actions are similar but in different ways. It would be better if we can reuse some code here... |
@berberman Those are good points I did not consider in this PR. I think its good to a create a new issue and see how the code and behavior can be consolidated. |
It would be nicer to have a configuration option for any new feature that is going to automatically edit source code without the user's input or permission, so that users can opt-in (or at least opt-out). |
Adding a configuration option for every new feature is the way of enterprise. You wouldn't need a configuration option if the feature worked all the time and always did what you want. That's what we should strive for. |
If this feature worked correctly, it would not do what I want. If it worked 100%, I think it would largely defeat the purpose of explicit imports. But more generally, when I ask for something in one place (completion) I don't like my editor to make changes in another place. |
I don't see how autoimports would defeat explicit import lists, maybe you can elaborate. But it's perfectly reasonable to disagree with any feature. However, when a feature does what 99% of users want, I expect the 1% to either send a PR or adjust their expectations. |
Mmm, i agree with @ttuegel, that dont propose add config option for all features but for "invasive" ones. I think that those ones deserves a config option even if they work for most users. Not sure if is enterprisey but i personally consider it a nice ux. |
I still don't see how auto-extending import lists on completions is an invasive feature. |
* Drop any items in explicit import list * Test if imports not included in explicit list show up in completions * Update CompItem to hold additionalTextEdit * Add placeholder value for additionalTextEdit field * Improvement completion tests. * Use explicit fields while constructing CompletionItem * Add function that will extend an import list * Use externalImports to extend import list * Make import list information available * First working prototype of extending import list. * Pass the original importDecl to cacheDataProducer * Add tests for completions with addtional text edits * Hlinting * Refine function name and signature * Pass the original importDecl to cacheDataProducer * Refactor code to use gaurds * Exhaust patterns * Handle empty import list * Use correct pattern * Update expected values in TextEdit * Add test adding imports to empty list * Remove old code * Handle names with underscore * Exhaust patterns * Improve storing of import map * Add trailing comma to import list completions. * Add support for Record snippets * Add 8.8.4 support * Code cleanup.
* Drop any items in explicit import list * Test if imports not included in explicit list show up in completions * Update CompItem to hold additionalTextEdit * Add placeholder value for additionalTextEdit field * Improvement completion tests. * Use explicit fields while constructing CompletionItem * Add function that will extend an import list * Use externalImports to extend import list * Make import list information available * First working prototype of extending import list. * Pass the original importDecl to cacheDataProducer * Add tests for completions with addtional text edits * Hlinting * Refine function name and signature * Pass the original importDecl to cacheDataProducer * Refactor code to use gaurds * Exhaust patterns * Handle empty import list * Use correct pattern * Update expected values in TextEdit * Add test adding imports to empty list * Remove old code * Handle names with underscore * Exhaust patterns * Improve storing of import map * Add trailing comma to import list completions. * Add support for Record snippets * Add 8.8.4 support * Code cleanup.
* Drop any items in explicit import list * Test if imports not included in explicit list show up in completions * Update CompItem to hold additionalTextEdit * Add placeholder value for additionalTextEdit field * Improvement completion tests. * Use explicit fields while constructing CompletionItem * Add function that will extend an import list * Use externalImports to extend import list * Make import list information available * First working prototype of extending import list. * Pass the original importDecl to cacheDataProducer * Add tests for completions with addtional text edits * Hlinting * Refine function name and signature * Pass the original importDecl to cacheDataProducer * Refactor code to use gaurds * Exhaust patterns * Handle empty import list * Use correct pattern * Update expected values in TextEdit * Add test adding imports to empty list * Remove old code * Handle names with underscore * Exhaust patterns * Improve storing of import map * Add trailing comma to import list completions. * Add support for Record snippets * Add 8.8.4 support * Code cleanup.
Address #576 requirement of automatically extending the import list.
Few points to address (and I would like some pointers on this)
Simple working Demo
Items to address:
This PR adds the new item to the last item like this:
Demo: