mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +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 format_buf::format;
|
||||||
use hir::db::HirDatabase;
|
use hir::db::HirDatabase;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
|
@ -14,6 +12,22 @@ use test_utils::tested_by;
|
||||||
|
|
||||||
use crate::{Assist, AssistCtx, AssistId};
|
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> {
|
pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
|
||||||
if ctx.frange.range.is_empty() {
|
if ctx.frange.range.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
@ -7,13 +7,12 @@ mod generated;
|
||||||
|
|
||||||
use hir::mock::MockDatabase;
|
use hir::mock::MockDatabase;
|
||||||
use ra_db::FileRange;
|
use ra_db::FileRange;
|
||||||
use ra_syntax::TextRange;
|
use test_utils::{assert_eq_text, extract_range_or_offset};
|
||||||
use test_utils::{assert_eq_text, extract_offset};
|
|
||||||
|
|
||||||
fn check(assist_id: &str, before: &str, after: &str) {
|
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 (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)
|
let (_assist_id, action) = crate::assists(&db, frange)
|
||||||
.into_iter()
|
.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]
|
#[macro_use]
|
||||||
pub mod marks;
|
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 cursor_pos = text.find(CURSOR_MARKER)?;
|
||||||
let mut new_text = String::with_capacity(text.len() - CURSOR_MARKER.len());
|
let mut new_text = String::with_capacity(text.len() - CURSOR_MARKER.len());
|
||||||
new_text.push_str(&text[..cursor_pos]);
|
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 (start, text) = try_extract_offset(text)?;
|
||||||
let (end, text) = try_extract_offset(&text)?;
|
let (end, text) = try_extract_offset(&text)?;
|
||||||
Some((TextRange::from_to(start, end), 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`
|
/// Extracts ranges, marked with `<tag> </tag>` paris from the `text`
|
||||||
pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) {
|
pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) {
|
||||||
let open = format!("<{}>", tag);
|
let open = format!("<{}>", tag);
|
||||||
|
|
|
@ -245,3 +245,20 @@ fn main() {
|
||||||
(1 + 2) * 4;
|
(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