From 745892fbddea56040139108277e728b53fd8fc11 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Thu, 28 May 2020 03:03:21 +0000 Subject: CTAN sync 202005280303 --- support/texlab/src/completion/latex/argument.rs | 282 ++++++++++++++++-------- 1 file changed, 190 insertions(+), 92 deletions(-) (limited to 'support/texlab/src/completion/latex/argument.rs') diff --git a/support/texlab/src/completion/latex/argument.rs b/support/texlab/src/completion/latex/argument.rs index db05bca824..5736099ca6 100644 --- a/support/texlab/src/completion/latex/argument.rs +++ b/support/texlab/src/completion/latex/argument.rs @@ -1,44 +1,204 @@ use super::combinators::{self, Parameter}; -use crate::completion::factory; -use crate::completion::DATABASE; -use crate::workspace::*; -use futures_boxed::boxed; -use lsp_types::*; +use crate::{ + completion::types::{Item, ItemData}, + feature::FeatureRequest, + protocol::CompletionParams, +}; use std::iter; -#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub async fn complete_latex_arguments<'a>( + req: &'a FeatureRequest, + items: &mut Vec>, +) { + for comp in req.view.components() { + for cmd in &comp.commands { + for (i, param) in cmd.parameters.iter().enumerate() { + complete_internal(req, items, &cmd.name, i, param).await; + } + } + } +} + +async fn complete_internal<'a>( + req: &'a FeatureRequest, + items: &mut Vec>, + name: &'a str, + index: usize, + param: &'a crate::components::Parameter, +) { + combinators::argument( + req, + iter::once(Parameter { name, index }), + |ctx| async move { + for arg in ¶m.0 { + let item = Item::new( + ctx.range, + ItemData::Argument { + name: &arg.name, + image: arg.image.as_deref(), + }, + ); + items.push(item); + } + }, + ) + .await; +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + feature::FeatureTester, + protocol::{Range, RangeExt}, + }; + use indoc::indoc; + + #[tokio::test] + async fn empty_latex_document() { + let req = FeatureTester::new() + .file("main.tex", "") + .main("main.tex") + .position(0, 0) + .test_completion_request() + .await; + let mut actual_items = Vec::new(); + + complete_latex_arguments(&req, &mut actual_items).await; + + assert!(actual_items.is_empty()); + } + + #[tokio::test] + async fn empty_bibtex_document() { + let req = FeatureTester::new() + .file("main.bib", "") + .main("main.bib") + .position(0, 0) + .test_completion_request() + .await; + let mut actual_items = Vec::new(); + + complete_latex_arguments(&req, &mut actual_items).await; + + assert!(actual_items.is_empty()); + } + + #[tokio::test] + async fn inside_mathbb_empty() { + let req = FeatureTester::new() + .file( + "main.tex", + indoc!( + r#" + \usepackage{amsfonts} + \mathbb{} + "# + ), + ) + .main("main.tex") + .position(1, 8) + .test_completion_request() + .await; + let mut actual_items = Vec::new(); + + complete_latex_arguments(&req, &mut actual_items).await; + + assert!(!actual_items.is_empty()); + assert_eq!(actual_items[0].range, Range::new_simple(1, 8, 1, 8)); + } + + #[tokio::test] + async fn inside_mathbb_non_empty() { + let req = FeatureTester::new() + .file( + "main.tex", + indoc!( + r#" + \usepackage{amsfonts} + \mathbb{foo} + "# + ), + ) + .main("main.tex") + .position(1, 8) + .test_completion_request() + .await; + let mut actual_items = Vec::new(); + + complete_latex_arguments(&req, &mut actual_items).await; + + assert!(!actual_items.is_empty()); + assert_eq!(actual_items[0].range, Range::new_simple(1, 8, 1, 11)); + } + + #[tokio::test] + async fn outside_mathbb_empty() { + let req = FeatureTester::new() + .file( + "main.tex", + indoc!( + r#" + \usepackage{amsfonts} + \mathbb{} + "# + ), + ) + .main("main.tex") + .position(1, 9) + .test_completion_request() + .await; + let mut actual_items = Vec::new(); + + complete_latex_arguments(&req, &mut actual_items).await; + + assert!(actual_items.is_empty()); + } +} + +/* +use super::combinators::{self, Parameter}; +use crate::{ + completion::factory, + feature::{FeatureProvider, FeatureRequest}, + protocol::{CompletionItem, CompletionParams, TextEdit}, +}; +use async_trait::async_trait; +use std::iter; + +#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)] pub struct LatexArgumentCompletionProvider; +#[async_trait] impl FeatureProvider for LatexArgumentCompletionProvider { type Params = CompletionParams; type Output = Vec; - #[boxed] - async fn execute<'a>(&'a self, request: &'a FeatureRequest) -> Self::Output { + async fn execute<'a>(&'a self, req: &'a FeatureRequest) -> Self::Output { let mut all_items = Vec::new(); - for component in DATABASE.related_components(request.related_documents()) { - for command in &component.commands { - let name = format!("\\{}", command.name); - for (i, parameter) in command.parameters.iter().enumerate() { + for comp in req.view.components() { + for cmd in &comp.commands { + let name = format!("\\{}", cmd.name); + for (i, param) in cmd.parameters.iter().enumerate() { let mut items = combinators::argument( - request, - iter::once(Parameter::new(&name, i)), - |context| { - async move { - let mut items = Vec::new(); - for argument in ¶meter.0 { - let text_edit = - TextEdit::new(context.range, (&argument.name).into()); - let item = factory::argument( - request, - &argument.name, - text_edit, - argument.image.as_ref().map(AsRef::as_ref), - ); - items.push(item); - } - items + req, + iter::once(Parameter { + name: &name, + index: i, + }), + |ctx| async move { + let mut items = Vec::new(); + for arg in ¶m.0 { + let text_edit = TextEdit::new(ctx.range, (&arg.name).into()); + let item = factory::argument( + req, + &arg.name, + text_edit, + arg.image.as_ref().map(AsRef::as_ref), + ); + items.push(item); } + items }, ) .await; @@ -50,68 +210,6 @@ impl FeatureProvider for LatexArgumentCompletionProvider { } } -#[cfg(test)] -mod tests { - use super::*; - use crate::range::RangeExt; - use lsp_types::{Position, Range}; - - #[test] - fn test_inside_mathbb_empty() { - let items = test_feature( - LatexArgumentCompletionProvider, - FeatureSpec { - files: vec![FeatureSpec::file( - "foo.tex", - "\\usepackage{amsfonts}\n\\mathbb{}", - )], - main_file: "foo.tex", - position: Position::new(1, 8), - ..FeatureSpec::default() - }, - ); - assert!(!items.is_empty()); - assert_eq!( - items[0].text_edit.as_ref().map(|edit| edit.range), - Some(Range::new_simple(1, 8, 1, 8)) - ); - } - #[test] - fn test_inside_mathbb_non_empty() { - let items = test_feature( - LatexArgumentCompletionProvider, - FeatureSpec { - files: vec![FeatureSpec::file( - "foo.tex", - "\\usepackage{amsfonts}\n\\mathbb{foo}", - )], - main_file: "foo.tex", - position: Position::new(1, 8), - ..FeatureSpec::default() - }, - ); - assert!(!items.is_empty()); - assert_eq!( - items[0].text_edit.as_ref().map(|edit| edit.range), - Some(Range::new_simple(1, 8, 1, 11)) - ); - } - #[test] - fn test_outside_mathbb() { - let items = test_feature( - LatexArgumentCompletionProvider, - FeatureSpec { - files: vec![FeatureSpec::file( - "foo.tex", - "\\usepackage{amsfonts}\n\\mathbb{}", - )], - main_file: "foo.tex", - position: Position::new(1, 9), - ..FeatureSpec::default() - }, - ); - assert!(items.is_empty()); - } -} +*/ -- cgit v1.2.3