Remove possible multiline details in completions

This commit is contained in:
Lukas Wirth 2021-11-24 16:01:33 +01:00
parent 3e4ac8a2c9
commit 0c98a01b3e
10 changed files with 81 additions and 63 deletions

View file

@ -260,8 +260,8 @@ fn foo() { let _ = lib::S::$0 }
"#, "#,
expect![[r#" expect![[r#"
fn public_method() fn() fn public_method() fn()
ct PUBLIC_CONST pub const PUBLIC_CONST: u32 = 1; ct PUBLIC_CONST pub const PUBLIC_CONST: u32;
ta PublicType pub type PublicType = u32; ta PublicType pub type PublicType;
"#]], "#]],
); );
} }
@ -392,10 +392,10 @@ impl<T> Sub for Wrap<T> {
expect![[r#" expect![[r#"
ta SubTy (as Sub) type SubTy; ta SubTy (as Sub) type SubTy;
ta Ty (as Super) type Ty; ta Ty (as Super) type Ty;
ct CONST (as Super) const CONST: u8 = 0; ct CONST (as Super) const CONST: u8;
fn func() (as Super) fn() fn func() (as Super) fn()
me method() (as Super) fn(&self) me method() (as Super) fn(&self)
ct C2 (as Sub) const C2: () = (); ct C2 (as Sub) const C2: ();
fn subfunc() (as Sub) fn() fn subfunc() (as Sub) fn()
me submethod() (as Sub) fn(&self) me submethod() (as Sub) fn(&self)
"#]], "#]],
@ -626,7 +626,7 @@ impl u8 {
} }
"#, "#,
expect![[r#" expect![[r#"
ct MAX pub const MAX: Self = 255; ct MAX pub const MAX: Self;
me func() fn(self) me func() fn(self)
"#]], "#]],
); );

View file

@ -115,7 +115,7 @@ fn add_custom_completions(
for import in imports.into_iter() { for import in imports.into_iter() {
builder.add_import(import); builder.add_import(import);
} }
builder.detail(snip.description.as_deref().unwrap_or_default()); builder.set_detail(snip.description.clone());
builder.add_to(acc); builder.add_to(acc);
}, },
); );

View file

@ -433,7 +433,7 @@ fn main() { Foo::Fo$0 }
kind: SymbolKind( kind: SymbolKind(
Variant, Variant,
), ),
detail: "{ x: i32, y: i32 }", detail: "{x: i32, y: i32}",
}, },
] ]
"#]], "#]],

View file

@ -1,10 +1,10 @@
//! Renderer for `enum` variants. //! Renderer for `enum` variants.
use std::iter; use std::{iter, mem};
use hir::{HasAttrs, HirDisplay}; use hir::{HasAttrs, HirDisplay};
use ide_db::SymbolKind; use ide_db::SymbolKind;
use itertools::Itertools; use stdx::format_to;
use crate::{ use crate::{
item::{CompletionItem, ImportEdit}, item::{CompletionItem, ImportEdit},
@ -105,18 +105,31 @@ impl<'a> EnumRender<'a> {
.into_iter() .into_iter()
.map(|field| (field.name(self.ctx.db()), field.ty(self.ctx.db()))); .map(|field| (field.name(self.ctx.db()), field.ty(self.ctx.db())));
let mut b = String::new();
let mut first_run = true;
match self.variant_kind { match self.variant_kind {
hir::StructKind::Tuple | hir::StructKind::Unit => format!( hir::StructKind::Tuple | hir::StructKind::Unit => {
"({})", format_to!(b, "(");
detail_types.map(|(_, t)| t.display(self.ctx.db()).to_string()).format(", ") for (_, t) in detail_types {
), if !mem::take(&mut first_run) {
hir::StructKind::Record => format!( format_to!(b, ", ");
"{{ {} }}", }
detail_types format_to!(b, "{}", t.display(self.ctx.db()));
.map(|(n, t)| format!("{}: {}", n, t.display(self.ctx.db()).to_string())) }
.format(", ") format_to!(b, ")");
), }
hir::StructKind::Record => {
format_to!(b, "{{");
for (n, t) in detail_types {
if !mem::take(&mut first_run) {
format_to!(b, ", ");
}
format_to!(b, "{}: {}", n, t.display(self.ctx.db()));
}
format_to!(b, "}}");
}
} }
b
} }
} }

View file

