@@ -71,19 +71,41 @@ pub struct HoverResult {
71
71
pub actions : Vec < HoverAction > ,
72
72
}
73
73
74
- /// Feature: Hover
75
- ///
76
- /// Shows additional information, like the type of an expression or the documentation for a definition when "focusing" code.
77
- /// Focusing is usually hovering with a mouse, but can also be triggered with a shortcut.
78
- ///
79
- /// image::https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif
74
+ // Feature: Hover
75
+ //
76
+ // Shows additional information, like the type of an expression or the documentation for a definition when "focusing" code.
77
+ // Focusing is usually hovering with a mouse, but can also be triggered with a shortcut.
78
+ //
79
+ // image::https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif
80
80
pub ( crate ) fn hover (
81
81
db : & RootDatabase ,
82
- position : FilePosition ,
82
+ range : FileRange ,
83
83
config : & HoverConfig ,
84
84
) -> Option < RangeInfo < HoverResult > > {
85
85
let sema = hir:: Semantics :: new ( db) ;
86
- let file = sema. parse ( position. file_id ) . syntax ( ) . clone ( ) ;
86
+ let file = sema. parse ( range. file_id ) . syntax ( ) . clone ( ) ;
87
+
88
+ // This means we're hovering over a range.
89
+ if !range. range . is_empty ( ) {
90
+ let expr = find_node_at_range :: < ast:: Expr > ( & file, range. range ) ?;
91
+ let ty = sema. type_of_expr ( & expr) ?;
92
+
93
+ if ty. is_unknown ( ) {
94
+ return None ;
95
+ }
96
+
97
+ let mut res = HoverResult :: default ( ) ;
98
+
99
+ res. markup = if config. markdown ( ) {
100
+ Markup :: fenced_block ( & ty. display ( db) )
101
+ } else {
102
+ ty. display ( db) . to_string ( ) . into ( )
103
+ } ;
104
+
105
+ return Some ( RangeInfo :: new ( range. range , res) ) ;
106
+ }
107
+
108
+ let position = FilePosition { file_id : range. file_id , offset : range. range . start ( ) } ;
87
109
let token = pick_best_token ( file. token_at_offset ( position. offset ) , |kind| match kind {
88
110
IDENT | INT_NUMBER | LIFETIME_IDENT | T ! [ self ] | T ! [ super ] | T ! [ crate ] => 3 ,
89
111
T ! [ '(' ] | T ! [ ')' ] => 2 ,
@@ -197,6 +219,7 @@ pub(crate) fn hover(
197
219
} else {
198
220
ty. display ( db) . to_string ( ) . into ( )
199
221
} ;
222
+
200
223
let range = sema. original_range ( & node) . range ;
201
224
Some ( RangeInfo :: new ( range, res) )
202
225
}
@@ -245,37 +268,6 @@ fn try_hover_for_lint(attr: &ast::Attr, token: &SyntaxToken) -> Option<RangeInfo
245
268
) )
246
269
}
247
270
248
- /// LSP Extension: Hover over a range
249
- ///
250
- /// Gets the type of the expression closest to the selection if the user is hovering inside
251
- /// the selection. If not, it is handled by `handle_hover`.
252
- ///
253
- /// https://user-images.githubusercontent.com/22298999/126914293-0ce49a92-545d-4005-a59e-9294fa2330d6.gif
254
- pub ( crate ) fn hover_range (
255
- db : & RootDatabase ,
256
- range : FileRange ,
257
- config : & HoverConfig ,
258
- ) -> Option < RangeInfo < HoverResult > > {
259
- let sema = hir:: Semantics :: new ( db) ;
260
- let file = sema. parse ( range. file_id ) . syntax ( ) . clone ( ) ;
261
- let expr = find_node_at_range :: < ast:: Expr > ( & file, range. range ) ?;
262
- let ty = sema. type_of_expr ( & expr) ?;
263
-
264
- if ty. is_unknown ( ) {
265
- return None ;
266
- }
267
-
268
- let mut res = HoverResult :: default ( ) ;
269
-
270
- res. markup = if config. markdown ( ) {
271
- Markup :: fenced_block ( & ty. display ( db) )
272
- } else {
273
- ty. display ( db) . to_string ( ) . into ( )
274
- } ;
275
-
276
- Some ( RangeInfo :: new ( range. range , res) )
277
- }
278
-
279
271
fn show_implementations_action ( db : & RootDatabase , def : Definition ) -> Option < HoverAction > {
280
272
fn to_action ( nav_target : NavigationTarget ) -> HoverAction {
281
273
HoverAction :: Implementation ( FilePosition {
@@ -565,7 +557,8 @@ fn find_std_module(famous_defs: &FamousDefs, name: &str) -> Option<hir::Module>
565
557
#[ cfg( test) ]
566
558
mod tests {
567
559
use expect_test:: { expect, Expect } ;
568
- use ide_db:: base_db:: FileLoader ;
560
+ use ide_db:: base_db:: { FileLoader , FileRange } ;
561
+ use syntax:: TextRange ;
569
562
570
563
use crate :: { fixture, hover:: HoverDocFormat , HoverConfig } ;
571
564
@@ -577,7 +570,7 @@ mod tests {
577
570
links_in_hover : true ,
578
571
documentation : Some ( HoverDocFormat :: Markdown ) ,
579
572
} ,
580
- position,
573
+ FileRange { file_id : position. file_id , range : TextRange :: empty ( position . offset ) } ,
581
574
)
582
575
. unwrap ( ) ;
583
576
assert ! ( hover. is_none( ) ) ;
@@ -591,7 +584,7 @@ mod tests {
591
584
links_in_hover : true ,
592
585
documentation : Some ( HoverDocFormat :: Markdown ) ,
593
586
} ,
594
- position,
587
+ FileRange { file_id : position. file_id , range : TextRange :: empty ( position . offset ) } ,
595
588
)
596
589
. unwrap ( )
597
590
. unwrap ( ) ;
@@ -611,7 +604,7 @@ mod tests {
611
604
links_in_hover : false ,
612
605
documentation : Some ( HoverDocFormat :: Markdown ) ,
613
606
} ,
614
- position,
607
+ FileRange { file_id : position. file_id , range : TextRange :: empty ( position . offset ) } ,
615
608
)
616
609
. unwrap ( )
617
610
. unwrap ( ) ;
@@ -631,7 +624,7 @@ mod tests {
631
624
links_in_hover : true ,
632
625
documentation : Some ( HoverDocFormat :: PlainText ) ,
633
626
} ,
634
- position,
627
+ FileRange { file_id : position. file_id , range : TextRange :: empty ( position . offset ) } ,
635
628
)
636
629
. unwrap ( )
637
630
. unwrap ( ) ;
@@ -651,7 +644,7 @@ mod tests {
651
644
links_in_hover : true ,
652
645
documentation : Some ( HoverDocFormat :: Markdown ) ,
653
646
} ,
654
- position,
647
+ FileRange { file_id : position. file_id , range : TextRange :: empty ( position . offset ) } ,
655
648
)
656
649
. unwrap ( )
657
650
. unwrap ( ) ;
@@ -661,7 +654,7 @@ mod tests {
661
654
fn check_hover_range ( ra_fixture : & str , expect : Expect ) {
662
655
let ( analysis, range) = fixture:: range ( ra_fixture) ;
663
656
let hover = analysis
664
- . hover_range (
657
+ . hover (
665
658
& HoverConfig {
666
659
links_in_hover : false ,
667
660
documentation : Some ( HoverDocFormat :: Markdown ) ,
@@ -676,7 +669,7 @@ mod tests {
676
669
fn check_hover_range_no_results ( ra_fixture : & str ) {
677
670
let ( analysis, range) = fixture:: range ( ra_fixture) ;
678
671
let hover = analysis
679
- . hover_range (
672
+ . hover (
680
673
& HoverConfig {
681
674
links_in_hover : false ,
682
675
documentation : Some ( HoverDocFormat :: Markdown ) ,
0 commit comments