]> git.lizzy.rs Git - rust.git/commitdiff
Add make_pub_crate code action to ra_editor
authorHirokazu Hata <h.hata.ai.t@gmail.com>
Sun, 16 Dec 2018 09:17:33 +0000 (18:17 +0900)
committerHirokazu Hata <h.hata.ai.t@gmail.com>
Mon, 24 Dec 2018 02:03:59 +0000 (11:03 +0900)
crates/ra_editor/src/code_actions.rs
crates/ra_editor/src/lib.rs

index 688a89c3dc497d76a09c7f8a156688b9fda9f5a3..1d78cb7e81e49bbcd7a67fc92c933523e44b14e4 100644 (file)
@@ -4,7 +4,7 @@
     algo::{find_covering_node, find_leaf_at_offset},
     ast::{self, AstNode, AttrsOwner, NameOwner, TypeParamsOwner},
     Direction, SourceFileNode,
-    SyntaxKind::{COMMA, WHITESPACE, COMMENT},
+    SyntaxKind::{COMMA, WHITESPACE, COMMENT, VISIBILITY, FN_KW, MOD_KW, STRUCT_KW, ENUM_KW, TRAIT_KW, FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF},
     SyntaxNodeRef, TextRange, TextUnit,
 };
 
@@ -174,6 +174,39 @@ fn anchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> {
     }
 }
 
+pub fn make_pub_crate<'a>(
+    file: &'a SourceFileNode,
+    offset: TextUnit,
+) -> Option<impl FnOnce() -> LocalEdit + 'a> {
+    let syntax = file.syntax();
+
+    let keyword = find_leaf_at_offset(syntax, offset).find(|leaf| match leaf.kind() {
+        FN_KW | MOD_KW | STRUCT_KW | ENUM_KW | TRAIT_KW => true,
+        _ => false,
+    })?;
+    let parent = keyword.parent()?;
+    let def_kws = vec![FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF];
+    let node_start = parent.range().start();
+    Some(move || {
+        let mut edit = TextEditBuilder::new();
+
+        if !def_kws.iter().any(|&def_kw| def_kw == parent.kind())
+            || parent.children().any(|child| child.kind() == VISIBILITY)
+        {
+            return LocalEdit {
+                edit: edit.finish(),
+                cursor_position: Some(offset),
+            };
+        }
+
+        edit.insert(node_start, "pub(crate) ".to_string());
+        LocalEdit {
+            edit: edit.finish(),
+            cursor_position: Some(node_start),
+        }
+    })
+}
+
 fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> {
     node.siblings(direction)
         .skip(1)
@@ -333,4 +366,43 @@ fn foo() {
         );
     }
 
+    #[test]
+    fn test_make_pub_crate() {
+        check_action(
+            "<|>fn foo() {}",
+            "<|>pub(crate) fn foo() {}",
+            |file, off| make_pub_crate(file, off).map(|f| f()),
+        );
+        check_action(
+            "f<|>n foo() {}",
+            "<|>pub(crate) fn foo() {}",
+            |file, off| make_pub_crate(file, off).map(|f| f()),
+        );
+        check_action(
+            "<|>struct Foo {}",
+            "<|>pub(crate) struct Foo {}",
+            |file, off| make_pub_crate(file, off).map(|f| f()),
+        );
+        check_action("<|>mod foo {}", "<|>pub(crate) mod foo {}", |file, off| {
+            make_pub_crate(file, off).map(|f| f())
+        });
+        check_action(
+            "<|>trait Foo {}",
+            "<|>pub(crate) trait Foo {}",
+            |file, off| make_pub_crate(file, off).map(|f| f()),
+        );
+        check_action("m<|>od {}", "<|>pub(crate) mod {}", |file, off| {
+            make_pub_crate(file, off).map(|f| f())
+        });
+        check_action(
+            "pub(crate) f<|>n foo() {}",
+            "pub(crate) f<|>n foo() {}",
+            |file, off| make_pub_crate(file, off).map(|f| f()),
+        );
+        check_action(
+            "unsafe f<|>n foo() {}",
+            "<|>pub(crate) unsafe fn foo() {}",
+            |file, off| make_pub_crate(file, off).map(|f| f()),
+        );
+    }
 }
index 36cabed25906df1cd45d95963e80fb0309153374..7b63b9a88db1a0a4cde4734cec61e52120d25848 100644 (file)
@@ -8,7 +8,7 @@
 mod typing;
 
 pub use self::{
-    code_actions::{add_derive, add_impl, flip_comma, introduce_variable, LocalEdit},
+    code_actions::{add_derive, add_impl, flip_comma, introduce_variable, make_pub_crate, LocalEdit},
     extend_selection::extend_selection,
     folding_ranges::{folding_ranges, Fold, FoldKind},
     line_index::{LineCol, LineIndex},