@ -4,6 +4,7 @@ use either::Either;
use hir::{AsAssocItem, HasSource, HirDisplay}; use hir::{AsAssocItem, HasSource, HirDisplay};
use ide_db::SymbolKind; use ide_db::SymbolKind;
use itertools::Itertools; use itertools::Itertools;
use stdx::format_to;
use syntax::ast; use syntax::ast;
use crate::{ use crate::{
@ -122,14 +123,11 @@ impl<'a> FunctionRender<'a> {
fn detail(&self) -> String { fn detail(&self) -> String {
let ret_ty = self.func.ret_type(self.ctx.db()); let ret_ty = self.func.ret_type(self.ctx.db());
let ret = if ret_ty.is_unit() { let mut detail = format!("fn({})", self.params_display());
// Omit the return type if it is the unit type if !ret_ty.is_unit() {
String::new() format_to!(detail, " -> {}", ret_ty.display(self.ctx.db()));
} else { }
format!(" {}", self.ty_display()) detail
};
format!("fn({}){}", self.params_display(), ret)
} }
fn params_display(&self) -> String { fn params_display(&self) -> String {
@ -153,12 +151,6 @@ impl<'a> FunctionRender<'a> {
} }
} }
fn ty_display(&self) -> String {
let ret_ty = self.func.ret_type(self.ctx.db());
format!("-> {}", ret_ty.display(self.ctx.db()))
}
fn params(&self) -> Params { fn params(&self) -> Params {
let ast_params = match self.ast_node.param_list() { let ast_params = match self.ast_node.param_list() {
Some(it) => it, Some(it) => it,

View file

@ -176,6 +176,9 @@ fn validate_snippet(
imports.push(green); imports.push(green);
} }
let snippet = snippet.iter().join("\n"); let snippet = snippet.iter().join("\n");
let description = if description.is_empty() { None } else { Some(description.into()) }; let description = (!description.is_empty())
.then(|| description.split_once('\n').map_or(description, |(it, _)| it))
.map(ToOwned::to_owned)
.map(Into::into);
Some((imports.into_boxed_slice(), snippet, description)) Some((imports.into_boxed_slice(), snippet, description))
} }

View file

@ -544,11 +544,11 @@ fn func() {
"#, "#,
expect![[r#" expect![[r#"
ev TupleV() (u32) ev TupleV() (u32)
ev RecordV { field: u32 } ev RecordV {field: u32}
ev UnitV () ev UnitV ()
ct ASSOC_CONST const ASSOC_CONST: () = (); ct ASSOC_CONST const ASSOC_CONST: ();
fn assoc_fn() fn() fn assoc_fn() fn()
ta AssocType type AssocType = (); ta AssocType type AssocType;
"#]], "#]],
); );
} }

View file

@ -286,11 +286,11 @@ fn func() {
"#, "#,
expect![[r#" expect![[r#"
ev TupleV() (u32) ev TupleV() (u32)
ev RecordV { field: u32 } ev RecordV {field: u32}
ev UnitV () ev UnitV ()
ct ASSOC_CONST const ASSOC_CONST: () = (); ct ASSOC_CONST const ASSOC_CONST: ();
fn assoc_fn() fn() fn assoc_fn() fn()
ta AssocType type AssocType = (); ta AssocType type AssocType;
"#]], "#]],
); );
} }

View file

@ -199,7 +199,7 @@ impl Enum {
fn func(_: Enum::$0) {} fn func(_: Enum::$0) {}
"#, "#,
expect![[r#" expect![[r#"
ta AssocType type AssocType = (); ta AssocType type AssocType;
"#]], "#]],
); );
} }

View file

@ -1,10 +1,6 @@
//! This module contains utilities for turning SyntaxNodes and HIR types //! This module contains utilities for rendering syntax nodes into a string representing their signature.
//! into types that may be used to render in a UI.
use crate::{ use crate::ast::{self, HasAttrs, HasGenericParams, HasName};
ast::{self, AstNode, HasAttrs, HasGenericParams, HasName},
SyntaxKind::{ATTR, COMMENT},
};
use ast::HasVisibility; use ast::HasVisibility;
use stdx::format_to; use stdx::format_to;
@ -55,25 +51,39 @@ pub fn function_declaration(node: &ast::Fn) -> String {
} }
pub fn const_label(node: &ast::Const) -> String { pub fn const_label(node: &ast::Const) -> String {
let label: String = node let mut s = String::new();
.syntax() if let Some(vis) = node.visibility() {
.children_with_tokens() format_to!(s, "{} ", vis);
.filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR)) }
.map(|node| node.to_string()) format_to!(s, "const ");
.collect(); if let Some(name) = node.name() {
format_to!(s, "{}", name);
label.trim().to_owned() } else {
format_to!(s, "?");
}
format_to!(s, ": ");
if let Some(ty) = node.ty() {
format_to!(s, "{}", ty);
} else {
format_to!(s, "?");
}
format_to!(s, ";");
s
} }
pub fn type_label(node: &ast::TypeAlias) -> String { pub fn type_label(node: &ast::TypeAlias) -> String {
let label: String = node let mut s = String::new();
.syntax() if let Some(vis) = node.visibility() {
.children_with_tokens() format_to!(s, "{} ", vis);
.filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR)) }
.map(|node| node.to_string()) format_to!(s, "type ");
.collect(); if let Some(name) = node.name() {
format_to!(s, "{}", name);
label.trim().to_owned() } else {
format_to!(s, "?");
}
format_to!(s, ";");
s
} }
pub fn macro_label(node: &ast::Macro) -> String { pub fn macro_label(node: &ast::Macro) -> String {