From 94b90761ebbdf33686e82feb5a89f98d049c5b65 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Tue, 27 Dec 2022 16:07:26 +0100 Subject: [PATCH] Bugfixes --- library/src/visualize/image.rs | 6 +++ src/ide/complete.rs | 57 +++--------------------- src/ide/mod.rs | 81 ++++++++++++++++++++++++++++++++++ src/ide/tooltip.rs | 42 ++---------------- 4 files changed, 97 insertions(+), 89 deletions(-) diff --git a/library/src/visualize/image.rs b/library/src/visualize/image.rs index bbb545765..07308b78d 100644 --- a/library/src/visualize/image.rs +++ b/library/src/visualize/image.rs @@ -23,6 +23,12 @@ use crate::prelude::*; /// - path: EcoString (positional, required) /// Path to an image file. /// +/// - width: Rel (named) +/// The width of the image. +/// +/// - height: Rel (named) +/// The height of the image. +/// /// ## Category /// visualize #[func] diff --git a/src/ide/complete.rs b/src/ide/complete.rs index ac60063b7..bbc4115a6 100644 --- a/src/ide/complete.rs +++ b/src/ide/complete.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use if_chain::if_chain; -use super::summarize_font_family; +use super::{plain_docs_sentence, summarize_font_family}; use crate::model::{CastInfo, Scope, Value}; use crate::syntax::ast::AstNode; use crate::syntax::{ast, LinkedNode, Source, SyntaxKind}; @@ -453,7 +453,7 @@ impl<'a> CompletionContext<'a> { kind: CompletionKind::Param, label: param.name.into(), apply: Some(format_eco!("{}: ${{}}", param.name)), - detail: Some(plain_docs_sentence(param.docs)), + detail: Some(plain_docs_sentence(param.docs).into()), }); } @@ -504,8 +504,8 @@ impl<'a> CompletionContext<'a> { self.snippet_completion("auto", "auto", "A smart default."); } CastInfo::Type("boolean") => { - self.snippet_completion("false", "false", "Yes / Enabled."); - self.snippet_completion("true", "true", "No / Disabled."); + self.snippet_completion("false", "false", "No / Disabled."); + self.snippet_completion("true", "true", "Yes / Enabled."); } CastInfo::Type("color") => { self.snippet_completion( @@ -566,7 +566,9 @@ impl<'a> CompletionContext<'a> { } let detail = docs.map(Into::into).or_else(|| match value { - Value::Func(func) => func.info().map(|info| plain_docs_sentence(info.docs)), + Value::Func(func) => { + func.info().map(|info| plain_docs_sentence(info.docs).into()) + } Value::Color(color) => Some(format_eco!("The color {color:?}.")), Value::Auto => Some("A smart default.".into()), _ => None, @@ -986,48 +988,3 @@ impl<'a> CompletionContext<'a> { self.scope_completions(|value| matches!(value, Value::Func(_))); } } - -/// Extract the first sentence of plain text of a piece of documentation. -/// -/// Removes Markdown formatting. -fn plain_docs_sentence(docs: &str) -> EcoString { - let mut s = unscanny::Scanner::new(docs); - let mut output = String::new(); - let mut link = false; - while let Some(c) = s.eat() { - match c { - '`' => { - let mut raw = s.eat_until('`'); - if (raw.starts_with('{') && raw.ends_with('}')) - || (raw.starts_with('[') && raw.ends_with(']')) - { - raw = &raw[1..raw.len() - 1]; - } - - s.eat(); - output.push('`'); - output.push_str(raw); - output.push('`'); - } - '[' => link = true, - ']' if link => { - if s.eat_if('(') { - s.eat_until(')'); - s.eat(); - } else if s.eat_if('[') { - s.eat_until(']'); - s.eat(); - } - link = false - } - '*' | '_' => {} - '.' => { - output.push('.'); - break; - } - _ => output.push(c), - } - } - - output.into() -} diff --git a/src/ide/mod.rs b/src/ide/mod.rs index 8068d4213..f52fa076c 100644 --- a/src/ide/mod.rs +++ b/src/ide/mod.rs @@ -7,3 +7,84 @@ mod tooltip; pub use complete::*; pub use highlight::*; pub use tooltip::*; + +use std::fmt::Write; + +use crate::font::{FontInfo, FontStyle}; + +/// Extract the first sentence of plain text of a piece of documentation. +/// +/// Removes Markdown formatting. +fn plain_docs_sentence(docs: &str) -> String { + let mut s = unscanny::Scanner::new(docs); + let mut output = String::new(); + let mut link = false; + while let Some(c) = s.eat() { + match c { + '`' => { + let mut raw = s.eat_until('`'); + if (raw.starts_with('{') && raw.ends_with('}')) + || (raw.starts_with('[') && raw.ends_with(']')) + { + raw = &raw[1..raw.len() - 1]; + } + + s.eat(); + output.push('`'); + output.push_str(raw); + output.push('`'); + } + '[' => link = true, + ']' if link => { + if s.eat_if('(') { + s.eat_until(')'); + s.eat(); + } else if s.eat_if('[') { + s.eat_until(']'); + s.eat(); + } + link = false + } + '*' | '_' => {} + '.' => { + output.push('.'); + break; + } + _ => output.push(c), + } + } + + output +} + +/// Create a short description of a font family. +pub fn summarize_font_family<'a>(variants: impl Iterator) -> String { + let mut infos: Vec<_> = variants.collect(); + infos.sort_by_key(|info| info.variant); + + let mut has_italic = false; + let mut min_weight = u16::MAX; + let mut max_weight = 0; + for info in &infos { + let weight = info.variant.weight.to_number(); + has_italic |= info.variant.style == FontStyle::Italic; + min_weight = min_weight.min(weight); + max_weight = min_weight.max(weight); + } + + let count = infos.len(); + let s = if count == 1 { "" } else { "s" }; + let mut detail = format!("{count} variant{s}."); + + if min_weight == max_weight { + write!(detail, " Weight {min_weight}.").unwrap(); + } else { + write!(detail, " Weights {min_weight}–{max_weight}.").unwrap(); + } + + if has_italic { + detail.push_str(" Has italics."); + } + + detail +} diff --git a/src/ide/tooltip.rs b/src/ide/tooltip.rs index 7f6ca692d..62cb11c1d 100644 --- a/src/ide/tooltip.rs +++ b/src/ide/tooltip.rs @@ -1,8 +1,6 @@ -use std::fmt::Write; - use if_chain::if_chain; -use crate::font::{FontInfo, FontStyle}; +use super::{plain_docs_sentence, summarize_font_family}; use crate::model::{CastInfo, Value}; use crate::syntax::ast::{self, AstNode}; use crate::syntax::{LinkedNode, Source, SyntaxKind}; @@ -28,7 +26,7 @@ fn function_tooltip(world: &dyn World, leaf: &LinkedNode) -> Option { if let Some(Value::Func(func)) = world.library().scope.get(ident); if let Some(info) = func.info(); then { - return Some(info.docs.into()); + return Some(plain_docs_sentence(&info.docs)); } } @@ -65,7 +63,7 @@ fn named_param_tooltip(world: &dyn World, leaf: &LinkedNode) -> Option { if let SyntaxKind::Ident(ident) = leaf.kind(); if let Some(param) = info.param(ident); then { - return Some(param.docs.into()); + return Some(plain_docs_sentence(param.docs)); } } @@ -126,37 +124,3 @@ fn font_family_tooltip(world: &dyn World, leaf: &LinkedNode) -> Option { None } - -/// Create a short description of a font family. -pub(super) fn summarize_font_family<'a>( - variants: impl Iterator, -) -> String { - let mut infos: Vec<_> = variants.collect(); - infos.sort_by_key(|info| info.variant); - - let mut has_italic = false; - let mut min_weight = u16::MAX; - let mut max_weight = 0; - for info in &infos { - let weight = info.variant.weight.to_number(); - has_italic |= info.variant.style == FontStyle::Italic; - min_weight = min_weight.min(weight); - max_weight = min_weight.max(weight); - } - - let count = infos.len(); - let s = if count == 1 { "" } else { "s" }; - let mut detail = format!("{count} variant{s}."); - - if min_weight == max_weight { - write!(detail, " Weight {min_weight}.").unwrap(); - } else { - write!(detail, " Weights {min_weight}–{max_weight}.").unwrap(); - } - - if has_italic { - detail.push_str(" Has italics."); - } - - detail -}