From 8d82d1551ee09faa5d46a58c17c40c2515d3f3b9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 22 Aug 2018 19:02:37 +0300 Subject: Extend add impl --- crates/libeditor/src/code_actions.rs | 68 ++++++++++++++++++++++++++---------- crates/libeditor/tests/test.rs | 10 +++--- 2 files changed, 55 insertions(+), 23 deletions(-) (limited to 'crates/libeditor') diff --git a/crates/libeditor/src/code_actions.rs b/crates/libeditor/src/code_actions.rs index 1e20c0f48..6c41923dd 100644 --- a/crates/libeditor/src/code_actions.rs +++ b/crates/libeditor/src/code_actions.rs @@ -1,4 +1,7 @@ -use {TextUnit, EditBuilder, Edit}; +use std::{ + fmt::{self, Write}, +}; + use libsyntax2::{ ast::{self, AstNode, AttrsOwner, TypeParamsOwner, NameOwner, ParsedFile}, SyntaxKind::COMMA, @@ -9,6 +12,8 @@ use libsyntax2::{ }, }; +use {TextUnit, EditBuilder, Edit}; + pub struct ActionResult { pub edit: Edit, pub cursor_position: Option, @@ -63,27 +68,31 @@ pub fn add_impl<'a>(file: &'a ParsedFile, offset: TextUnit) -> Option String::new(), - // Some(params) => { - // let mut buf = String::new(); - // } - // }; + let type_params = nominal.type_param_list(); let mut edit = EditBuilder::new(); let start_offset = nominal.syntax().range().end(); - edit.insert( - start_offset, - format!( - "\n\nimpl {} {{\n\n}}", - name.text(), - ) - ); + let mut buf = String::new(); + buf.push_str("\n\nimpl"); + if let Some(type_params) = type_params { + buf.push_display(&type_params.syntax().text()); + } + buf.push_str(" "); + buf.push_str(name.text().as_str()); + if let Some(type_params) = type_params { + comma_list( + &mut buf, "<", ">", + type_params.type_params() + .filter_map(|it| it.name()) + .map(|it| it.text()) + ); + } + buf.push_str(" {\n"); + let offset = start_offset + TextUnit::of_str(&buf); + buf.push_str("\n}"); + edit.insert(start_offset, buf); ActionResult { edit: edit.finish(), - cursor_position: Some( - start_offset + TextUnit::of_str("\n\nimpl {\n") + name.syntax().range().len() - ), + cursor_position: Some(offset), } }) } @@ -104,3 +113,26 @@ pub fn find_node<'a, N: AstNode<'a>>(syntax: SyntaxNodeRef<'a>, offset: TextUnit .next() } +fn comma_list(buf: &mut String, bra: &str, ket: &str, items: impl Iterator) { + buf.push_str(bra); + let mut first = true; + for item in items { + if !first { + first = false; + buf.push_str(", "); + } + write!(buf, "{}", item).unwrap(); + } + buf.push_str(ket); +} + +trait PushDisplay { + fn push_display(&mut self, item: &T); +} + +impl PushDisplay for String { + fn push_display(&mut self, item: &T) { + use std::fmt::Write; + write!(self, "{}", item).unwrap() + } +} diff --git a/crates/libeditor/tests/test.rs b/crates/libeditor/tests/test.rs index 3b0ec78eb..42926ffc8 100644 --- a/crates/libeditor/tests/test.rs +++ b/crates/libeditor/tests/test.rs @@ -151,11 +151,11 @@ fn test_add_impl() { "struct Foo {}\n\nimpl Foo {\n<|>\n}\n", |file, off| add_impl(file, off).map(|f| f()), ); - // check_action( - // "struct Foo {<|>}", - // "struct Foo {}\nimpl Foo {\n<|>\n}", - // |file, off| add_impl(file, off).map(|f| f()), - // ); + check_action( + "struct Foo {<|>}", + "struct Foo {}\n\nimpl Foo {\n<|>\n}", + |file, off| add_impl(file, off).map(|f| f()), + ); } #[test] -- cgit v1.2.3