Skip to content

Introduce "introduce match" #531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions crates/ra_ide_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! However, IDE specific bits of the analysis (most notably completion) happen
//! in this crate.
//!
//! The sibling `ra_ide_api_light` handles thouse bits of IDE functionality
//! The sibling `ra_ide_api_light` handles those bits of IDE functionality
//! which are restricted to a single file and need only syntax.
mod db;
mod imp;
Expand Down Expand Up @@ -309,12 +309,12 @@ impl Analysis {
self.db.line_index(file_id)
}

/// Selects the next syntactic nodes encopasing the range.
/// Selects the next syntactic nodes encompassing the range.
pub fn extend_selection(&self, frange: FileRange) -> TextRange {
extend_selection::extend_selection(&self.db, frange)
}

/// Returns position of the mathcing brace (all types of braces are
/// Returns position of the matching brace (all types of braces are
/// supported).
pub fn matching_brace(&self, file: &SourceFile, offset: TextUnit) -> Option<TextUnit> {
ra_ide_api_light::matching_brace(file, offset)
Expand Down Expand Up @@ -397,7 +397,7 @@ impl Analysis {
self.with_db(|db| db.find_all_refs(position))
}

/// Returns a short text descrbing element at position.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit off-topic, but perhaps it helps anyone reading this

I too sometimes struggle with grammar :) A small tip from one non-native English speaker who likes to be correct to any other: there's two plugins that I use to help me avoid spelling issues in my code:

They complement each other, as one is used in "textual" contexts, such as README's, or code comments, while the other is used to avoid common spelling mistakes in my actual Rust code, and works with CamelCase situations.

Here's my config for both of them, in case it helps anyone:

{
    "spellright.language": ["en-GB"],
    "spellright.groupDictionaries": false,
    "spellright.documentTypes": [
        "markdown",
        "plaintext",
        "rust",
    ],
    "spellright.parserByClass": {
        "rust": {
            "parser": "code"
        }
    },
    "spellright.notificationClass": "information",
    "spellright.configurationScope": "user",
    "spellright.statusBarIndicator": false,

    "cSpell.checkLimit": 2048,
    "cSpell.language": "en-GB",
    "cSpell.showStatus": false,
    "cSpell.enabledLanguageIds": [
        "markdown",
        "plaintext",
        "rust"
    ],
    "cSpell.userWords": [
        "Deserialize",
        "Tuple",
        "alloc",
        "clippy",
        "rustc",
        "rustfmt",
        "struct",
    ],
    "cSpell.languageSettings": [
        {
            "languageId": "rust",
            "ignoreRegExpList": [
                "/\/\/\/? .*/"
            ]
        }
    ]
}

It's easy to add words to the cSpell.userWords array as you work, using the contextual popup in the editor. I trimmed the list down to a few useful ones for Rust development. The same goes for the spellright spelling updates, but those are stored in $VSCODE/User/spellright.dict:

clippy
fmt
impl
iter
mut
println
rustc
rustfmt
usize
utf8
vec

cc @matklad

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I do have a spelling problem in any language :-)

I've tried using a cspell check extension, but unfortunately it gives a fair amount of false positives, and in general is pretty distractive: F8 brings you not to the next compiler error, but to the one of the dozen spelling mistakes.

I'd love to have a spellchecker which only checks comments and have close to zeto false positiv rate, but I haven't invstigated this yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could start by using spellright, and configure it to only show you spelling mistakes in your code comments.

I agree that it's annoying that cspell gives plenty of false positives, but when I'm working in a project, I fairly quickly add all of the project-specific variable names to the list of ignored spellings, after which things quiet down.

Anyway, I agree, it's not perfect, but it helped me, and is "good enough" for now (especially if you skip cspell and only focus on comments/documentation in Rust).

/// Returns a short text describing element at position.
pub fn hover(&self, position: FilePosition) -> Cancelable<Option<RangeInfo<String>>> {
self.with_db(|db| hover::hover(db, position))
}
Expand Down
3 changes: 3 additions & 0 deletions crates/ra_ide_api_light/src/assists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
mod flip_comma;
mod add_derive;
mod add_impl;
mod introduce_match;
mod introduce_variable;
mod change_visibility;
mod split_import;
Expand All @@ -24,6 +25,7 @@ pub use self::{
flip_comma::flip_comma,
add_derive::add_derive,
add_impl::add_impl,
introduce_match::introduce_match,
introduce_variable::introduce_variable,
change_visibility::change_visibility,
split_import::split_import,
Expand All @@ -37,6 +39,7 @@ pub fn assists(file: &SourceFile, range: TextRange) -> Vec<LocalEdit> {
flip_comma,
add_derive,
add_impl,
introduce_match,
introduce_variable,
change_visibility,
split_import,
Expand Down
117 changes: 117 additions & 0 deletions crates/ra_ide_api_light/src/assists/introduce_match.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use ra_syntax::{ast::{self, AstNode}, TextUnit};

use crate::assists::{AssistCtx, Assist};

pub fn introduce_match<'a>(ctx: AssistCtx) -> Option<Assist> {
let node = ctx.covering_node();
let _expr = node.ancestors().filter_map(ast::Expr::cast).next()?;

ctx.build("introduce match", move |edit| {
let first_part = format!("match {} {{\n ", node.text());
let match_expr = format!("{}_ => (),\n}}", first_part);
edit.replace_node_and_indent(node, match_expr.into_boxed_str());

// FIXME: Set cursor at beginning of first match arm.
// The following doesn't work because of re-indentation:
//
// edit.set_cursor(expr.range().start() + TextUnit::of_str(&first_part));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... I think replace_and_indent could return an offset of the start of the substituted node?

//
// Workaround:
edit.set_cursor(node.range().start() + TextUnit::of_str("match "));
})
}

#[cfg(test)]
mod tests {
use super::*;
use crate::assists::{check_assist, check_assist_range};

#[test]
fn test_introduce_match_simple() {
check_assist(
introduce_match,
"
fn foo() {
let x = Some(42);
x<|>
}",
"
fn foo() {
let x = Some(42);
match <|>x {
_ => (),
}
}",
);
}

#[test]
fn test_introduce_match_expr_stmt() {
check_assist_range(
introduce_match,
"
fn foo() {
<|>Some(42).map(|x| x + 1)<|>
}",
"
fn foo() {
match <|>Some(42).map(|x| x + 1) {
_ => (),
}
}",
);
}

#[test]
fn test_introduce_match_part_of_expr_stmt() {
check_assist_range(
introduce_match,
"
fn foo() {
<|>Some(21)<|>.map(|x| x + 21);
}",
"
fn foo() {
match <|>Some(21) {
_ => (),
}.map(|x| x + 21);
}",
);
}

#[test]
fn test_introduce_match_last_expr() {
check_assist_range(
introduce_match,
"
fn foo() {
bar(<|>Ok(42)<|>)
}",
// FIXME: This is the wrong indentation
"
fn foo() {
bar(match <|>Ok(42) {
_ => (),
})
}",
);
}

#[test]
fn test_introduce_match_last_full_expr() {
check_assist_range(
introduce_match,
"
fn foo() {
<|>bar(1 + 1)<|>
}",
"
fn foo() {
match <|>bar(1 + 1) {
_ => (),
}
}",
);
}

}