mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
tweak extend selection
This commit is contained in:
parent
8fc7f438c4
commit
05a9d42f54
3 changed files with 54 additions and 16 deletions
|
@ -1,5 +1,5 @@
|
||||||
use libsyntax2::{
|
use libsyntax2::{
|
||||||
File, TextRange, SyntaxNodeRef,
|
File, TextRange, SyntaxNodeRef, TextUnit,
|
||||||
SyntaxKind::*,
|
SyntaxKind::*,
|
||||||
algo::{find_leaf_at_offset, find_covering_node, ancestors, Direction, siblings},
|
algo::{find_leaf_at_offset, find_covering_node, ancestors, Direction, siblings},
|
||||||
};
|
};
|
||||||
|
@ -18,11 +18,22 @@ pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange>
|
||||||
}
|
}
|
||||||
let ws = leaves.next()?;
|
let ws = leaves.next()?;
|
||||||
let ws_text = ws.leaf_text().unwrap();
|
let ws_text = ws.leaf_text().unwrap();
|
||||||
let range = TextRange::from_to(offset, ws.range().end()) - ws.range().start();
|
let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start();
|
||||||
let ws_suffix = &ws_text.as_str()[range];
|
let prefix = TextRange::from_to(ws.range().start(), offset) - ws.range().start();
|
||||||
|
let ws_suffix = &ws_text.as_str()[suffix];
|
||||||
|
let ws_prefix = &ws_text.as_str()[prefix];
|
||||||
if ws_text.contains("\n") && !ws_suffix.contains("\n") {
|
if ws_text.contains("\n") && !ws_suffix.contains("\n") {
|
||||||
if let Some(node) = ws.next_sibling() {
|
if let Some(node) = ws.next_sibling() {
|
||||||
return Some(node.range());
|
let start = match ws_prefix.rfind('\n') {
|
||||||
|
Some(idx) => ws.range().start() + TextUnit::from((idx + 1) as u32),
|
||||||
|
None => node.range().start()
|
||||||
|
};
|
||||||
|
let end = if root.text().char_at(node.range().end()) == Some('\n') {
|
||||||
|
node.range().end() + TextUnit::of_char('\n')
|
||||||
|
} else {
|
||||||
|
node.range().end()
|
||||||
|
};
|
||||||
|
return Some(TextRange::from_to(start, end));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Some(ws.range());
|
return Some(ws.range());
|
||||||
|
@ -99,7 +110,7 @@ impl S {
|
||||||
|
|
||||||
}
|
}
|
||||||
}"#,
|
}"#,
|
||||||
&["fn foo() {\n\n }"]
|
&[" fn foo() {\n\n }\n"]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,16 @@ fn compute_expr_scopes(expr: ast::Expr, scopes: &mut FnScopes, scope: ScopeId) {
|
||||||
compute_block_scopes(block, scopes, scope);
|
compute_block_scopes(block, scopes, scope);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
ast::Expr::BlockExpr(e) => {
|
||||||
|
if let Some(block) = e.block() {
|
||||||
|
compute_block_scopes(block, scopes, scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast::Expr::LoopExpr(e) => {
|
||||||
|
if let Some(block) = e.loop_body() {
|
||||||
|
compute_block_scopes(block, scopes, scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
ast::Expr::WhileExpr(e) => {
|
ast::Expr::WhileExpr(e) => {
|
||||||
let cond_scope = e.condition().and_then(|cond| {
|
let cond_scope = e.condition().and_then(|cond| {
|
||||||
compute_cond_scopes(cond, scopes, scope)
|
compute_cond_scopes(cond, scopes, scope)
|
||||||
|
@ -147,11 +157,6 @@ fn compute_expr_scopes(expr: ast::Expr, scopes: &mut FnScopes, scope: ScopeId) {
|
||||||
if let Some(block) = e.loop_body() {
|
if let Some(block) = e.loop_body() {
|
||||||
compute_block_scopes(block, scopes, cond_scope.unwrap_or(scope));
|
compute_block_scopes(block, scopes, cond_scope.unwrap_or(scope));
|
||||||
}
|
}
|
||||||
},
|
|
||||||
ast::Expr::BlockExpr(e) => {
|
|
||||||
if let Some(block) = e.block() {
|
|
||||||
compute_block_scopes(block, scopes, scope);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ast::Expr::ForExpr(e) => {
|
ast::Expr::ForExpr(e) => {
|
||||||
if let Some(expr) = e.iterable() {
|
if let Some(expr) = e.iterable() {
|
||||||
|
@ -165,7 +170,7 @@ fn compute_expr_scopes(expr: ast::Expr, scopes: &mut FnScopes, scope: ScopeId) {
|
||||||
if let Some(block) = e.loop_body() {
|
if let Some(block) = e.loop_body() {
|
||||||
compute_block_scopes(block, scopes, scope);
|
compute_block_scopes(block, scopes, scope);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
ast::Expr::LambdaExpr(e) => {
|
ast::Expr::LambdaExpr(e) => {
|
||||||
let mut scope = scopes.new_scope(scope);
|
let mut scope = scopes.new_scope(scope);
|
||||||
scopes.add_params_bindings(scope, e.param_list());
|
scopes.add_params_bindings(scope, e.param_list());
|
||||||
|
@ -180,11 +185,7 @@ fn compute_expr_scopes(expr: ast::Expr, scopes: &mut FnScopes, scope: ScopeId) {
|
||||||
.chain(e.expr())
|
.chain(e.expr())
|
||||||
.for_each(|expr| compute_expr_scopes(expr, scopes, scope));
|
.for_each(|expr| compute_expr_scopes(expr, scopes, scope));
|
||||||
}
|
}
|
||||||
ast::Expr::LoopExpr(e) => {
|
|
||||||
if let Some(block) = e.loop_body() {
|
|
||||||
compute_block_scopes(block, scopes, scope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
expr.syntax().children()
|
expr.syntax().children()
|
||||||
.filter_map(ast::Expr::cast)
|
.filter_map(ast::Expr::cast)
|
||||||
|
@ -273,4 +274,18 @@ mod tests {
|
||||||
&["x"],
|
&["x"],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn test_match() {
|
||||||
|
// do_check(r"
|
||||||
|
// fn quux() {
|
||||||
|
// match () {
|
||||||
|
// Some(x) => {
|
||||||
|
// <|>
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// }",
|
||||||
|
// &["x"],
|
||||||
|
// );
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,18 @@ impl<'a> SyntaxText<'a> {
|
||||||
});
|
});
|
||||||
SyntaxText { node: self.node, range }
|
SyntaxText { node: self.node, range }
|
||||||
}
|
}
|
||||||
|
pub fn char_at(&self, offset: TextUnit) -> Option<char> {
|
||||||
|
let mut start: TextUnit = 0.into();
|
||||||
|
for chunk in self.chunks() {
|
||||||
|
let end = start + TextUnit::of_str(chunk);
|
||||||
|
if start <= offset && offset < end {
|
||||||
|
let off: usize = u32::from(offset - start) as usize;
|
||||||
|
return Some(chunk[off..].chars().next().unwrap());
|
||||||
|
}
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> fmt::Debug for SyntaxText<'a> {
|
impl<'a> fmt::Debug for SyntaxText<'a> {
|
||||||
|
|
Loading…
Reference in a new issue