-
-
Notifications
You must be signed in to change notification settings - Fork 407
Add "Go to type" hyperlinks in the hover popup (like Rust has) #4691
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
base: master
Are you sure you want to change the base?
Conversation
Hi @dschrempf
I need to check if the order they come in is deterministic when we query the locations.
Yes, I just copied the Rust one.
Yeah. For some reason the locations query does not return anything when you're on the type level. This is how |
Ad "Go to type ... not showing for symbols on the type level": Actually, it makes sense, but only somewhat. When the cursor is on
However, when the cursor is on
|
Exactly - the definitions in the hover use the same functionality underneath. I don't know if this is a bug or intended behavior. Maybe @fendor knows? |
I don't know exactly, I presume it is an artefact of HIE file structure or how GHC defines the AST and its source locations. So, probably a "bug". I don't think it is something worth investing too much time into right now (i.e., not for this PR in particular), and we should rather focus on the presentation in the hover. |
Not sure why this pipeline fails. Running |
@dnikolovv The testsuite in HLS is unfortunately quite flaky. You can likely ignore the testcase, and wait for an admin to restart the job. If the failing test case cannot be reproduced locally, then you can ignore it for now. |
pTypes :: [T.Text] | ||
pTypes | ||
| Prelude.length names == 1 = dropEnd1 $ map wrapHaskell prettyTypes | ||
| otherwise = map wrapHaskell prettyTypes | ||
pTypes :: M.Map Name Location -> [T.Text] | ||
pTypes locationsMap = | ||
case names of | ||
[_singleName] -> dropEnd1 $ prettyTypes Nothing locationsMap | ||
_ -> prettyTypes Nothing locationsMap |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a bit offtopic:
- Why do we
dropEnd1
whenlength names == 1
? - Why don't we
dropEnd1
whenlength names /= 1
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm tempted to remove this (actually I did but then reverted it) because it seems weird and unneeded to me as well. I tested a build without it and it seemed fine.
However, this is 4 year old code introduced by 2fef041 so I can't really comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My guess for the motivation behind dropEnd1
is that the author wants to avoid showing the same type/signature in pTypes
as the one shown in prettyName. If that is the case, I think we should also do dropEnd1
when length names /= 1
(for example, names
has 1 "actual" name and an evidence name), at least in today's GHC versions.
I also need to deal with this duplication when implementing signature help. I decide to filter out the same type instead of dropEnd1
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why just change it to use intelecate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jian-lin your explanation is correct. If we have the expression x
where x :: Int
, then in the hover, we would get both the lines x :: Int
for the variable at this point and _ :: Int
for the entire expression. The point of the code is to remove the duplication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @wz1000. However, my main question is that we should always (not just when length names == 1
) filter out the same type. For example, the current hover info for ==
in x = (==) True
contains duplicated type forall a. Eq a => a -> a -> Bool
.
== :: forall a. Eq a => a -> a -> Bool
Defined in ‘GHC.Classes’ (ghc-prim-0.11.0)
Documentation
Source
* * *
Evidence of constraint Eq Bool
using an external instance
Defined in ‘GHC.Classes’
* * *
_ :: Bool -> Bool -> Bool
* * *
_ :: forall a. Eq a => a -> a -> Bool
* * *
infix 4 ==
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for implementing this nice feature!
Could we add a testcase? Otherwise, this looks good to me and we can merge after a test has been added :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more review
module Development.IDE.Core.LookupMod (lookupMod, LookupModule) where | ||
|
||
import Control.Monad.Trans.Maybe (MaybeT (MaybeT)) | ||
import Development.IDE.Core.Shake (HieDbWriter, IdeAction) | ||
import Development.IDE.GHC.Compat.Core (ModuleName, Unit) | ||
import Development.IDE.Types.Location (Uri) | ||
|
||
-- | Gives a Uri for the module, given the .hie file location and the the module info | ||
-- The Bool denotes if it is a boot module | ||
type LookupModule m = FilePath -> ModuleName -> Unit -> Bool -> MaybeT m Uri | ||
|
||
-- | Eventually this will lookup/generate URIs for files in dependencies, but not in the | ||
-- project. Right now, this is just a stub. | ||
lookupMod :: | ||
-- | access the database | ||
HieDbWriter -> | ||
-- | The `.hie` file we got from the database | ||
FilePath -> | ||
ModuleName -> | ||
Unit -> | ||
-- | Is this file a boot file? | ||
Bool -> | ||
MaybeT IdeAction Uri | ||
lookupMod _dbchan _hie_f _mod _uid _boot = MaybeT $ pure Nothing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, removed.
That was a bit too hasty. This was old code that I had to move around to avoid circular references. It doesn't do anything functionally but maybe the author wants to go back to it at some point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion, and if it is dead code, it should go. We can revive it later if need be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to get back to it eventually, but I also think this is not needed as is and barely gives any advantage right now. So, let's just get rid of it, and then merge :)
6021b15
to
b1eab33
Compare
859c323
to
f21e011
Compare
Added tests. |
There was one concern that this might explode the Hover message if maaaanny types are involved. Do we perhaps want to impose a hard upper-limit on the number of elements we display, such as 10? What do you think about this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, modulo my last comment, thank you for taking care of this!
module Development.IDE.Core.LookupMod (lookupMod, LookupModule) where | ||
|
||
import Control.Monad.Trans.Maybe (MaybeT (MaybeT)) | ||
import Development.IDE.Core.Shake (HieDbWriter, IdeAction) | ||
import Development.IDE.GHC.Compat.Core (ModuleName, Unit) | ||
import Development.IDE.Types.Location (Uri) | ||
|
||
-- | Gives a Uri for the module, given the .hie file location and the the module info | ||
-- The Bool denotes if it is a boot module | ||
type LookupModule m = FilePath -> ModuleName -> Unit -> Bool -> MaybeT m Uri | ||
|
||
-- | Eventually this will lookup/generate URIs for files in dependencies, but not in the | ||
-- project. Right now, this is just a stub. | ||
lookupMod :: | ||
-- | access the database | ||
HieDbWriter -> | ||
-- | The `.hie` file we got from the database | ||
FilePath -> | ||
ModuleName -> | ||
Unit -> | ||
-- | Is this file a boot file? | ||
Bool -> | ||
MaybeT IdeAction Uri | ||
lookupMod _dbchan _hie_f _mod _uid _boot = MaybeT $ pure Nothing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to get back to it eventually, but I also think this is not needed as is and barely gives any advantage right now. So, let's just get rid of it, and then merge :)
This is how it looks in Rust: