Start work on syntax highlighting completions

This commit is contained in:
Max Brunsfeld 2022-02-02 18:14:30 -08:00
parent 45898daf83
commit 439d12cb85
7 changed files with 349 additions and 221 deletions

View file

@ -49,11 +49,23 @@ pub trait ToLspPosition {
pub trait LspPostProcessor: 'static + Send + Sync {
fn process_diagnostics(&self, diagnostics: &mut lsp::PublishDiagnosticsParams);
fn label_for_completion(&self, _completion: &lsp::CompletionItem) -> Option<String> {
fn label_for_completion(
&self,
_: &lsp::CompletionItem,
_: &Language,
) -> Option<CompletionLabel> {
None
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CompletionLabel {
pub text: String,
pub runs: Vec<(Range<usize>, HighlightId)>,
pub filter_range: Range<usize>,
pub left_aligned_len: usize,
}
#[derive(Default, Deserialize)]
pub struct LanguageConfig {
pub name: String,
@ -253,24 +265,26 @@ impl Language {
}
}
pub fn label_for_completion(&self, completion: &lsp::CompletionItem) -> Option<String> {
pub fn label_for_completion(
&self,
completion: &lsp::CompletionItem,
) -> Option<CompletionLabel> {
self.lsp_post_processor
.as_ref()
.and_then(|p| p.label_for_completion(completion))
.as_ref()?
.label_for_completion(completion, self)
}
pub fn highlight_text<'a>(&'a self, text: &'a Rope) -> Vec<(Range<usize>, HighlightId)> {
pub fn highlight_text<'a>(
&'a self,
text: &'a Rope,
range: Range<usize>,
) -> Vec<(Range<usize>, HighlightId)> {
let mut result = Vec::new();
if let Some(grammar) = &self.grammar {
let tree = grammar.parse_text(text, None);
let mut offset = 0;
for chunk in BufferChunks::new(
text,
0..text.len(),
Some(&tree),
self.grammar.as_ref(),
vec![],
) {
for chunk in BufferChunks::new(text, range, Some(&tree), self.grammar.as_ref(), vec![])
{
let end_offset = offset + chunk.text.len();
if let Some(highlight_id) = chunk.highlight_id {
result.push((offset..end_offset, highlight_id));
@ -291,6 +305,10 @@ impl Language {
HighlightMap::new(grammar.highlights_query.capture_names(), theme);
}
}
pub fn grammar(&self) -> Option<&Arc<Grammar>> {
self.grammar.as_ref()
}
}
impl Grammar {
@ -316,6 +334,28 @@ impl Grammar {
pub fn highlight_map(&self) -> HighlightMap {
self.highlight_map.lock().clone()
}
pub fn highlight_id_for_name(&self, name: &str) -> Option<HighlightId> {
let capture_id = self.highlights_query.capture_index_for_name(name)?;
Some(self.highlight_map.lock().get(capture_id))
}
}
impl CompletionLabel {
fn plain(completion: &lsp::CompletionItem) -> Self {
let mut result = Self {
text: completion.label.clone(),
runs: Vec::new(),
left_aligned_len: completion.label.len(),
filter_range: 0..completion.label.len(),
};
if let Some(filter_text) = &completion.filter_text {
if let Some(ix) = completion.label.find(filter_text) {
result.filter_range = ix..ix + filter_text.len();
}
}
result
}
}
#[cfg(any(test, feature = "test-support"))]