mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
support range selection in assist docs
This commit is contained in:
parent
733fd64260
commit
4a83aae098
5 changed files with 85 additions and 9 deletions
|
@ -1,5 +1,3 @@
|
|||
//! FIXME: write short doc here
|
||||
|
||||
use format_buf::format;
|
||||
use hir::db::HirDatabase;
|
||||
use ra_syntax::{
|
||||
|
@ -14,6 +12,22 @@ use test_utils::tested_by;
|
|||
|
||||
use crate::{Assist, AssistCtx, AssistId};
|
||||
|
||||
// Assist: introduce_variable
|
||||
//
|
||||
// Extracts subexpression into a variable.
|
||||
//
|
||||
// ```
|
||||
// fn main() {
|
||||
// <|>(1 + 2)<|> * 4;
|
||||
// }
|
||||
// ```
|
||||
// ->
|
||||
// ```
|
||||
// fn main() {
|
||||
// let var_name = (1 + 2);
|
||||
// var_name * 4;
|
||||
// }
|
||||
// ```
|
||||
pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
|
||||
if ctx.frange.range.is_empty() {
|
||||
return None;
|
||||
|
|
|
@ -7,13 +7,12 @@ mod generated;
|
|||
|
||||
use hir::mock::MockDatabase;
|
||||
use ra_db::FileRange;
|
||||
use ra_syntax::TextRange;
|
||||
use test_utils::{assert_eq_text, extract_offset};
|
||||
use test_utils::{assert_eq_text, extract_range_or_offset};
|
||||
|
||||
fn check(assist_id: &str, before: &str, after: &str) {
|
||||
let (before_cursor_pos, before) = extract_offset(before);
|
||||
let (selection, before) = extract_range_or_offset(before);
|
||||
let (db, _source_root, file_id) = MockDatabase::with_single_file(&before);
|
||||
let frange = FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) };
|
||||
let frange = FileRange { file_id, range: selection.into() };
|
||||
|
||||
let (_assist_id, action) = crate::assists(&db, frange)
|
||||
.into_iter()
|
||||
|
|
|
@ -255,3 +255,21 @@ fn main() {
|
|||
"#####,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doctest_introduce_variable() {
|
||||
check(
|
||||
"introduce_variable",
|
||||
r#####"
|
||||
fn main() {
|
||||
<|>(1 + 2)<|> * 4;
|
||||
}
|
||||
"#####,
|
||||
r#####"
|
||||
fn main() {
|
||||
let var_name = (1 + 2);
|
||||
var_name * 4;
|
||||
}
|
||||
"#####,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
//! FIXME: write short doc here
|
||||
//! Assorted testing utilities.
|
||||
//!
|
||||
//! Most notable things are:
|
||||
//!
|
||||
//! * Rich text comparison, which outputs a diff.
|
||||
//! * Extracting markup (mainly, `<|>` markers) out of fixture strings.
|
||||
//! * marks (see the eponymous module).
|
||||
|
||||
#[macro_use]
|
||||
pub mod marks;
|
||||
|
@ -43,7 +49,7 @@ pub fn extract_offset(text: &str) -> (TextUnit, String) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn try_extract_offset(text: &str) -> Option<(TextUnit, String)> {
|
||||
fn try_extract_offset(text: &str) -> Option<(TextUnit, String)> {
|
||||
let cursor_pos = text.find(CURSOR_MARKER)?;
|
||||
let mut new_text = String::with_capacity(text.len() - CURSOR_MARKER.len());
|
||||
new_text.push_str(&text[..cursor_pos]);
|
||||
|
@ -59,12 +65,34 @@ pub fn extract_range(text: &str) -> (TextRange, String) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn try_extract_range(text: &str) -> Option<(TextRange, String)> {
|
||||
fn try_extract_range(text: &str) -> Option<(TextRange, String)> {
|
||||
let (start, text) = try_extract_offset(text)?;
|
||||
let (end, text) = try_extract_offset(&text)?;
|
||||
Some((TextRange::from_to(start, end), text))
|
||||
}
|
||||
|
||||
pub enum RangeOrOffset {
|
||||
Range(TextRange),
|
||||
Offset(TextUnit),
|
||||
}
|
||||
|
||||
impl From<RangeOrOffset> for TextRange {
|
||||
fn from(selection: RangeOrOffset) -> Self {
|
||||
match selection {
|
||||
RangeOrOffset::Range(it) => it,
|
||||
RangeOrOffset::Offset(it) => TextRange::from_to(it, it),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_range_or_offset(text: &str) -> (RangeOrOffset, String) {
|
||||
if let Some((range, text)) = try_extract_range(text) {
|
||||
return (RangeOrOffset::Range(range), text);
|
||||
}
|
||||
let (offset, text) = extract_offset(text);
|
||||
(RangeOrOffset::Offset(offset), text)
|
||||
}
|
||||
|
||||
/// Extracts ranges, marked with `<tag> </tag>` paris from the `text`
|
||||
pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) {
|
||||
let open = format!("<{}>", tag);
|
||||
|
|
|
@ -245,3 +245,20 @@ fn main() {
|
|||
(1 + 2) * 4;
|
||||
}
|
||||
```
|
||||
|
||||
## `introduce_variable`
|
||||
|
||||
Extracts subexpression into a variable.
|
||||
|
||||
```rust
|
||||
// BEFORE
|
||||
fn main() {
|
||||
<|>(1 + 2)<|> * 4;
|
||||
}
|
||||
|
||||
// AFTER
|
||||
fn main() {
|
||||
let var_name = (1 + 2);
|
||||
var_name * 4;
|
||||
}
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue