diff --git a/crates/editor/src/folding_ranges.rs b/crates/editor/src/folding_ranges.rs index 749417e92ae9fce301265b834a6cbef1ca79297c..175f2cfa396d26c1de6ecbe29cb2d9e04e606a5d 100644 --- a/crates/editor/src/folding_ranges.rs +++ b/crates/editor/src/folding_ranges.rs @@ -859,7 +859,7 @@ mod tests { " }\n", "}\n", "\n", - "fn newline() { … }\n", + "fn newline() { … }\n", ] .concat(), ); @@ -996,7 +996,7 @@ mod tests { "\n", "fn outer() { outer… }\n", "\n", - "fn newline() { … }\n", + "fn newline() { … }\n", ] .concat(), ); diff --git a/crates/project/src/lsp_command.rs b/crates/project/src/lsp_command.rs index c8e51db90e159769612e2ed0fa5beb5ea218c833..bd94378433d7a8d992b913258999a6004b8031f2 100644 --- a/crates/project/src/lsp_command.rs +++ b/crates/project/src/lsp_command.rs @@ -4799,17 +4799,10 @@ impl LspCommand for GetFoldingRanges { ); let start = snapshot.anchor_after(start); let end = snapshot.anchor_before(end); - let collapsed_text = - folding_range - .collapsed_text - .filter(|t| !t.is_empty()) - .map(|t| { - if t.contains('\n') { - SharedString::from(t.replace('\n', " ")) - } else { - SharedString::from(t) - } - }); + let collapsed_text = folding_range + .collapsed_text + .filter(|t| !t.is_empty()) + .map(|t| SharedString::from(crate::lsp_store::collapse_newlines(&t, " "))); LspFoldingRange { range: start..end, collapsed_text, diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index d37674defb1abed9d77730827a6183aaf9ac87d6..f8f78e95c6a00cc023ed898e6a84ff23ad449167 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -7668,9 +7668,10 @@ impl LspStore { source_worktree_id, path, kind: symbol_kind, - name: symbol_name, + name: collapse_newlines(&symbol_name, "↵ "), range: range_from_lsp(symbol_location.range), - container_name, + container_name: container_name + .map(|c| collapse_newlines(&c, "↵ ")), }) }, ) @@ -14275,6 +14276,13 @@ async fn populate_labels_for_symbols( } } +pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String { + text.lines() + .map(|line| line.trim()) + .filter(|line| !line.is_empty()) + .join(separator) +} + fn include_text(server: &lsp::LanguageServer) -> Option { match server.capabilities().text_document_sync.as_ref()? { lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? { diff --git a/crates/project/src/lsp_store/document_symbols.rs b/crates/project/src/lsp_store/document_symbols.rs index c60c41b2d73781ca6a53964c354174caa65c459e..e0b16182a95b109eb1cf4b034369a28cafd58d85 100644 --- a/crates/project/src/lsp_store/document_symbols.rs +++ b/crates/project/src/lsp_store/document_symbols.rs @@ -249,6 +249,8 @@ fn flatten_document_symbols( output: &mut Vec>, ) { for symbol in symbols { + let name = super::collapse_newlines(&symbol.name, " "); + let start = snapshot.clip_point_utf16(symbol.range.start, Bias::Right); let end = snapshot.clip_point_utf16(symbol.range.end, Bias::Left); let selection_start = snapshot.clip_point_utf16(symbol.selection_range.start, Bias::Right); @@ -258,18 +260,12 @@ fn flatten_document_symbols( let selection_range = snapshot.anchor_after(selection_start)..snapshot.anchor_before(selection_end); - let (text, name_ranges, source_range_for_text) = enriched_symbol_text( - &symbol.name, - start, - selection_start, - selection_end, - snapshot, - ) - .unwrap_or_else(|| { - let name = symbol.name.clone(); - let name_len = name.len(); - (name, vec![0..name_len], selection_range.clone()) - }); + let (text, name_ranges, source_range_for_text) = + enriched_symbol_text(&name, start, selection_start, selection_end, snapshot) + .unwrap_or_else(|| { + let name_len = name.len(); + (name.clone(), vec![0..name_len], selection_range.clone()) + }); output.push(OutlineItem { depth, @@ -454,4 +450,50 @@ mod tests { flatten_document_symbols(&symbols, &snapshot, 0, &mut items); assert!(items.is_empty()); } + + #[gpui::test] + async fn test_newlines_collapsed_in_name(cx: &mut TestAppContext) { + let buffer = cx.new(|cx| Buffer::local("x = 1\ny = 2\n", cx)); + + let symbols = vec![ + make_symbol( + "line1\nline2", + lsp::SymbolKind::VARIABLE, + (0, 0)..(0, 5), + (0, 0)..(0, 1), + vec![], + ), + make_symbol( + " a \n b ", + lsp::SymbolKind::VARIABLE, + (1, 0)..(1, 5), + (1, 0)..(1, 1), + vec![], + ), + make_symbol( + "a\r\nb", + lsp::SymbolKind::VARIABLE, + (0, 0)..(1, 5), + (0, 0)..(0, 1), + vec![], + ), + make_symbol( + "a\n\nb", + lsp::SymbolKind::VARIABLE, + (0, 0)..(1, 5), + (0, 0)..(0, 1), + vec![], + ), + ]; + + let snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot()); + let mut items = Vec::new(); + flatten_document_symbols(&symbols, &snapshot, 0, &mut items); + + assert_eq!(items.len(), 4); + assert_eq!(items[0].text, "line1 line2"); + assert_eq!(items[1].text, "a b"); + assert_eq!(items[2].text, "a b"); + assert_eq!(items[3].text, "a b"); + } }