diff options
Diffstat (limited to 'crates/ra_editor/src/assists/change_visibility.rs')
-rw-r--r-- | crates/ra_editor/src/assists/change_visibility.rs | 85 |
1 files changed, 32 insertions, 53 deletions
diff --git a/crates/ra_editor/src/assists/change_visibility.rs b/crates/ra_editor/src/assists/change_visibility.rs index 98c218f32..e2cd9ffd1 100644 --- a/crates/ra_editor/src/assists/change_visibility.rs +++ b/crates/ra_editor/src/assists/change_visibility.rs | |||
@@ -1,90 +1,69 @@ | |||
1 | use ra_text_edit::TextEditBuilder; | ||
2 | use ra_syntax::{ | 1 | use ra_syntax::{ |
3 | SourceFileNode, | ||
4 | algo::find_leaf_at_offset, | ||
5 | SyntaxKind::{VISIBILITY, FN_KW, MOD_KW, STRUCT_KW, ENUM_KW, TRAIT_KW, FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF}, | 2 | SyntaxKind::{VISIBILITY, FN_KW, MOD_KW, STRUCT_KW, ENUM_KW, TRAIT_KW, FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF}, |
6 | TextUnit, | ||
7 | }; | 3 | }; |
8 | 4 | ||
9 | use crate::assists::LocalEdit; | 5 | use crate::assists::{AssistCtx, Assist}; |
10 | 6 | ||
11 | pub fn change_visibility<'a>( | 7 | pub fn change_visibility(ctx: AssistCtx) -> Option<Assist> { |
12 | file: &'a SourceFileNode, | 8 | let keyword = ctx.leaf_at_offset().find(|leaf| match leaf.kind() { |
13 | offset: TextUnit, | ||
14 | ) -> Option<impl FnOnce() -> LocalEdit + 'a> { | ||
15 | let syntax = file.syntax(); | ||
16 | |||
17 | let keyword = find_leaf_at_offset(syntax, offset).find(|leaf| match leaf.kind() { | ||
18 | FN_KW | MOD_KW | STRUCT_KW | ENUM_KW | TRAIT_KW => true, | 9 | FN_KW | MOD_KW | STRUCT_KW | ENUM_KW | TRAIT_KW => true, |
19 | _ => false, | 10 | _ => false, |
20 | })?; | 11 | })?; |
21 | let parent = keyword.parent()?; | 12 | let parent = keyword.parent()?; |
22 | let def_kws = vec![FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF]; | 13 | let def_kws = vec![FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF]; |
23 | let node_start = parent.range().start(); | 14 | // Parent is not a definition, can't add visibility |
24 | Some(move || { | 15 | if !def_kws.iter().any(|&def_kw| def_kw == parent.kind()) { |
25 | let mut edit = TextEditBuilder::new(); | 16 | return None; |
26 | 17 | } | |
27 | if !def_kws.iter().any(|&def_kw| def_kw == parent.kind()) | 18 | // Already have visibility, do nothing |
28 | || parent.children().any(|child| child.kind() == VISIBILITY) | 19 | if parent.children().any(|child| child.kind() == VISIBILITY) { |
29 | { | 20 | return None; |
30 | return LocalEdit { | 21 | } |
31 | label: "make pub crate".to_string(), | ||
32 | edit: edit.finish(), | ||
33 | cursor_position: Some(offset), | ||
34 | }; | ||
35 | } | ||
36 | 22 | ||
37 | edit.insert(node_start, "pub(crate) ".to_string()); | 23 | let node_start = parent.range().start(); |
38 | LocalEdit { | 24 | ctx.build("make pub crate", |edit| { |
39 | label: "make pub crate".to_string(), | 25 | edit.insert(node_start, "pub(crate) "); |
40 | edit: edit.finish(), | 26 | edit.set_cursor(node_start); |
41 | cursor_position: Some(node_start), | ||
42 | } | ||
43 | }) | 27 | }) |
44 | } | 28 | } |
45 | 29 | ||
46 | #[cfg(test)] | 30 | #[cfg(test)] |
47 | mod tests { | 31 | mod tests { |
48 | use super::*; | 32 | use super::*; |
49 | use crate::test_utils::check_action; | 33 | use crate::assists::check_assist; |
50 | 34 | ||
51 | #[test] | 35 | #[test] |
52 | fn test_change_visibility() { | 36 | fn test_change_visibility() { |
53 | check_action( | 37 | check_assist( |
38 | change_visibility, | ||
54 | "<|>fn foo() {}", | 39 | "<|>fn foo() {}", |
55 | "<|>pub(crate) fn foo() {}", | 40 | "<|>pub(crate) fn foo() {}", |
56 | |file, off| change_visibility(file, off).map(|f| f()), | ||
57 | ); | 41 | ); |
58 | check_action( | 42 | check_assist( |
43 | change_visibility, | ||
59 | "f<|>n foo() {}", | 44 | "f<|>n foo() {}", |
60 | "<|>pub(crate) fn foo() {}", | 45 | "<|>pub(crate) fn foo() {}", |
61 | |file, off| change_visibility(file, off).map(|f| f()), | ||
62 | ); | 46 | ); |
63 | check_action( | 47 | check_assist( |
48 | change_visibility, | ||
64 | "<|>struct Foo {}", | 49 | "<|>struct Foo {}", |
65 | "<|>pub(crate) struct Foo {}", | 50 | "<|>pub(crate) struct Foo {}", |
66 | |file, off| change_visibility(file, off).map(|f| f()), | ||
67 | ); | 51 | ); |
68 | check_action("<|>mod foo {}", "<|>pub(crate) mod foo {}", |file, off| { | 52 | check_assist( |
69 | change_visibility(file, off).map(|f| f()) | 53 | change_visibility, |
70 | }); | 54 | "<|>mod foo {}", |
71 | check_action( | 55 | "<|>pub(crate) mod foo {}", |
56 | ); | ||
57 | check_assist( | ||
58 | change_visibility, | ||
72 | "<|>trait Foo {}", | 59 | "<|>trait Foo {}", |
73 | "<|>pub(crate) trait Foo {}", | 60 | "<|>pub(crate) trait Foo {}", |
74 | |file, off| change_visibility(file, off).map(|f| f()), | ||
75 | ); | ||
76 | check_action("m<|>od {}", "<|>pub(crate) mod {}", |file, off| { | ||
77 | change_visibility(file, off).map(|f| f()) | ||
78 | }); | ||
79 | check_action( | ||
80 | "pub(crate) f<|>n foo() {}", | ||
81 | "pub(crate) f<|>n foo() {}", | ||
82 | |file, off| change_visibility(file, off).map(|f| f()), | ||
83 | ); | 61 | ); |
84 | check_action( | 62 | check_assist(change_visibility, "m<|>od {}", "<|>pub(crate) mod {}"); |
63 | check_assist( | ||
64 | change_visibility, | ||
85 | "unsafe f<|>n foo() {}", | 65 | "unsafe f<|>n foo() {}", |
86 | "<|>pub(crate) unsafe fn foo() {}", | 66 | "<|>pub(crate) unsafe fn foo() {}", |
87 | |file, off| change_visibility(file, off).map(|f| f()), | ||
88 | ); | 67 | ); |
89 | } | 68 | } |
90 | } | 69 | } |