aboutsummaryrefslogtreecommitdiff
path: root/crates/libeditor
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-26 10:09:28 +0100
committerAleksey Kladov <[email protected]>2018-08-26 10:09:28 +0100
commitac226021cfd26a9332b5971f3e05118d77822af5 (patch)
tree04e9d19956b74d551f798bf26f420fa978b8f30f /crates/libeditor
parent4c121bfa2f2a7a06f01143e3203c650156e2fb4e (diff)
scope based comletion
Diffstat (limited to 'crates/libeditor')
-rw-r--r--crates/libeditor/src/code_actions.rs2
-rw-r--r--crates/libeditor/src/completion.rs42
-rw-r--r--crates/libeditor/tests/test.rs34
3 files changed, 53 insertions, 25 deletions
diff --git a/crates/libeditor/src/code_actions.rs b/crates/libeditor/src/code_actions.rs
index f53a8f9c6..e6ba83d2e 100644
--- a/crates/libeditor/src/code_actions.rs
+++ b/crates/libeditor/src/code_actions.rs
@@ -9,7 +9,7 @@ use libsyntax2::{
9 SyntaxNodeRef, 9 SyntaxNodeRef,
10 algo::{ 10 algo::{
11 Direction, siblings, 11 Direction, siblings,
12 find_leaf_at_offset, ancestors, 12 find_leaf_at_offset,
13 }, 13 },
14}; 14};
15 15
diff --git a/crates/libeditor/src/completion.rs b/crates/libeditor/src/completion.rs
index cf61ec784..16c9ead74 100644
--- a/crates/libeditor/src/completion.rs
+++ b/crates/libeditor/src/completion.rs
@@ -1,7 +1,11 @@
1use libsyntax2::{ 1use libsyntax2::{
2 File, TextUnit, 2 File, TextUnit, AstNode, SyntaxNodeRef,
3 ast, 3 ast::{self, NameOwner},
4 algo::find_leaf_at_offset, 4 algo::{
5 ancestors,
6 visit::{visitor_ctx, VisitorCtx},
7 walk::preorder,
8 },
5}; 9};
6 10
7use { 11use {
@@ -25,7 +29,33 @@ pub fn scope_completion(file: &File, offset: TextUnit) -> Option<Vec<CompletionI
25} 29}
26 30
27fn complete(name_ref: ast::NameRef) -> Vec<CompletionItem> { 31fn complete(name_ref: ast::NameRef) -> Vec<CompletionItem> {
28 vec![CompletionItem { 32 let mut res = Vec::new();
29 name: "foo".to_string() 33 for node in ancestors(name_ref.syntax()) {
30 }] 34 process_scope(node, &mut res);
35 }
36 res
37}
38
39fn process_scope(node: SyntaxNodeRef, sink: &mut Vec<CompletionItem>) {
40 let _ = visitor_ctx(sink)
41 .visit::<ast::Block, _>(|block, sink| {
42 block.let_stmts()
43 .filter_map(|it| it.pat())
44 .for_each(move |it| process_pat(it, sink))
45 })
46 .visit::<ast::FnDef, _>(|fn_def, sink| {
47 fn_def.param_list().into_iter()
48 .flat_map(|it| it.params())
49 .filter_map(|it| it.pat())
50 .for_each(move |it| process_pat(it, sink))
51 })
52 .accept(node);
53
54 fn process_pat(pat: ast::Pat, sink: &mut Vec<CompletionItem>) {
55 let items = preorder(pat.syntax())
56 .filter_map(ast::BindPat::cast)
57 .filter_map(ast::BindPat::name)
58 .map(|name| CompletionItem { name: name.text().to_string() });
59 sink.extend(items);
60 }
31} 61}
diff --git a/crates/libeditor/tests/test.rs b/crates/libeditor/tests/test.rs
index 20de2f240..ecdc149c7 100644
--- a/crates/libeditor/tests/test.rs
+++ b/crates/libeditor/tests/test.rs
@@ -256,25 +256,23 @@ struct Foo { f: u32 }
256"); 256");
257} 257}
258 258
259// #[test] 259#[test]
260// fn test_completion() { 260fn test_completion() {
261// fn do_check(code: &str, expected_completions: &str) { 261 fn do_check(code: &str, expected_completions: &str) {
262// let (off, code) = extract_offset(&code); 262 let (off, code) = extract_offset(&code);
263// let file = file(&code); 263 let file = file(&code);
264// let completions = scope_completion(&file, off).unwrap(); 264 let completions = scope_completion(&file, off).unwrap();
265// assert_eq_dbg(expected_completions, &completions); 265 assert_eq_dbg(expected_completions, &completions);
266// } 266 }
267 267
268// do_check(r" 268 do_check(r"
269// fn foo(foo: i32) { 269fn quux(x: i32) {
270// let bar = 92; 270 let y = 92;
271// 1 + <|> 271 1 + <|>
272// } 272}
273// ", r#" 273", r#"[CompletionItem { name: "y" },
274// CompletionItem { name: "bar" }, 274 CompletionItem { name: "x" }]"#);
275// CompletionItem { name: "foo" }, 275}
276// "#);
277// }
278 276
279fn file(text: &str) -> File { 277fn file(text: &str) -> File {
280 File::parse(text) 278 File::parse(text)