aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/assists/introduce_variable.rs18
-rw-r--r--crates/ra_assists/src/doc_tests.rs7
-rw-r--r--crates/ra_assists/src/doc_tests/generated.rs18
-rw-r--r--crates/test_utils/src/lib.rs34
-rw-r--r--docs/user/assists.md17
5 files changed, 85 insertions, 9 deletions
diff --git a/crates/ra_assists/src/assists/introduce_variable.rs b/crates/ra_assists/src/assists/introduce_variable.rs
index 43378c4b0..8245dc99f 100644
--- a/crates/ra_assists/src/assists/introduce_variable.rs
+++ b/crates/ra_assists/src/assists/introduce_variable.rs
@@ -1,5 +1,3 @@
1//! FIXME: write short doc here
2
3use format_buf::format; 1use format_buf::format;
4use hir::db::HirDatabase; 2use hir::db::HirDatabase;
5use ra_syntax::{ 3use ra_syntax::{
@@ -14,6 +12,22 @@ use test_utils::tested_by;
14 12
15use crate::{Assist, AssistCtx, AssistId}; 13use crate::{Assist, AssistCtx, AssistId};
16 14
15// Assist: introduce_variable
16//
17// Extracts subexpression into a variable.
18//
19// ```
20// fn main() {
21// <|>(1 + 2)<|> * 4;
22// }
23// ```
24// ->
25// ```
26// fn main() {
27// let var_name = (1 + 2);
28// var_name * 4;
29// }
30// ```
17pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 31pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
18 if ctx.frange.range.is_empty() { 32 if ctx.frange.range.is_empty() {
19 return None; 33 return None;
diff --git a/crates/ra_assists/src/doc_tests.rs b/crates/ra_assists/src/doc_tests.rs
index 872bbdf17..0ccf9d730 100644
--- a/crates/ra_assists/src/doc_tests.rs
+++ b/crates/ra_assists/src/doc_tests.rs
@@ -7,13 +7,12 @@ mod generated;
7 7
8use hir::mock::MockDatabase; 8use hir::mock::MockDatabase;
9use ra_db::FileRange; 9use ra_db::FileRange;
10use ra_syntax::TextRange; 10use test_utils::{assert_eq_text, extract_range_or_offset};
11use test_utils::{assert_eq_text, extract_offset};
12 11
13fn check(assist_id: &str, before: &str, after: &str) { 12fn check(assist_id: &str, before: &str, after: &str) {
14 let (before_cursor_pos, before) = extract_offset(before); 13 let (selection, before) = extract_range_or_offset(before);
15 let (db, _source_root, file_id) = MockDatabase::with_single_file(&before); 14 let (db, _source_root, file_id) = MockDatabase::with_single_file(&before);
16 let frange = FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; 15 let frange = FileRange { file_id, range: selection.into() };
17 16
18 let (_assist_id, action) = crate::assists(&db, frange) 17 let (_assist_id, action) = crate::assists(&db, frange)
19 .into_iter() 18 .into_iter()
diff --git a/crates/ra_assists/src/doc_tests/generated.rs b/crates/ra_assists/src/doc_tests/generated.rs
index d390db33c..493bd94d0 100644
--- a/crates/ra_assists/src/doc_tests/generated.rs
+++ b/crates/ra_assists/src/doc_tests/generated.rs
@@ -255,3 +255,21 @@ fn main() {
255"#####, 255"#####,
256 ) 256 )
257} 257}
258
259#[test]
260fn doctest_introduce_variable() {
261 check(
262 "introduce_variable",
263 r#####"
264fn main() {
265 <|>(1 + 2)<|> * 4;
266}
267"#####,
268 r#####"
269fn main() {
270 let var_name = (1 + 2);
271 var_name * 4;
272}
273"#####,
274 )
275}
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index c40943b63..1244ea8cf 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -1,4 +1,10 @@
1//! FIXME: write short doc here 1//! Assorted testing utilities.
2//!
3//! Most notable things are:
4//!
5//! * Rich text comparison, which outputs a diff.
6//! * Extracting markup (mainly, `<|>` markers) out of fixture strings.
7//! * marks (see the eponymous module).
2 8
3#[macro_use] 9#[macro_use]
4pub mod marks; 10pub mod marks;
@@ -43,7 +49,7 @@ pub fn extract_offset(text: &str) -> (TextUnit, String) {
43 } 49 }
44} 50}
45 51
46pub fn try_extract_offset(text: &str) -> Option<(TextUnit, String)> { 52fn try_extract_offset(text: &str) -> Option<(TextUnit, String)> {
47 let cursor_pos = text.find(CURSOR_MARKER)?; 53 let cursor_pos = text.find(CURSOR_MARKER)?;
48 let mut new_text = String::with_capacity(text.len() - CURSOR_MARKER.len()); 54 let mut new_text = String::with_capacity(text.len() - CURSOR_MARKER.len());
49 new_text.push_str(&text[..cursor_pos]); 55 new_text.push_str(&text[..cursor_pos]);
@@ -59,12 +65,34 @@ pub fn extract_range(text: &str) -> (TextRange, String) {
59 } 65 }
60} 66}
61 67
62pub fn try_extract_range(text: &str) -> Option<(TextRange, String)> { 68fn try_extract_range(text: &str) -> Option<(TextRange, String)> {
63 let (start, text) = try_extract_offset(text)?; 69 let (start, text) = try_extract_offset(text)?;
64 let (end, text) = try_extract_offset(&text)?; 70 let (end, text) = try_extract_offset(&text)?;
65 Some((TextRange::from_to(start, end), text)) 71 Some((TextRange::from_to(start, end), text))
66} 72}
67 73
74pub enum RangeOrOffset {
75 Range(TextRange),
76 Offset(TextUnit),
77}
78
79impl From<RangeOrOffset> for TextRange {
80 fn from(selection: RangeOrOffset) -> Self {
81 match selection {
82 RangeOrOffset::Range(it) => it,
83 RangeOrOffset::Offset(it) => TextRange::from_to(it, it),
84 }
85 }
86}
87
88pub fn extract_range_or_offset(text: &str) -> (RangeOrOffset, String) {
89 if let Some((range, text)) = try_extract_range(text) {
90 return (RangeOrOffset::Range(range), text);
91 }
92 let (offset, text) = extract_offset(text);
93 (RangeOrOffset::Offset(offset), text)
94}
95
68/// Extracts ranges, marked with `<tag> </tag>` paris from the `text` 96/// Extracts ranges, marked with `<tag> </tag>` paris from the `text`
69pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) { 97pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) {
70 let open = format!("<{}>", tag); 98 let open = format!("<{}>", tag);
diff --git a/docs/user/assists.md b/docs/user/assists.md
index 8e2e8cc94..182f07e98 100644
--- a/docs/user/assists.md
+++ b/docs/user/assists.md
@@ -245,3 +245,20 @@ fn main() {
245 (1 + 2) * 4; 245 (1 + 2) * 4;
246} 246}
247``` 247```
248
249## `introduce_variable`
250
251Extracts subexpression into a variable.
252
253```rust
254// BEFORE
255fn main() {
256 <|>(1 + 2)<|> * 4;
257}
258
259// AFTER
260fn main() {
261 let var_name = (1 + 2);
262 var_name * 4;
263}
264```