Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

175 lines
3.6 KiB
Rust
Raw Normal View History

2021-07-21 18:31:12 +02:00
//! Completes keywords, except:
//! - `self`, `super` and `crate`, as these are considered part of path completions.
//! - `await`, as this is a postfix completion we handle this in the postfix completions.
2022-06-03 16:11:26 +02:00
use syntax::ast::Item;
2022-06-17 10:45:19 +02:00
use crate::{
context::{NameRefContext, NameRefKind},
CompletionContext, Completions,
};
2019-01-08 22:33:36 +03:00
2020-10-25 10:59:15 +03:00
pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
2022-06-03 16:11:26 +02:00
let item = match ctx.nameref_ctx() {
2022-06-17 10:45:19 +02:00
Some(NameRefContext { kind: Some(NameRefKind::Keyword(item)), .. }) => item,
2022-06-03 16:11:26 +02:00
_ => return,
};
2021-06-17 15:10:25 +02:00
2022-06-03 16:33:37 +02:00
let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
2022-06-03 16:11:26 +02:00
match item {
Item::Impl(it) => {
if it.for_token().is_none() && it.trait_().is_none() && it.self_ty().is_some() {
add_keyword("for", "for");
}
add_keyword("where", "where");
}
Item::Enum(_)
| Item::Fn(_)
| Item::Struct(_)
| Item::Trait(_)
| Item::TypeAlias(_)
| Item::Union(_) => {
add_keyword("where", "where");
2021-06-17 15:43:21 +02:00
}
2022-06-03 16:11:26 +02:00
_ => (),
}
2020-06-13 13:47:30 +02:00
}
2019-01-08 22:33:36 +03:00
#[cfg(test)]
mod tests {
2020-08-21 13:19:31 +02:00
use expect_test::{expect, Expect};
2020-07-03 12:51:18 +02:00
use crate::tests::{check_edit, completion_list};
2020-07-03 12:51:18 +02:00
fn check(ra_fixture: &str, expect: Expect) {
let actual = completion_list(ra_fixture);
2020-07-03 12:51:18 +02:00
expect.assert_eq(&actual)
2020-06-12 08:49:12 +02:00
}
2019-01-08 22:33:36 +03:00
#[test]
fn test_else_edit_after_if() {
2020-07-03 13:21:14 +02:00
check_edit(
"else",
2021-01-06 20:15:48 +00:00
r#"fn quux() { if true { () } $0 }"#,
r#"fn quux() { if true { () } else {
$0
} }"#,
2020-07-03 13:21:14 +02:00
);
2019-01-08 22:33:36 +03:00
}
#[test]
fn test_keywords_after_unsafe_in_block_expr() {
2020-07-03 12:51:18 +02:00
check(
2021-01-06 20:15:48 +00:00
r"fn my_fn() { unsafe $0 }",
2020-07-03 12:51:18 +02:00
expect![[r#"
kw fn
kw impl
kw trait
sn pd
sn ppd
2020-07-03 12:51:18 +02:00
"#]],
2019-01-08 22:33:36 +03:00
);
}
2020-07-04 10:36:12 +02:00
#[test]
fn test_completion_await_impls_future() {
check(
r#"
//- minicore: future
use core::future::*;
2020-07-04 10:36:12 +02:00
struct A {}
impl Future for A {}
2021-01-06 20:15:48 +00:00
fn foo(a: A) { a.$0 }
2020-09-10 20:01:23 +08:00
"#,
expect![[r#"
kw await expr.await
sn box Box::new(expr)
sn call function(expr)
sn dbg dbg!(expr)
sn dbgr dbg!(&expr)
sn let let
sn letm let mut
sn match match expr {}
sn ref &expr
sn refm &mut expr
2020-09-10 20:01:23 +08:00
"#]],
);
check(
r#"
//- minicore: future
2020-09-10 20:01:23 +08:00
use std::future::*;
fn foo() {
let a = async {};
2021-01-06 20:15:48 +00:00
a.$0
2020-09-10 20:01:23 +08:00
}
2020-07-04 10:36:12 +02:00
"#,
expect![[r#"
kw await expr.await
sn box Box::new(expr)
sn call function(expr)
sn dbg dbg!(expr)
sn dbgr dbg!(&expr)
sn let let
sn letm let mut
sn match match expr {}
sn ref &expr
sn refm &mut expr
2020-07-04 10:36:12 +02:00
"#]],
)
}
2020-07-10 17:41:43 +02:00
#[test]
fn let_semi() {
2021-03-08 22:19:44 +02:00
cov_mark::check!(let_semi);
check_edit(
"match",
r#"
fn main() { let x = $0 }
"#,
r#"
fn main() { let x = match $1 {
$0
}; }
"#,
);
check_edit(
"if",
r#"
fn main() {
let x = $0
let y = 92;
}
"#,
r#"
fn main() {
let x = if $1 {
$0
};
let y = 92;
}
"#,
);
check_edit(
"loop",
r#"
fn main() {
let x = $0
bar();
}
"#,
r#"
fn main() {
let x = loop {
$0
};
bar();
}
"#,
);
}
2019-01-08 22:33:36 +03:00
}