Improvments to REPL tab-completion (#3227)#3231
Improvments to REPL tab-completion (#3227)#3231hdgarrood merged 1 commit intopurescript:masterfrom rndnoise:master
Conversation
|
|
||
| -- * State helpers | ||
|
|
||
| updateImportExports :: PSCiState -> PSCiState |
There was a problem hiding this comment.
Could you add a comment here saying something like
This function updates the Imports and Exports values in the PSCiState, which are used for handling completions. This function must be called whenever the PSCiState is modified to ensure that completions remain accurate.
There was a problem hiding this comment.
Alternatively, is it worth using an explicit export list and hiding the PSCiState constructor so that we can easily verify that the PSCiState can't get out of sync?
There was a problem hiding this comment.
Yeah, I think both are good ideas.
|
|
||
| initialPSCiState :: PSCiState | ||
| initialPSCiState = PSCiState [] [] [] | ||
| initialPSCiState = updateImportExports (PSCiState [] [] [] nullImports nullExports) |
There was a problem hiding this comment.
Will updateImportExports do anything here?
There was a problem hiding this comment.
Yes, perhaps surprisingly. It adds the types from Prim, which is implicitly imported in the module created in that function.
tests/TestPsci/CompletionTest.hs
Outdated
| , ("G", ["GT"]) | ||
| , ("P.G", ["P.GT"]) | ||
| , ("P.uni", ["P.unit"]) | ||
| , ("voi", []) -- import Prelude exclude (void) |
There was a problem hiding this comment.
The syntax is import Prelude hiding (void)
|
I've hidden the I also made an optimization to |
|
The build is failing due to an unused function |
|
After a closer look, I don't think |
hdgarrood
left a comment
There was a problem hiding this comment.
Thanks for this, and the commit speeding up the REPL tests in particular looks great! However, it is really useful for us to be able to keep separate things in separate commits so that the history is easier to look over later, and also in case we ever need to revert one of the changes (but not the other). So would you mind splitting that off for now?
Removing any code which is now obsolete is definitely a good idea 👍
I just realised it would probably be helpful to add a comment near initialPSCiState to clarify the reason we need to use updateImportsExports there?
Also, looking at this I realised that we haven't actually managed to guarantee that the Imports and Exports stay in sync this way; if you export just the fields of a record type you're still able to modify the values that those fields have if you're given a value of that type. For instance, the change in app/Command/REPL.hs is changing the psciLoadedExterns directly, and not going via the utility functions exported by Types. I think we would need to convert PSCiState to a normal constructor (rather than using the record style) and define each of the accessors as normal functions rather than record fields to be able to guarantee that the state can only be modified in a certain way. But if doing it this way seems like it would be any more difficult than just a few mechanical translations then let's not worry about it for now.
| print' $ showModules importedModules | ||
| return () | ||
| st <- get | ||
| print' $ showModules (psciImportedModules st) |
There was a problem hiding this comment.
Bit of a nitpick, but using $ as well as parens on the same line is stylistically perhaps not the best thing to do. I don't mind which but would you mind sticking to one or the other?
|
OK, I think I've addressed all of your points.
Sure, it is done. In general though, how do contributors here manage related or interdependent pull requests? Should those not be made into PRs until the dependency has been merged, or do people create PRs that have stacked on other PR branches?
I've removed that call and exported
Good catch. I saw a compiler error halfway through making that change and assumed it confirmed my guess that I could export the type without exporting the constructor, but it must have been a different error. It is now a data declaration with some extra "getter" methods, so now it shouldn't be possible to take apart or build a
No problem. |
| , psciLoadedExterns :: [(P.Module, P.ExternsFile)] | ||
| } deriving Show | ||
| [ImportedModule] -- ^ psciImportedModules | ||
| [P.Declaration] -- ^ psciLetBindings |
There was a problem hiding this comment.
Haddock is crashing on this line. It doesn't seem like you're allowed to annotate the individual arguments to a constructor, just the whole constructor or record fields: https://www.haskell.org/haddock/doc/html/ch03s02.html
hdgarrood
left a comment
There was a problem hiding this comment.
In general though, how do contributors here manage related or interdependent pull requests? Should those not be made into PRs until the dependency has been merged, or do people create PRs that have stacked on other PR branches?
I've seen both approaches used and they both seem to work fine. I think if you open a new PR which depends on some other still-open PR, we'd probably ask you to rebase it after we've merged the first one.
| module Language.PureScript.Interactive.Types | ||
| ( PSCiConfig(..) | ||
| , PSCiState -- constructor is not exported, to prevent psciImports and psciExports from | ||
| -- becoming inconsistent with importedModules, letBindnigs and loadedExterns |
|
This looks great; I'm happy to merge once CI is passing. |
- Complete all names that have been imported (transitively or directly) - Do not complete names that haven't been imported - Only recompute list of names after import or adding a let binding rather than after each request for name completion This commit fixes #3227
hdgarrood
left a comment
There was a problem hiding this comment.
Great, thanks very much!
rather than after each request for name completion
This pull request fixes #3227