Skip to content
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

Fix weird behavior of OPTIONS_GHC completions (fixes #3908) #4031

Merged
merged 3 commits into from
Feb 10, 2024

Conversation

jhrcek
Copy link
Collaborator

@jhrcek jhrcek commented Feb 1, 2024

Reproducer for #3908

The issue is that getCompletionPrefix on this line doesn't correctly identify the "already typed prefix of the ghc option".
It thinks the prefix is only the part up to '-' (e.g. in the reproducer it tries to fuzzy match prefix "fo" instead of "dsuppress-constant-fo" against existing flags), which can be also seen in the suggestion dropdown (note only "fo" is highlighted).
Screenshot from 2024-02-01 07-53-49

I'll take some time over weekend to try to fix this. In the meantime I welcome any suggestions as to what would be the proper way to fix this.

  1. modify getCompletionPrefix to accept larger prefix (seems too dangerous, as it's used by a lot of code already)?
  2. create custom version of "prefix finder" tailored to ghc options (my plan)?

NOTE: although the tests seem to pass, it's due to issue on master due to which most tests are not running - this is being resolved in #4028

@jhrcek jhrcek marked this pull request as draft February 1, 2024 06:54
@michaelpj
Copy link
Collaborator

getCompletionPrefix is mis-named: it finds completion prefixes for Haskell identifiers. So yeah, we need a custom one. Maybe we can make it more generic, not sure?

Also note that it's moved to Logic.hs in ghcide, I'm going to get rid of the one in lsp at some point, it should never have been there.

@michaelpj
Copy link
Collaborator

The use in the cabal plugin is likely also wrong for this reason!

@jhrcek jhrcek force-pushed the jhrcek/fix-OPTIONS_GHC-autocomplete branch from f76ca86 to 1835e21 Compare February 4, 2024 08:23
@jhrcek jhrcek changed the title Add reproducer for bug in OPTIONS_GHC completions (#3908) Fix weird behavior of OPTIONS_GHC completions (fixes #3908) Feb 4, 2024
@jhrcek jhrcek force-pushed the jhrcek/fix-OPTIONS_GHC-autocomplete branch from 1835e21 to 0c81fb2 Compare February 4, 2024 08:25
@jhrcek jhrcek marked this pull request as ready for review February 4, 2024 08:38
@jhrcek
Copy link
Collaborator Author

jhrcek commented Feb 4, 2024

Here's how it works after the fix in this PR:

Peek 2024-02-04 09-37

@@ -904,7 +904,7 @@ getCompletionPrefix pos@(Position l c) (VFS.VirtualFile _ _ ropetext) =
lastMaybe = headMaybe . reverse

-- grab the entire line the cursor is at
curLine <- headMaybe $ T.lines $ Rope.toText
curLine <- headMaybe $ Rope.lines
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is supposed to be faster than Text.lines, so why not use it here as well..
https://hackage.haskell.org/package/text-rope-0.2/docs/Data-Text-Lines.html#v:lines

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! We really need to audit all uses of Rope.toText, maybe even give it a hlint hint. It's generally unnecessarily expensive and does work proportional to the length of the document...

@fendor
Copy link
Collaborator

fendor commented Feb 4, 2024

The use in the cabal plugin is likely also wrong for this reason!

IIRC, hls-cabal-plugin introduces its own completion prefix function due to / in filepaths.

@@ -904,7 +904,7 @@ getCompletionPrefix pos@(Position l c) (VFS.VirtualFile _ _ ropetext) =
lastMaybe = headMaybe . reverse

-- grab the entire line the cursor is at
curLine <- headMaybe $ T.lines $ Rope.toText
curLine <- headMaybe $ Rope.lines
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! We really need to audit all uses of Rope.toText, maybe even give it a hlint hint. It's generally unnecessarily expensive and does work proportional to the length of the document...

| "{-# options_ghc" `T.isPrefixOf` line
= map buildCompletion
(Fuzzy.simpleFilter (VFS.prefixText pfix) flags)
= let flagPrefix = getGhcOptionPrefix cursorPos cnts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic here feels a little bad; we're passing in pfix here and no longer using it at all. Maybe we can refactor it a bit?

Copy link
Collaborator Author

@jhrcek jhrcek Feb 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by "refactor a bit"?

I did localized change in fear of breaking existing functionality.

I can look into rewriting the whole thing so that the pragmas plugin doesn't use VFS.getCompletionPrefix from lsp package at all. I actually didn't notice there were two versions of that (one in ghcide and one in lsp).

Or did you mean something like pulling out this options_ghc branch from the result helper and have structure like this?

-            result <$> VFS.getCompletionPrefix position cnts
+
+            (result <$> VFS.getCompletionPrefix cursorPos cnts)
+           <|> 
+           (mkGhcOptionCompletions <$> getGhcOptionCompletionPrefix cursorPos cnts))

and treating option prefixes

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's what I meant. I didn't meant to say that the pragmas plugin shouldn't be using the generic getCompletionPrefix function (although that's almost certainly true, for the same reasons!), just that the particular branch that you're changing now sits oddly.

I actually didn't notice there were two versions of that (one in ghcide and one in lsp).

I'm going to kill the lsp one, so ignore that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On reflection, I don't want to block this on doing the refactoring, so I'm happy to leave it up to you whether you want to do that now or not. If not, maybe leave a note explaining the weirdness.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll get back to this and try if I can clean it up. It just needs a bit more focus time that I'm unlikely to get during workdays 😄

@jhrcek jhrcek marked this pull request as draft February 5, 2024 04:07
@jhrcek jhrcek force-pushed the jhrcek/fix-OPTIONS_GHC-autocomplete branch from 0c81fb2 to bfabdef Compare February 9, 2024 18:59
@jhrcek jhrcek marked this pull request as ready for review February 9, 2024 18:59
@jhrcek jhrcek force-pushed the jhrcek/fix-OPTIONS_GHC-autocomplete branch 2 times, most recently from 1c74f2a to 8b02ab4 Compare February 9, 2024 19:03
@jhrcek jhrcek force-pushed the jhrcek/fix-OPTIONS_GHC-autocomplete branch from 8b02ab4 to 7942f99 Compare February 9, 2024 19:05
@jhrcek
Copy link
Collaborator Author

jhrcek commented Feb 9, 2024

I did my best to reuse the results of getCompletionPrefix and avoid repeated work.
Let me know if it looks good. I'll merge this as is in a day or two if there's no response.

@jhrcek jhrcek merged commit 1bbe780 into haskell:master Feb 10, 2024
39 checks passed
@jhrcek jhrcek deleted the jhrcek/fix-OPTIONS_GHC-autocomplete branch February 12, 2024 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants