From 4a83aae09849123dbbbc5726b07c2601a14397a8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 26 Oct 2019 19:58:18 +0300 Subject: support range selection in assist docs --- .../ra_assists/src/assists/introduce_variable.rs | 18 ++++++++++-- crates/ra_assists/src/doc_tests.rs | 7 ++--- crates/ra_assists/src/doc_tests/generated.rs | 18 ++++++++++++ crates/test_utils/src/lib.rs | 34 ++++++++++++++++++++-- 4 files changed, 68 insertions(+), 9 deletions(-) (limited to 'crates') 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 @@ -//! 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) -> Option { if ctx.frange.range.is_empty() { 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; 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() 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() { "#####, ) } + +#[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; +} +"#####, + ) +} 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 @@ -//! 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 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 ` ` paris from the `text` pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec, String) { let open = format!("<{}>", tag); -- cgit v1.2.3