Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/flip_binexpr.rs')
| -rw-r--r-- | crates/ide-assists/src/handlers/flip_binexpr.rs | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/crates/ide-assists/src/handlers/flip_binexpr.rs b/crates/ide-assists/src/handlers/flip_binexpr.rs index 247e8109ab..8f2306e903 100644 --- a/crates/ide-assists/src/handlers/flip_binexpr.rs +++ b/crates/ide-assists/src/handlers/flip_binexpr.rs @@ -1,6 +1,7 @@ use syntax::{ SyntaxKind, T, - ast::{self, AstNode, BinExpr, syntax_factory::SyntaxFactory}, + ast::{self, AstNode, BinExpr, RangeItem, syntax_factory::SyntaxFactory}, + syntax_editor::Position, }; use crate::{AssistContext, AssistId, Assists}; @@ -87,6 +88,74 @@ impl From<ast::BinaryOp> for FlipAction { } } +// Assist: flip_range_expr +// +// Flips operands of a range expression. +// +// ``` +// fn main() { +// let _ = 90..$02; +// } +// ``` +// -> +// ``` +// fn main() { +// let _ = 2..90; +// } +// ``` +// --- +// ``` +// fn main() { +// let _ = 90..$0; +// } +// ``` +// -> +// ``` +// fn main() { +// let _ = ..90; +// } +// ``` +pub(crate) fn flip_range_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { + let range_expr = ctx.find_node_at_offset::<ast::RangeExpr>()?; + let op = range_expr.op_token()?; + let start = range_expr.start(); + let end = range_expr.end(); + + if !op.text_range().contains_range(ctx.selection_trimmed()) { + return None; + } + if start.is_none() && end.is_none() { + return None; + } + + acc.add( + AssistId::refactor_rewrite("flip_range_expr"), + "Flip range expression", + op.text_range(), + |builder| { + let mut edit = builder.make_editor(range_expr.syntax()); + + match (start, end) { + (Some(start), Some(end)) => { + edit.replace(start.syntax(), end.syntax()); + edit.replace(end.syntax(), start.syntax()); + } + (Some(start), None) => { + edit.delete(start.syntax()); + edit.insert(Position::after(&op), start.syntax().clone_for_update()); + } + (None, Some(end)) => { + edit.delete(end.syntax()); + edit.insert(Position::before(&op), end.syntax().clone_for_update()); + } + (None, None) => (), + } + + builder.add_file_edits(ctx.vfs_file_id(), edit); + }, + ) +} + #[cfg(test)] mod tests { use super::*; |