use std::rc::Rc;
use super::{
super::environment::{CompletionEnvironment, CompletionLocation},
super::error::CompletionError,
super::utils::{CompletionTemplate, dispatch_completion_query},
};
use crate::server::{Server, lsp::CompletionList, message_handler::completion::utils::reduce_path};
use futures::lock::Mutex;
use ll_sparql_parser::syntax_kind::SyntaxKind;
pub async fn completions(
server_rc: Rc<Mutex<Server>>,
environment: &CompletionEnvironment,
) -> Result<CompletionList, CompletionError> {
let mut template_context = environment.template_context().await;
template_context.insert("local_context", &local_context(environment));
dispatch_completion_query(
server_rc,
environment,
template_context,
CompletionTemplate::PredicateCompletionContextInsensitive,
true,
)
.await
}
fn local_context(environment: &CompletionEnvironment) -> Option<String> {
if let CompletionLocation::BlankNodeProperty(ref prop_list) = environment.location {
if environment
.continuations
.contains(&SyntaxKind::PropertyListPath)
|| environment
.continuations
.contains(&SyntaxKind::PropertyListPathNotEmpty)
|| prop_list.property_list().is_none()
{
Some("[] ?qls_entity []".to_string())
} else {
let properties = prop_list.property_list().unwrap().properties();
if environment.continuations.contains(&SyntaxKind::VerbPath) {
Some("[] ?qls_entity []".to_string())
} else if properties.len() == 1 {
reduce_path(
"[]",
&properties[0].verb,
"[]",
environment
.anchor_token
.as_ref()
.unwrap()
.text_range()
.end(),
)
} else {
let (last_prop, prev_prop) = properties.split_last()?;
Some(format!(
"[] {} . {}",
prev_prop
.iter()
.map(|prop| prop.text())
.collect::<Vec<_>>()
.join(" ; "),
reduce_path(
"[]",
&last_prop.verb,
"[]",
environment
.anchor_token
.as_ref()
.unwrap()
.text_range()
.end()
)?
))
}
}
} else {
None
}
}