mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 10:40:54 +00:00
Don't serialize the full LSP symbol when collaborating
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
72ad3c2897
commit
fad335b2ba
7 changed files with 68 additions and 55 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3567,7 +3567,6 @@ dependencies = [
|
|||
"editor",
|
||||
"fuzzy",
|
||||
"gpui",
|
||||
"language",
|
||||
"ordered-float",
|
||||
"postage",
|
||||
"project",
|
||||
|
|
|
@ -80,7 +80,7 @@ pub trait LspExt: 'static + Send + Sync {
|
|||
fn label_for_completion(&self, _: &lsp::CompletionItem, _: &Language) -> Option<CodeLabel> {
|
||||
None
|
||||
}
|
||||
fn label_for_symbol(&self, _: &lsp::SymbolInformation, _: &Language) -> Option<CodeLabel> {
|
||||
fn label_for_symbol(&self, _: &str, _: lsp::SymbolKind, _: &Language) -> Option<CodeLabel> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -435,8 +435,8 @@ impl Language {
|
|||
.label_for_completion(completion, self)
|
||||
}
|
||||
|
||||
pub fn label_for_symbol(&self, symbol: &lsp::SymbolInformation) -> Option<CodeLabel> {
|
||||
self.lsp_ext.as_ref()?.label_for_symbol(symbol, self)
|
||||
pub fn label_for_symbol(&self, name: &str, kind: lsp::SymbolKind) -> Option<CodeLabel> {
|
||||
self.lsp_ext.as_ref()?.label_for_symbol(name, kind, self)
|
||||
}
|
||||
|
||||
pub fn highlight_text<'a>(
|
||||
|
|
|
@ -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<PointUtf16>,
|
||||
}
|
||||
|
||||
#[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,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -233,49 +233,50 @@ impl LspExt for RustLsp {
|
|||
|
||||
fn label_for_symbol(
|
||||
&self,
|
||||
symbol: &lsp::SymbolInformation,
|
||||
name: &str,
|
||||
kind: lsp::SymbolKind,
|
||||
language: &Language,
|
||||
) -> Option<CodeLabel> {
|
||||
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,
|
||||
|
|
Loading…
Reference in a new issue