Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Implement signature help#4626

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
jian-lin wants to merge5 commits intohaskell:master
base:master
Choose a base branch
Loading
fromlinj-fork:pr/signature-help

Conversation

jian-lin
Copy link
Contributor

@jian-linjian-lin commentedJun 8, 2025
edited
Loading

Closes#3598

I will update progress here.

2025-06-02 - 2025-06-08

  • Add basic boilerplate for signature help plugin

2025-06-09 - 2025-07-13

  • Finish signature help plugin MVP: show function signature and highlight the current parameter
    • commit:9168b74

    • click for video demo
      Screencast.From.2025-07-13.02-11-44.webm

2025-07-14 - 2025-07-20

  • Add basic tests. Some of them are not passed for now.

@@ -764,6 +770,10 @@ instance PluginRequestMethod Method_TextDocumentDocumentSymbol where
si = SymbolInformation name' (ds ^. L.kind) Nothing parent (ds ^. L.deprecated) loc
in [si] <> children'

-- TODO(@linj) is this correct?
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is reasonable. ReallycombineResponses should have a way to return an error. There are a bunch of methods where it really only makes sense if we have one handler.

Wecould try to combine responses: we would combine the signatures, and so long as only one of them indicated an active signature it would be okay. But that's a bit sketchy and I doubt we'll have several anyway!

jian-lin reacted with thumbs up emoji
TODO:- handle more cases- add successful and (currently failed) tests- show documentation
Copy link
Collaborator

@michaelpjmichaelpj left a comment

Choose a reason for hiding this comment

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

I think really worth trying to start getting some tests in place!

jian-lin reacted with thumbs up emoji
case fromCurrentPosition positionMapping position of
Nothing -> pure Nothing
Just oldPosition -> do
let functionName =
Copy link
Collaborator

Choose a reason for hiding this comment

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

you probably want to do all these in one go, this looks like it will traverse the AST three times! I think you can just do one call toextractInfoFromSmallestContainingFunctionApplicationAst and get all the pieces together though?

if nodeHasAnnotation ("HsVar", "HsExpr") hieAst
then
case M.elems $ M.filter isUse $ getSourceNodeIds hieAst of
[identifierDetails] -> identType identifierDetails >>= (prettyType >>> Just)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suggest not printing the type here and instead returning the type itself. That would mean that when you're doingmkArguments you can pattern match on the type itself, not on the string representation. Then you don't need to worry about e.g. whether it prints on multiple lines or whatever.

(Just $ InL argumentNumber)

-- TODO(@linj) can type string be a multi-line string?
mkArguments :: UInt -> Text -> [ParameterInformation]
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this would be a lot simpler if you were just looking at the type itself!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Although hmm, the offsets are into the string 😱 So maybe you would need to incrementally build up theParameterInformations and the overalllabel, but that would probably still be nicer?

type Annotation = (FastStringCompat, FastStringCompat)

nodeHasAnnotation :: Annotation -> HieAST a -> Bool
nodeHasAnnotation annotation = sourceNodeInfo >>> maybe False (isAnnotationInNodeInfo annotation)
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: I think it tends to be easier to read a simple case expression than one of the pattern-matching functions likemaybe. I usually only usemaybe if it's partially-applied.

You can still avoid naming theHieAst parameter if you want usingLambdaCase.

nodeHasAnnotation :: Annotation -> HieAST a -> Bool
nodeHasAnnotation annotation = sourceNodeInfo >>> maybe False (isAnnotationInNodeInfo annotation)

-- TODO(@linj): the left most node may not be the function node. example: (if True then f else g) x
Copy link
Collaborator

Choose a reason for hiding this comment

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

write a test!

Copy link
Collaborator

Choose a reason for hiding this comment

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

this is a great example btw. In this case I think we would have to give no signature help, I think, since it's only dynamically known which function we're getting.

if nodeHasAnnotation ("HsVar", "HsExpr") hieAst
then
case mapMaybe extractName $ M.keys $ M.filter isUse $ getSourceNodeIds hieAst of
[name] -> Just name -- TODO(@linj) will there be more than one name?
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not 100% sure when/if this can happen. I think it might happen if we're looking at a typeclass method, in which case we could get the generic typeclass method and the specific one perhaps? That would be a good use-case for multilple signatures, e.g. if we have

foldMap @[] f ^

then we might want to see both the genericFoldable signature and the one for the list instance.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think my general suggestion would be: let's treat possibly-multiple node annotations as producing possibly-multiple signatures.

(Just $ InL argumentNumber)
]
(Just 0)
(Just $ InL argumentNumber)
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we know if this is 0 or 1-indexed? specification doesn't say (of course 🙄 ) so I guess we'll have to test it in vscode to see

jian-lin and fendor reacted with laugh emoji
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@michaelpjmichaelpjmichaelpj left review comments

@fendorfendorAwaiting requested review from fendorfendor will be requested when the pull request is marked ready for reviewfendor is a code owner

At least 1 approving review is required to merge this pull request.

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

Show function signature while providing the arguments
2 participants
@jian-lin@michaelpj

[8]ページ先頭

©2009-2025 Movatter.jp