use cpp_code_analysis::VfsFile;
use cpp_code_analysis::file::coordinates::FileOffset;
use cpp_code_analysis::format::completions_at;
use cpp_code_analysis::{DiskFiles, FileView, Session};
use lsp_types::{CompletionItem, CompletionItemKind, Position, Range, TextEdit};
pub fn format_string_complete(
session: &Session<DiskFiles>,
view: &FileView,
file: &VfsFile,
in_the_file: FileOffset,
) -> Option<Vec<CompletionItem>> {
if view.written_text().is_some() {
return None;
}
let config = super::config_for(session)?;
let literals = session.format_literals(view, &config);
let literal = literals
.iter()
.find(|literal| literal.range.contain(in_the_file.get()))?;
let text = view
.source
.get(literal.range.start_offset..literal.range.end_offset())?;
let at = in_the_file.get() - literal.range.start_offset;
let found = completions_at(text, literal.kind, at);
let start_of = |offset: usize| position_of(file, literal.range.start_offset + offset);
Some(
found
.into_iter()
.map(|completion| {
let range = match (start_of(completion.start), start_of(completion.end)) {
(Some(start), Some(end)) => Some(Range::new(start, end)),
_ => None,
};
CompletionItem {
label: completion.label.clone(),
kind: Some(CompletionItemKind::ENUM_MEMBER),
detail: Some(completion.detail),
filter_text: Some(completion.label.clone()),
text_edit: range.map(|range| {
lsp_types::CompletionTextEdit::Edit(TextEdit::new(
range,
completion.label.clone(),
))
}),
..CompletionItem::default()
}
})
.collect(),
)
}
fn position_of(file: &VfsFile, offset: usize) -> Option<Position> {
if offset > file.text.len() {
return None;
}
crate::util::position_in_file(file, offset)
}