From a4566c36a3b9c04801d8654c8386084ceae6645b Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 8 Apr 2024 21:43:18 -0400 Subject: [PATCH] gleam: Strip newlines in completion details returned from language server (#10304) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR updates the Gleam extension to strip out newlines in the completion details returned from the language server. These newlines were causing the completion menu to compute a large height for each item, resulting in lots of empty space in the completion menu: Screenshot 2024-04-08 at 8 53 29 PM The approach to stripping newlines allocates a bit more than I would like. It would be good to see if it is possible for the Gleam language server to not send us these newlines in the first place. Release Notes: - N/A --- extensions/gleam/src/gleam.rs | 39 ++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/extensions/gleam/src/gleam.rs b/extensions/gleam/src/gleam.rs index 6fe4024785403c19b76c30a95b3763ddc3aa1ebc..b754d705c9f5db78f3ce4e4cb69377da1104a410 100644 --- a/extensions/gleam/src/gleam.rs +++ b/extensions/gleam/src/gleam.rs @@ -114,7 +114,7 @@ impl zed::Extension for GleamExtension { completion: zed::lsp::Completion, ) -> Option { let name = &completion.label; - let ty = completion.detail?; + let ty = strip_newlines_from_detail(&completion.detail?); let let_binding = "let a"; let colon = ": "; let assignment = " = "; @@ -146,3 +146,40 @@ impl zed::Extension for GleamExtension { } zed::register_extension!(GleamExtension); + +/// Removes newlines from the completion detail. +/// +/// The Gleam LSP can return types containing newlines, which causes formatting +/// issues within the Zed completions menu. +fn strip_newlines_from_detail(detail: &str) -> String { + let without_newlines = detail + .replace("->\n ", "-> ") + .replace("\n ", "") + .replace(",\n", ""); + + let comma_delimited_parts = without_newlines.split(','); + comma_delimited_parts + .map(|part| part.trim()) + .collect::>() + .join(", ") +} + +#[cfg(test)] +mod tests { + use crate::strip_newlines_from_detail; + + #[test] + fn test_strip_newlines_from_detail() { + let detail = "fn(\n Selector(a),\n b,\n fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> a,\n) -> Selector(a)"; + let expected = "fn(Selector(a), b, fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> a) -> Selector(a)"; + assert_eq!(strip_newlines_from_detail(detail), expected); + + let detail = "fn(Selector(a), b, fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> a) ->\n Selector(a)"; + let expected = "fn(Selector(a), b, fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> a) -> Selector(a)"; + assert_eq!(strip_newlines_from_detail(detail), expected); + + let detail = "fn(\n Method,\n List(#(String, String)),\n a,\n Scheme,\n String,\n Option(Int),\n String,\n Option(String),\n) -> Request(a)"; + let expected = "fn(Method, List(#(String, String)), a, Scheme, String, Option(Int), String, Option(String)) -> Request(a)"; + assert_eq!(strip_newlines_from_detail(&detail), expected); + } +}