diff options
| author | Aleksey Kladov <aleksey.kladov@gmail.com> | 2020-07-17 11:20:28 +0200 |
|---|---|---|
| committer | Aleksey Kladov <aleksey.kladov@gmail.com> | 2020-07-17 11:20:28 +0200 |
| commit | 2729665235d941e83876a3799defe76326a5b807 (patch) | |
| tree | 558a5016a73d424e7b4409a8804a4fea1cdd0fec | |
| parent | 7e932f33391bd78a43a06d275a4d2f93fe3d7e8d (diff) | |
| download | rust-2729665235d941e83876a3799defe76326a5b807.tar.gz rust-2729665235d941e83876a3799defe76326a5b807.zip | |
Continue non-doc comments with trailing space
| -rw-r--r-- | crates/ra_ide/src/typing.rs | 1 | ||||
| -rw-r--r-- | crates/ra_ide/src/typing/on_enter.rs | 67 |
2 files changed, 59 insertions, 9 deletions
diff --git a/crates/ra_ide/src/typing.rs b/crates/ra_ide/src/typing.rs index 83776d2b6d3..d3ce744b44c 100644 --- a/crates/ra_ide/src/typing.rs +++ b/crates/ra_ide/src/typing.rs @@ -39,7 +39,6 @@ pub(crate) const TRIGGER_CHARS: &str = ".=>"; // Some features trigger on typing certain characters: // // - typing `let =` tries to smartly add `;` if `=` is followed by an existing expression -// - Enter inside comments automatically inserts `///` // - typing `.` in a chain method call auto-indents pub(crate) fn on_char_typed( db: &RootDatabase, diff --git a/crates/ra_ide/src/typing/on_enter.rs b/crates/ra_ide/src/typing/on_enter.rs index 2faaa8ff071..143b1ae413e 100644 --- a/crates/ra_ide/src/typing/on_enter.rs +++ b/crates/ra_ide/src/typing/on_enter.rs @@ -7,10 +7,31 @@ use ra_syntax::{ ast::{self, AstToken}, AstNode, SmolStr, SourceFile, SyntaxKind::*, - SyntaxToken, TextSize, TokenAtOffset, + SyntaxToken, TextRange, TextSize, TokenAtOffset, }; use ra_text_edit::TextEdit; +use test_utils::mark; +// Feature: On Enter +// +// rust-analyzer can override kbd:[Enter] key to make it smarter: +// +// - kbd:[Enter] inside triple-slash comments automatically inserts `///` +// - kbd:[Enter] in the middle or after a trailing space in `//` inserts `//` +// +// This action needs to be assigned to shortcut explicitly. +// +// VS Code:: +// +// Add the following to `keybindings.json`: +// [source,json] +// ---- +// { +// "key": "Enter", +// "command": "rust-analyzer.onEnter", +// "when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust" +// } +// ---- pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<TextEdit> { let parse = db.parse(position.file_id); let file = parse.tree(); @@ -30,15 +51,25 @@ pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<Text return None; } + let mut remove_last_space = false; // Continuing single-line non-doc comments (like this one :) ) is annoying - if prefix == "//" && comment_range.end() == position.offset && !followed_by_comment(&comment) { - return None; + if prefix == "//" && comment_range.end() == position.offset { + if comment.text().ends_with(' ') { + mark::hit!(continues_end_of_line_comment_with_space); + remove_last_space = true; + } else if !followed_by_comment(&comment) { + return None; + } } let indent = node_indent(&file, comment.syntax())?; let inserted = format!("\n{}{} $0", indent, prefix); - let edit = TextEdit::insert(position.offset, inserted); - + let delete = if remove_last_space { + TextRange::new(position.offset - TextSize::of(' '), position.offset) + } else { + TextRange::empty(position.offset) + }; + let edit = TextEdit::replace(delete, inserted); Some(edit) } @@ -75,10 +106,10 @@ fn node_indent(file: &SourceFile, token: &SyntaxToken) -> Option<SmolStr> { #[cfg(test)] mod tests { - use test_utils::assert_eq_text; + use stdx::trim_indent; + use test_utils::{assert_eq_text, mark}; use crate::mock_analysis::analysis_and_position; - use stdx::trim_indent; fn apply_on_enter(before: &str) -> Option<String> { let (analysis, position) = analysis_and_position(&before); @@ -192,7 +223,7 @@ fn main() { } #[test] - fn does_not_continue_end_of_code_comment() { + fn does_not_continue_end_of_line_comment() { do_check_noop( r" fn main() { @@ -202,4 +233,24 @@ fn main() { ", ); } + + #[test] + fn continues_end_of_line_comment_with_space() { + mark::check!(continues_end_of_line_comment_with_space); + do_check( + r#" +fn main() { + // Fix me <|> + let x = 1 + 1; +} +"#, + r#" +fn main() { + // Fix me + // $0 + let x = 1 + 1; +} +"#, + ); + } } |
