Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide_completion/src/config.rs')
| -rw-r--r-- | crates/ide_completion/src/config.rs | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/crates/ide_completion/src/config.rs b/crates/ide_completion/src/config.rs index c300ce887b..b28b59b0a5 100644 --- a/crates/ide_completion/src/config.rs +++ b/crates/ide_completion/src/config.rs @@ -5,6 +5,8 @@ //! completions if we are allowed to. use ide_db::helpers::{insert_use::InsertUseConfig, SnippetCap}; +use itertools::Itertools; +use syntax::ast; #[derive(Clone, Debug, PartialEq, Eq)] pub struct CompletionConfig { @@ -15,4 +17,46 @@ pub struct CompletionConfig { pub add_call_argument_snippets: bool, pub snippet_cap: Option<SnippetCap>, pub insert_use: InsertUseConfig, + pub postfix_snippets: Vec<PostfixSnippet>, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct PostfixSnippet { + pub label: String, + snippet: String, + pub description: Option<String>, + pub requires: Box<[String]>, +} + +impl PostfixSnippet { + pub fn new( + label: String, + snippet: &[String], + description: &[String], + requires: &[String], + ) -> Option<Self> { + // validate that these are indeed simple paths + if requires.iter().any(|path| match ast::Path::parse(path) { + Ok(path) => path.segments().any(|seg| { + !matches!(seg.kind(), Some(ast::PathSegmentKind::Name(_))) + || seg.generic_arg_list().is_some() + }), + Err(_) => true, + }) { + return None; + } + let snippet = snippet.iter().join("\n"); + let description = description.iter().join("\n"); + let description = if description.is_empty() { None } else { Some(description) }; + Some(PostfixSnippet { + label, + snippet, + description, + requires: requires.iter().cloned().collect(), // Box::into doesn't work as that has a Copy bound 😒 + }) + } + + pub fn snippet(&self, receiver: &str) -> String { + self.snippet.replace("$receiver", receiver) + } } |