@@ -3,12 +3,38 @@ use ide_db::{
3
3
base_db:: AnchoredPathBuf ,
4
4
} ;
5
5
use syntax:: {
6
- ast:: { self } ,
7
- AstNode , TextRange ,
6
+ ast:: { self , Whitespace } ,
7
+ AstNode , AstToken , SourceFile , TextRange , TextSize ,
8
8
} ;
9
9
10
10
use crate :: assist_context:: { AssistContext , Assists } ;
11
11
12
+ /// Trim(remove leading and trailing whitespace) `initial_range` in `source_file`, return the trimmed range.
13
+ fn trimmed_text_range ( source_file : & SourceFile , initial_range : TextRange ) -> TextRange {
14
+ let mut trimmed_range = initial_range;
15
+ while source_file
16
+ . syntax ( )
17
+ . token_at_offset ( trimmed_range. start ( ) )
18
+ . find_map ( Whitespace :: cast)
19
+ . is_some ( )
20
+ && trimmed_range. start ( ) < trimmed_range. end ( )
21
+ {
22
+ let start = trimmed_range. start ( ) + TextSize :: from ( 1 ) ;
23
+ trimmed_range = TextRange :: new ( start, trimmed_range. end ( ) ) ;
24
+ }
25
+ while source_file
26
+ . syntax ( )
27
+ . token_at_offset ( trimmed_range. end ( ) )
28
+ . find_map ( Whitespace :: cast)
29
+ . is_some ( )
30
+ && trimmed_range. start ( ) < trimmed_range. end ( )
31
+ {
32
+ let end = trimmed_range. end ( ) - TextSize :: from ( 1 ) ;
33
+ trimmed_range = TextRange :: new ( trimmed_range. start ( ) , end) ;
34
+ }
35
+ trimmed_range
36
+ }
37
+
12
38
// Assist: promote_mod_file
13
39
//
14
40
// Moves inline module's contents to a separate file.
@@ -17,7 +43,7 @@ use crate::assist_context::{AssistContext, Assists};
17
43
// //- /main.rs
18
44
// mod a;
19
45
// //- /a.rs
20
- // $0fn t() {}
46
+ // $0fn t() {}$0
21
47
// ```
22
48
// ->
23
49
// ```
@@ -26,18 +52,23 @@ use crate::assist_context::{AssistContext, Assists};
26
52
pub ( crate ) fn promote_mod_file ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
27
53
let source_file = ctx. find_node_at_offset :: < ast:: SourceFile > ( ) ?;
28
54
let module = ctx. sema . to_module_def ( ctx. frange . file_id ) ?;
29
- if module. is_mod_rs ( ctx. db ( ) ) {
55
+ // Enable this assist if the user select all "meaningful" content in the source file
56
+ let trimmed_selected_range = trimmed_text_range ( & source_file, ctx. frange . range ) ;
57
+ let trimmed_file_range = trimmed_text_range ( & source_file, source_file. syntax ( ) . text_range ( ) ) ;
58
+ if module. is_mod_rs ( ctx. db ( ) ) || trimmed_selected_range != trimmed_file_range {
30
59
return None ;
31
60
}
61
+
32
62
let target = TextRange :: new (
33
63
source_file. syntax ( ) . text_range ( ) . start ( ) ,
34
64
source_file. syntax ( ) . text_range ( ) . end ( ) ,
35
65
) ;
36
- let path = format ! ( "./{}/mod.rs" , module. name( ctx. db( ) ) ?. to_string( ) ) ;
66
+ let module_name = module. name ( ctx. db ( ) ) ?. to_string ( ) ;
67
+ let path = format ! ( "./{}/mod.rs" , module_name) ;
37
68
let dst = AnchoredPathBuf { anchor : ctx. frange . file_id , path } ;
38
69
acc. add (
39
70
AssistId ( "promote_mod_file" , AssistKind :: Refactor ) ,
40
- "Promote Module to directory" ,
71
+ format ! ( "Turn {}.rs to {}/mod.rs" , module_name , module_name ) ,
41
72
target,
42
73
|builder| {
43
74
builder. move_file ( ctx. frange . file_id , dst) ;
@@ -60,7 +91,7 @@ mod tests {
60
91
mod a;
61
92
//- /a.rs
62
93
$0fn t() {}
63
- "# ,
94
+ $0 "#,
64
95
r#"
65
96
//- /a/mod.rs
66
97
fn t() {}
@@ -69,44 +100,23 @@ fn t() {}
69
100
}
70
101
71
102
#[ test]
72
- fn cursor_can_be_putted_anywhere ( ) {
73
- check_assist (
103
+ fn must_select_all_file ( ) {
104
+ check_assist_not_applicable (
74
105
promote_mod_file,
75
106
r#"
76
107
//- /main.rs
77
108
mod a;
78
109
//- /a.rs
79
110
fn t() {}$0
80
- "# ,
81
- r#"
82
- //- /a/mod.rs
83
- fn t() {}
84
111
"# ,
85
112
) ;
86
- check_assist (
87
- promote_mod_file,
88
- r#"
89
- //- /main.rs
90
- mod a;
91
- //- /a.rs
92
- fn t()$0 {}
93
- "# ,
94
- r#"
95
- //- /a/mod.rs
96
- fn t() {}
97
- "# ,
98
- ) ;
99
- check_assist (
113
+ check_assist_not_applicable (
100
114
promote_mod_file,
101
115
r#"
102
116
//- /main.rs
103
117
mod a;
104
118
//- /a.rs
105
- fn t($0) {}
106
- "# ,
107
- r#"
108
- //- /a/mod.rs
109
- fn t() {}
119
+ $0fn$0 t() {}
110
120
"# ,
111
121
) ;
112
122
}
@@ -147,8 +157,8 @@ $0fn t() {}
147
157
r#"//- /main.rs
148
158
mod a;
149
159
//- /a.rs
150
- mod b;
151
- $0fn t() {}
160
+ $0mod b;
161
+ fn t() {}$0
152
162
//- /a/b.rs
153
163
fn t1() {}
154
164
"# ,
0 commit comments