diff --git a/Cargo.lock b/Cargo.lock index 624126c163b6bd30ff06a9ea3db2c0c2cddfccb0..ad03ed00e845e06b63135c65b0b273ed3e854d54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9134,6 +9134,7 @@ dependencies = [ "futures 0.3.31", "gpui", "http_client", + "indoc", "language", "log", "lsp", diff --git a/crates/diagnostics/src/diagnostic_renderer.rs b/crates/diagnostics/src/diagnostic_renderer.rs index 77bb249733f612ede3017e1cff592927b40e8d43..11b9f8ddb4ad3284bdac271743cc36f6f70fbf3f 100644 --- a/crates/diagnostics/src/diagnostic_renderer.rs +++ b/crates/diagnostics/src/diagnostic_renderer.rs @@ -6,7 +6,7 @@ use editor::{ hover_popover::diagnostics_markdown_style, }; use gpui::{AppContext, Entity, Focusable, WeakEntity}; -use language::{BufferId, Diagnostic, DiagnosticEntry}; +use language::{BufferId, Diagnostic, DiagnosticEntry, LanguageRegistry}; use lsp::DiagnosticSeverity; use markdown::{Markdown, MarkdownElement}; use settings::Settings; @@ -27,6 +27,7 @@ impl DiagnosticRenderer { diagnostic_group: Vec>, buffer_id: BufferId, diagnostics_editor: Option>, + languages: Arc, cx: &mut App, ) -> Vec { let Some(primary_ix) = diagnostic_group @@ -79,7 +80,9 @@ impl DiagnosticRenderer { initial_range: primary.range.clone(), severity: primary.diagnostic.severity, diagnostics_editor: diagnostics_editor.clone(), - markdown: cx.new(|cx| Markdown::new(markdown.into(), None, None, cx)), + markdown: cx.new(|cx| { + Markdown::new(markdown.into(), Some(languages.clone()), None, cx) + }), }); } else if entry.range.start.row.abs_diff(primary.range.start.row) < 5 { let markdown = Self::markdown(&entry.diagnostic); @@ -88,7 +91,9 @@ impl DiagnosticRenderer { initial_range: entry.range.clone(), severity: entry.diagnostic.severity, diagnostics_editor: diagnostics_editor.clone(), - markdown: cx.new(|cx| Markdown::new(markdown.into(), None, None, cx)), + markdown: cx.new(|cx| { + Markdown::new(markdown.into(), Some(languages.clone()), None, cx) + }), }); } else { let mut markdown = Self::markdown(&entry.diagnostic); @@ -100,7 +105,9 @@ impl DiagnosticRenderer { initial_range: entry.range.clone(), severity: entry.diagnostic.severity, diagnostics_editor: diagnostics_editor.clone(), - markdown: cx.new(|cx| Markdown::new(markdown.into(), None, None, cx)), + markdown: cx.new(|cx| { + Markdown::new(markdown.into(), Some(languages.clone()), None, cx) + }), }); } } @@ -127,9 +134,11 @@ impl editor::DiagnosticRenderer for DiagnosticRenderer { buffer_id: BufferId, snapshot: EditorSnapshot, editor: WeakEntity, + languages: Arc, cx: &mut App, ) -> Vec> { - let blocks = Self::diagnostic_blocks_for_group(diagnostic_group, buffer_id, None, cx); + let blocks = + Self::diagnostic_blocks_for_group(diagnostic_group, buffer_id, None, languages, cx); blocks .into_iter() .map(|block| { @@ -155,9 +164,11 @@ impl editor::DiagnosticRenderer for DiagnosticRenderer { diagnostic_group: Vec>, range: Range, buffer_id: BufferId, + languages: Arc, cx: &mut App, ) -> Option> { - let blocks = Self::diagnostic_blocks_for_group(diagnostic_group, buffer_id, None, cx); + let blocks = + Self::diagnostic_blocks_for_group(diagnostic_group, buffer_id, None, languages, cx); blocks.into_iter().find_map(|block| { if block.initial_range == range { Some(block.markdown) diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 1daa9025b64f2a783409ba5ebe10214ed55c362b..4841faaca33b4fd151595331919327a67f8f8e8d 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -508,6 +508,15 @@ impl ProjectDiagnosticsEditor { window: &mut Window, cx: &mut Context, ) -> Task> { + let languages = self + .editor + .read(cx) + .project + .as_ref() + .unwrap() + .read(cx) + .languages() + .clone(); let was_empty = self.multibuffer.read(cx).is_empty(); let buffer_snapshot = buffer.read(cx).snapshot(); let buffer_id = buffer_snapshot.remote_id(); @@ -559,6 +568,7 @@ impl ProjectDiagnosticsEditor { group, buffer_snapshot.remote_id(), Some(this.clone()), + languages.clone(), cx, ) })?; diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index a25a96cdabd30d43a60b6ab61b2e0ed2e3e41de7..db4e46591441d5d66a841a4b2e1f601a79c8a3cf 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -111,8 +111,9 @@ use itertools::Itertools; use language::{ AutoindentMode, BracketMatch, BracketPair, Buffer, Capability, CharKind, CodeLabel, CursorShape, DiagnosticEntry, DiffOptions, DocumentationConfig, EditPredictionsMode, - EditPreview, HighlightedText, IndentKind, IndentSize, Language, OffsetRangeExt, Point, - Selection, SelectionGoal, TextObject, TransactionId, TreeSitterOptions, WordsQuery, + EditPreview, HighlightedText, IndentKind, IndentSize, Language, LanguageRegistry, + OffsetRangeExt, Point, Selection, SelectionGoal, TextObject, TransactionId, TreeSitterOptions, + WordsQuery, language_settings::{ self, InlayHintSettings, LspInsertMode, RewrapBehavior, WordsCompletionMode, all_language_settings, language_settings, @@ -402,6 +403,7 @@ pub trait DiagnosticRenderer { buffer_id: BufferId, snapshot: EditorSnapshot, editor: WeakEntity, + languages: Arc, cx: &mut App, ) -> Vec>; @@ -410,6 +412,7 @@ pub trait DiagnosticRenderer { diagnostic_group: Vec>, range: Range, buffer_id: BufferId, + languages: Arc, cx: &mut App, ) -> Option>; @@ -16574,13 +16577,20 @@ impl Editor { let Some(renderer) = GlobalDiagnosticRenderer::global(cx) else { return; }; + let languages = self.project.as_ref().unwrap().read(cx).languages().clone(); let diagnostic_group = buffer .diagnostic_group(buffer_id, diagnostic.diagnostic.group_id) .collect::>(); - let blocks = - renderer.render_group(diagnostic_group, buffer_id, snapshot, cx.weak_entity(), cx); + let blocks = renderer.render_group( + diagnostic_group, + buffer_id, + snapshot, + cx.weak_entity(), + languages, + cx, + ); let blocks = self.display_map.update(cx, |display_map, cx| { display_map.insert_blocks(blocks, cx).into_iter().collect() diff --git a/crates/editor/src/hover_popover.rs b/crates/editor/src/hover_popover.rs index bda229e34669482549182b2c7abbe2c3efb9a751..7626ad7cd46caf2411de12cc5e518efea4b46866 100644 --- a/crates/editor/src/hover_popover.rs +++ b/crates/editor/src/hover_popover.rs @@ -275,6 +275,13 @@ fn show_hover( return None; } } + let languages = editor + .project + .as_ref() + .unwrap() + .read(cx) + .languages() + .clone(); let hover_popover_delay = EditorSettings::get_global(cx).hover_popover_delay; let all_diagnostics_active = editor.active_diagnostics == ActiveDiagnostic::All; @@ -340,7 +347,7 @@ fn show_hover( renderer .as_ref() .and_then(|renderer| { - renderer.render_hover(group, point_range, buffer_id, cx) + renderer.render_hover(group, point_range, buffer_id, languages, cx) }) .context("no rendered diagnostic") })??; diff --git a/crates/languages/Cargo.toml b/crates/languages/Cargo.toml index 2e8f007cff9b3dcdbc1be9c8405c90369ed12413..a49a310ebb2d6ca4866975cb5656c2d24d86364b 100644 --- a/crates/languages/Cargo.toml +++ b/crates/languages/Cargo.toml @@ -44,6 +44,7 @@ dap.workspace = true futures.workspace = true gpui.workspace = true http_client.workspace = true +indoc.workspace = true language.workspace = true log.workspace = true lsp.workspace = true diff --git a/crates/languages/src/vtsls.rs b/crates/languages/src/vtsls.rs index 6ef39e7142d42bf810538d05ba9e04e908e948a8..6c5986a090fb6f180338e60b67d56b45b0781ffd 100644 --- a/crates/languages/src/vtsls.rs +++ b/crates/languages/src/vtsls.rs @@ -283,26 +283,35 @@ impl LspAdapter for VtslsLspAdapter { fn diagnostic_message_to_markdown(&self, message: &str) -> Option { use regex::{Captures, Regex}; + dbg!(&message); // Helper functions for formatting let format_type_block = |prefix: &str, content: &str| -> String { if prefix.is_empty() { if content.len() > 50 || content.contains('\n') || content.contains('`') { - format!("\n```typescript\n{}\n```\n", content) + format!("\n```typescript\ntype a ={}\n```\n", dbg!(content)) } else { - format!("`{}`", content) + format!("`{}`", dbg!(content)) } } else { - format!("{} `{}`", prefix, content) + if content.len() > 50 || content.contains('\n') || content.contains('`') { + format!( + "{}\n```typescript\ntype a ={}\n```\n", + prefix, + dbg!(content) + ) + } else { + format!("{} `{}`", prefix, dbg!(content)) + } } }; let format_typescript_block = - |content: &str| -> String { format!("\n\n```typescript\n{}\n```\n", content) }; + |content: &str| -> String { format!("\n\n```typescript\n{}\n```\n", dbg!(content)) }; - let format_simple_type_block = |content: &str| -> String { format!("`{}`", content) }; + let format_simple_type_block = |content: &str| -> String { format!("`{}`", dbg!(content)) }; - let unstyle_code_block = |content: &str| -> String { format!("`{}`", content) }; + let unstyle_code_block = |content: &str| -> String { format!("`{}`", dbg!(content)) }; let mut result = message.to_string(); @@ -396,9 +405,11 @@ impl LspAdapter for VtslsLspAdapter { .to_string(); // Format types + dbg!(&result); let re = Regex::new(r#"(?i)(type|type alias|interface|module|file|file name|class|method's|subtype of constraint) ['"](.*?)['"]"#).unwrap(); result = re .replace_all(&result, |caps: &Captures| { + dbg!(&caps); format_type_block(&caps[1], &caps[2]) }) .to_string(); @@ -469,3 +480,25 @@ async fn get_cached_ts_server_binary( .await .log_err() } + +#[cfg(test)] +mod test { + use super::*; + use indoc::indoc; + + #[test] + fn test_diagnostic_message_to_markdown() { + let message = "Property 'user' is missing in type '{ person: { username: string; email: string; }; }' but required in type '{ user: { name: string; email: `${string}@${string}.${string}`; age: number; }; }'."; + let expected = indoc! { " + Property `user` is missing in type `{ person: { username: string; email: string; }; }` but required in type + + ```typescript + { user: { name: string; email: `${string}@${string}.${string}`; age: number; }; } + ``` + "}; + let result = VtslsLspAdapter::new(NodeRuntime::unavailable()) + .diagnostic_message_to_markdown(message) + .unwrap(); + pretty_assertions::assert_eq!(result, expected.to_string()); + } +} diff --git a/crates/markdown/src/markdown.rs b/crates/markdown/src/markdown.rs index dba4bc64b191b1e189cd114b2f66cd408c2feece..5912cb51661f4cf35e2645571dcef23ced1f443a 100644 --- a/crates/markdown/src/markdown.rs +++ b/crates/markdown/src/markdown.rs @@ -1534,12 +1534,26 @@ impl MarkdownElementBuilder { rendered_index: self.pending_line.text.len(), source_index: source_range.start, }); - self.pending_line.text.push_str(text); + if text.starts_with("type a =") { + self.pending_line.text.push_str(&text["type a =".len()..]); + } else { + self.pending_line.text.push_str(text); + } self.current_source_index = source_range.end; if let Some(Some(language)) = self.code_block_stack.last() { + dbg!(&language); let mut offset = 0; - for (range, highlight_id) in language.highlight_text(&Rope::from(text), 0..text.len()) { + for (mut range, highlight_id) in + language.highlight_text(&Rope::from(text), 0..text.len()) + { + if text.starts_with("type a =") { + if range.start < "type a =".len() || range.end < "type a =".len() { + continue; + } + range.start -= "type a =".len(); + range.end -= "type a =".len(); + }; if range.start > offset { self.pending_line .runs