diff --git a/Cargo.lock b/Cargo.lock index be461064fd..696a9ba509 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3567,7 +3567,6 @@ dependencies = [ "editor", "fuzzy", "gpui", - "language", "ordered-float", "postage", "project", diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 007706c41a..b6bb8230fb 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -80,7 +80,7 @@ pub trait LspExt: 'static + Send + Sync { fn label_for_completion(&self, _: &lsp::CompletionItem, _: &Language) -> Option { None } - fn label_for_symbol(&self, _: &lsp::SymbolInformation, _: &Language) -> Option { + fn label_for_symbol(&self, _: &str, _: lsp::SymbolKind, _: &Language) -> Option { None } } @@ -435,8 +435,8 @@ impl Language { .label_for_completion(completion, self) } - pub fn label_for_symbol(&self, symbol: &lsp::SymbolInformation) -> Option { - self.lsp_ext.as_ref()?.label_for_symbol(symbol, self) + pub fn label_for_symbol(&self, name: &str, kind: lsp::SymbolKind) -> Option { + self.lsp_ext.as_ref()?.label_for_symbol(name, kind, self) } pub fn highlight_text<'a>( diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index e651c16a81..8a76645aee 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -24,6 +24,7 @@ use postage::{broadcast, prelude::Stream, sink::Sink, watch}; use smol::block_on; use std::{ convert::TryInto, + mem, ops::Range, path::{Component, Path, PathBuf}, sync::{atomic::AtomicBool, Arc}, @@ -125,7 +126,9 @@ pub struct Symbol { pub language_name: String, pub path: PathBuf, pub label: CodeLabel, - pub lsp_symbol: lsp::SymbolInformation, + pub name: String, + pub kind: lsp::SymbolKind, + pub range: Range, } #[derive(Default)] @@ -1281,18 +1284,21 @@ impl Project { path = relativize_path(&worktree_abs_path, &abs_path); } - let label = - language.label_for_symbol(&lsp_symbol).unwrap_or_else( - || CodeLabel::plain(lsp_symbol.name.clone(), None), - ); + let label = language + .label_for_symbol(&lsp_symbol.name, lsp_symbol.kind) + .unwrap_or_else(|| { + CodeLabel::plain(lsp_symbol.name.clone(), None) + }); Some(Symbol { source_worktree_id, worktree_id, language_name: language.name().to_string(), + name: lsp_symbol.name, + kind: lsp_symbol.kind, label, path, - lsp_symbol, + range: range_from_lsp(lsp_symbol.location.range), }) }, )); @@ -2896,16 +2902,24 @@ impl Project { let language = self .languages .get_language(&serialized_symbol.language_name); - let lsp_symbol = serde_json::from_slice(&serialized_symbol.lsp_symbol)?; + let start = serialized_symbol + .start + .ok_or_else(|| anyhow!("invalid start"))?; + let end = serialized_symbol + .end + .ok_or_else(|| anyhow!("invalid end"))?; + let kind = unsafe { mem::transmute(serialized_symbol.kind) }; Ok(Symbol { source_worktree_id: WorktreeId::from_proto(serialized_symbol.source_worktree_id), worktree_id: WorktreeId::from_proto(serialized_symbol.worktree_id), language_name: serialized_symbol.language_name.clone(), label: language - .and_then(|language| language.label_for_symbol(&lsp_symbol)) - .unwrap_or(CodeLabel::plain(lsp_symbol.name.clone(), None)), + .and_then(|language| language.label_for_symbol(&serialized_symbol.name, kind)) + .unwrap_or_else(|| CodeLabel::plain(serialized_symbol.name.clone(), None)), + name: serialized_symbol.name, path: PathBuf::from(serialized_symbol.path), - lsp_symbol, + range: PointUtf16::new(start.row, start.column)..PointUtf16::new(end.row, end.column), + kind, }) } @@ -3195,8 +3209,17 @@ fn serialize_symbol(symbol: &Symbol) -> proto::Symbol { source_worktree_id: symbol.source_worktree_id.to_proto(), worktree_id: symbol.worktree_id.to_proto(), language_name: symbol.language_name.clone(), + name: symbol.name.clone(), + kind: unsafe { mem::transmute(symbol.kind) }, path: symbol.path.to_string_lossy().to_string(), - lsp_symbol: serde_json::to_vec(&symbol.lsp_symbol).unwrap(), + start: Some(proto::Point { + row: symbol.range.start.row, + column: symbol.range.start.column, + }), + end: Some(proto::Point { + row: symbol.range.end.row, + column: symbol.range.end.column, + }), } } diff --git a/crates/project_symbols/Cargo.toml b/crates/project_symbols/Cargo.toml index 77e125e9bb..f467261986 100644 --- a/crates/project_symbols/Cargo.toml +++ b/crates/project_symbols/Cargo.toml @@ -10,7 +10,6 @@ path = "src/project_symbols.rs" editor = { path = "../editor" } fuzzy = { path = "../fuzzy" } gpui = { path = "../gpui" } -language = { path = "../language" } project = { path = "../project" } text = { path = "../text" } workspace = { path = "../workspace" } diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index 3cd3ef1132..b20a37b295 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -10,7 +10,6 @@ use gpui::{ AppContext, Axis, Entity, ModelHandle, MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; -use language::range_from_lsp; use ordered_float::OrderedFloat; use postage::watch; use project::{Project, Symbol}; @@ -358,14 +357,13 @@ impl ProjectSymbolsView { let symbol = symbol.clone(); cx.spawn(|workspace, mut cx| async move { let buffer = buffer.await?; - let range = range_from_lsp(symbol.lsp_symbol.location.range); workspace.update(&mut cx, |workspace, cx| { let start; let end; { let buffer = buffer.read(cx); - start = buffer.clip_point_utf16(range.start, Bias::Left); - end = buffer.clip_point_utf16(range.end, Bias::Left); + start = buffer.clip_point_utf16(symbol.range.start, Bias::Left); + end = buffer.clip_point_utf16(symbol.range.end, Bias::Left); } let editor = workspace.open_item(BufferItemHandle(buffer), cx); diff --git a/crates/rpc/proto/zed.proto b/crates/rpc/proto/zed.proto index 0f001a26f7..91bf28ffe0 100644 --- a/crates/rpc/proto/zed.proto +++ b/crates/rpc/proto/zed.proto @@ -188,8 +188,11 @@ message Symbol { uint64 source_worktree_id = 1; uint64 worktree_id = 2; string language_name = 3; - string path = 4; - bytes lsp_symbol = 5; + string name = 4; + int32 kind = 5; + string path = 6; + Point start = 7; + Point end = 8; } message OpenBufferForSymbol { @@ -620,6 +623,11 @@ message Range { uint64 end = 2; } +message Point { + uint32 row = 1; + uint32 column = 2; +} + message Nonce { uint64 upper_half = 1; uint64 lower_half = 2; diff --git a/crates/zed/src/language.rs b/crates/zed/src/language.rs index ac56c29a0f..d7969259a4 100644 --- a/crates/zed/src/language.rs +++ b/crates/zed/src/language.rs @@ -233,49 +233,50 @@ impl LspExt for RustLsp { fn label_for_symbol( &self, - symbol: &lsp::SymbolInformation, + name: &str, + kind: lsp::SymbolKind, language: &Language, ) -> Option { - let (text, filter_range, display_range) = match symbol.kind { + let (text, filter_range, display_range) = match kind { lsp::SymbolKind::METHOD | lsp::SymbolKind::FUNCTION => { - let text = format!("fn {} () {{}}", symbol.name); - let filter_range = 3..3 + symbol.name.len(); + let text = format!("fn {} () {{}}", name); + let filter_range = 3..3 + name.len(); let display_range = 0..filter_range.end; (text, filter_range, display_range) } lsp::SymbolKind::STRUCT => { - let text = format!("struct {} {{}}", symbol.name); - let filter_range = 7..7 + symbol.name.len(); + let text = format!("struct {} {{}}", name); + let filter_range = 7..7 + name.len(); let display_range = 0..filter_range.end; (text, filter_range, display_range) } lsp::SymbolKind::ENUM => { - let text = format!("enum {} {{}}", symbol.name); - let filter_range = 5..5 + symbol.name.len(); + let text = format!("enum {} {{}}", name); + let filter_range = 5..5 + name.len(); let display_range = 0..filter_range.end; (text, filter_range, display_range) } lsp::SymbolKind::INTERFACE => { - let text = format!("trait {} {{}}", symbol.name); - let filter_range = 6..6 + symbol.name.len(); + let text = format!("trait {} {{}}", name); + let filter_range = 6..6 + name.len(); let display_range = 0..filter_range.end; (text, filter_range, display_range) } lsp::SymbolKind::CONSTANT => { - let text = format!("const {}: () = ();", symbol.name); - let filter_range = 6..6 + symbol.name.len(); + let text = format!("const {}: () = ();", name); + let filter_range = 6..6 + name.len(); let display_range = 0..filter_range.end; (text, filter_range, display_range) } lsp::SymbolKind::MODULE => { - let text = format!("mod {} {{}}", symbol.name); - let filter_range = 4..4 + symbol.name.len(); + let text = format!("mod {} {{}}", name); + let filter_range = 4..4 + name.len(); let display_range = 0..filter_range.end; (text, filter_range, display_range) } lsp::SymbolKind::TYPE_PARAMETER => { - let text = format!("type {} {{}}", symbol.name); - let filter_range = 5..5 + symbol.name.len(); + let text = format!("type {} {{}}", name); + let filter_range = 5..5 + name.len(); let display_range = 0..filter_range.end; (text, filter_range, display_range) } @@ -456,7 +457,6 @@ mod tests { } #[test] - #[allow(deprecated)] fn test_rust_label_for_symbol() { let language = rust(); let grammar = language.grammar().unwrap(); @@ -474,14 +474,7 @@ mod tests { let highlight_keyword = grammar.highlight_id_for_name("keyword").unwrap(); assert_eq!( - language.label_for_symbol(&lsp::SymbolInformation { - kind: lsp::SymbolKind::FUNCTION, - name: "hello".to_string(), - location: lsp::Location::new("file://a".parse().unwrap(), Default::default()), - container_name: Default::default(), - deprecated: Default::default(), - tags: Default::default(), - }), + language.label_for_symbol("hello", lsp::SymbolKind::FUNCTION), Some(CodeLabel { text: "fn hello".to_string(), filter_range: 3..8, @@ -490,14 +483,7 @@ mod tests { ); assert_eq!( - language.label_for_symbol(&lsp::SymbolInformation { - kind: lsp::SymbolKind::TYPE_PARAMETER, - name: "World".to_string(), - location: lsp::Location::new("file://a".parse().unwrap(), Default::default()), - container_name: Default::default(), - deprecated: Default::default(), - tags: Default::default(), - }), + language.label_for_symbol("World", lsp::SymbolKind::TYPE_PARAMETER), Some(CodeLabel { text: "type World".to_string(), filter_range: 5..10,