From c14ca038dac7085da7a4111347c4da49556d6e7e Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Sun, 16 Dec 2018 18:17:33 +0900 Subject: [PATCH] Add make_pub_crate code action to ra_editor --- crates/ra_editor/src/code_actions.rs | 74 +++++++++++++++++++++++++++- crates/ra_editor/src/lib.rs | 2 +- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/crates/ra_editor/src/code_actions.rs b/crates/ra_editor/src/code_actions.rs index 688a89c3dc4..1d78cb7e81e 100644 --- a/crates/ra_editor/src/code_actions.rs +++ b/crates/ra_editor/src/code_actions.rs @@ -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 { } } +pub fn make_pub_crate<'a>( + file: &'a SourceFileNode, + offset: TextUnit, +) -> Option 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 { 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()), + ); + } } diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs index 36cabed2590..7b63b9a88db 100644 --- a/crates/ra_editor/src/lib.rs +++ b/crates/ra_editor/src/lib.rs @@ -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},