Auto complete definitions within imports#2152
Conversation
|
Thanks for the fix, great to see tests to exercise it |
|
I am not sure if this fixes #2082. Afaics tests are demonstrating that completions works inside imports lists but the issue is about completions over qualified imports in the body of the module:
|
|
Sorry, I misunderstood the ticket. Will remove from the description. |
To clarify the expected behaviour is functions from MyModule followed by functions from all modules. |
| buildModouleExportMap:: Maybe (ExportsMap) -> DM.Map T.Text [T.Text] | ||
| buildModouleExportMap (Just exportsMap) = do |
There was a problem hiding this comment.
What does this function do?
There was a problem hiding this comment.
I had a typo in the name, however, it builds a map of "module.name" -> ["functions" .. ] which I use to look up the available functions for that module
There was a problem hiding this comment.
And why is it needed? Can't you use the ExportsMap as it is?
There was a problem hiding this comment.
I believe I need it because I have to group on "module.name" and use that as the key to look up all functions within that module. ExportsMap as it is seems to be a map of "function-name" -> [{moduleNameText: "module-name", name: "function-name" ...} ]
There was a problem hiding this comment.
Ah yes, you are right.
But why build a map to do only one lookup and then throw it away?
- Cost of building the map: O(NlogN)
- Cost of doing the lookup by scanning the original exports map: O(N)
Neither is good enough, you want O(logN). How? Probably by changing the representation of the exports map to add a second index, the module name.
There was a problem hiding this comment.
Do you think the first suggestion would be a good first pass? With potential follow up commits to pull out a plugin?
There was a problem hiding this comment.
The ExportsMap only indexes package modules. You will need to fetch the ModIface for local modules. So both changes are needed
There was a problem hiding this comment.
I took a first pass at this. There is still more work to do. As of this comment, I am just generating the map based on the already existing map. I also see that this does not work for local modules, as you suggested.
There was a problem hiding this comment.
Second pass - I generate the map from the modIface rather than the existing map.. This still does not account for local modules
There was a problem hiding this comment.
OK, I now generate the map for local modules as well. I will take a look at your other comments.
dont worry, the pr looks great anyways, lets see if we had a opened issue about |
|
Afaics this fixes #797 (cc @ndmitchell) |
…l-language-server into import-func-completions
160a017 to
f53cc5a
Compare
f53cc5a to
863a483
Compare
|
stack builds are failing: |
…l-language-server into import-func-completions
thank you - this is fixed |
…l-language-server into import-func-completions
…l-language-server into import-func-completions
pepeiborra
left a comment
There was a problem hiding this comment.
Almost there! Just some minor performance improvements requested
…l-language-server into import-func-completions
|
This looks all good, but let's take a look at the Completion benchmark experiments before landing. |
@pepeiborra - What is involved with this step? Is this part of CI or is it a manual step that I should run and report on? Happy to work through it |
There's a CI job that runs the benchmarks, renders the results summary, and produces downloadable artifacts. See https://github.com/haskell/haskell-language-server/actions/runs/1211084983 However the CI results are not entirely reliable, so you can run locally with |
|
Running locally in gitpod, I get the following results : There is a substantial regression in userTime for the "completions after edit" experiment, which takes almost 3 times longer. This is really bad considering that the experiment doesn't actually try to complete within imports - it's just completing on a random identifier inside the module body. Bummer!
Therefore the way forward is to extract import completion out to a new plugin - we don't need a new package, it can stay within ghcide the same way that we split code actions into multiple plugins recently. |
|
Ah, the other thing worth trying is switching from |
Ahh ok, glad this was caught by the experiments! My original implementation made many calls to useWithStaleFast, we still don't want to use that approach, right? One other thought I had would be to pass in I am also happy to separate it out into a separate plugin |
It's not ideal, but would be good to benchmark. Overhead will be seen in the delayedTime column |
…l-language-server into import-func-completions
Just pushed up a commit with this. I am still figuring out how to run the benchmark |
pepeiborra
left a comment
There was a problem hiding this comment.
And that's why benchmarks are important.
Marking this as ready to merge now, follow ups are optional and can be done in future PRs.
Thanks @alexnaspo for your dedication, this was an awesome effort.
jneira
left a comment
There was a problem hiding this comment.
Amazing tour the force from you both @pepeiborra and @alexnaspo, congrats!
|
This fixed (hopefully) #314 |

AutoComplete functions inside a module import
import Control.Applicative (A<cursor-position>)Will auto complete to Alternative, Applicative... etc