diff options
Diffstat (limited to 'src/ide/complete.rs')
| -rw-r--r-- | src/ide/complete.rs | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/src/ide/complete.rs b/src/ide/complete.rs index 2e810ee9..a0d5e9a4 100644 --- a/src/ide/complete.rs +++ b/src/ide/complete.rs @@ -2,10 +2,14 @@ use std::collections::{BTreeSet, HashSet}; use ecow::{eco_format, EcoString}; use if_chain::if_chain; +use unscanny::Scanner; use super::{analyze_expr, analyze_import, plain_docs_sentence, summarize_font_family}; -use crate::eval::{methods_on, CastInfo, Scope, Value}; -use crate::syntax::{ast, LinkedNode, Source, SyntaxKind}; +use crate::eval::{methods_on, CastInfo, Library, Scope, Value}; +use crate::syntax::{ + ast, is_id_continue, is_id_start, is_ident, LinkedNode, Source, SyntaxKind, +}; +use crate::util::separated_list; use crate::World; /// Autocomplete a cursor position in a source file. @@ -104,6 +108,22 @@ fn complete_markup(ctx: &mut CompletionContext) -> bool { } } + // Directly after a raw block. + let mut s = Scanner::new(&ctx.text); + s.jump(ctx.leaf.offset()); + if s.eat_if("```") { + s.eat_while('`'); + let start = s.cursor(); + if s.eat_if(is_id_start) { + s.eat_while(is_id_continue); + } + if s.cursor() == ctx.cursor { + ctx.from = start; + ctx.raw_completions(); + } + return true; + } + // Anywhere: "|". if ctx.explicit { ctx.from = ctx.cursor; @@ -830,9 +850,11 @@ fn code_completions(ctx: &mut CompletionContext, hashtag: bool) { /// Context for autocompletion. struct CompletionContext<'a> { world: &'a (dyn World + 'static), + library: &'a Library, source: &'a Source, global: &'a Scope, math: &'a Scope, + text: &'a str, before: &'a str, after: &'a str, leaf: LinkedNode<'a>, @@ -852,12 +874,15 @@ impl<'a> CompletionContext<'a> { explicit: bool, ) -> Option<Self> { let text = source.text(); + let library = world.library(); let leaf = LinkedNode::new(source.root()).leaf_at(cursor)?; Some(Self { world, + library, source, - global: &world.library().global.scope(), - math: &world.library().math.scope(), + global: &library.global.scope(), + math: &library.math.scope(), + text, before: &text[..cursor], after: &text[cursor..], leaf, @@ -908,6 +933,28 @@ impl<'a> CompletionContext<'a> { } } + /// Add completions for raw block tags. + fn raw_completions(&mut self) { + for (name, mut tags) in (self.library.items.raw_languages)() { + let lower = name.to_lowercase(); + if !tags.contains(&lower.as_str()) { + tags.push(lower.as_str()); + } + + tags.retain(|tag| is_ident(tag)); + if tags.is_empty() { + continue; + } + + self.completions.push(Completion { + kind: CompletionKind::Constant, + label: name.into(), + apply: Some(tags[0].into()), + detail: Some(separated_list(&tags, " or ").into()), + }); + } + } + /// Add a completion for a specific value. fn value_completion( &mut self, |
