Remove more todos

Antonio Scandurra created

Change summary

crates/editor2/src/editor.rs                | 968 +++++++++++-----------
crates/editor2/src/items.rs                 |  41 
crates/editor2/src/link_go_to_definition.rs | 538 ++++++------
crates/editor2/src/scroll.rs                |   3 
crates/workspace2/src/pane.rs               |  26 
crates/workspace2/src/workspace2.rs         | 142 +-
6 files changed, 856 insertions(+), 862 deletions(-)

Detailed changes

crates/editor2/src/editor.rs 🔗

@@ -21,7 +21,7 @@ mod editor_tests;
 #[cfg(any(test, feature = "test-support"))]
 pub mod test;
 use aho_corasick::AhoCorasick;
-use anyhow::Result;
+use anyhow::{Context as _, Result};
 use blink_manager::BlinkManager;
 use client::{ClickhouseEvent, Client, Collaborator, ParticipantIndex, TelemetrySettings};
 use clock::ReplicaId;
@@ -36,9 +36,9 @@ pub use element::{
 use futures::FutureExt;
 use fuzzy::{StringMatch, StringMatchCandidate};
 use gpui::{
-    AnyElement, AppContext, BackgroundExecutor, Context, Element, EventEmitter, FocusHandle, Hsla,
-    Model, Pixels, Render, Subscription, Task, TextStyle, View, ViewContext, WeakView,
-    WindowContext,
+    div, AnyElement, AppContext, BackgroundExecutor, Context, Div, Element, EventEmitter,
+    FocusHandle, Hsla, Model, Pixels, Render, Subscription, Task, TextStyle, View, ViewContext,
+    VisualContext, WeakView, WindowContext,
 };
 use highlight_matching_bracket::refresh_matching_bracket_highlights;
 use hover_popover::{hide_hover, HoverState};
@@ -48,10 +48,11 @@ use itertools::Itertools;
 pub use language::{char_kind, CharKind};
 use language::{
     language_settings::{self, all_language_settings, InlayHintSettings},
-    AutoindentMode, BracketPair, Buffer, CodeAction, Completion, CursorShape, Diagnostic, Language,
-    LanguageRegistry, OffsetRangeExt, Point, Selection, SelectionGoal, TransactionId,
+    point_from_lsp, AutoindentMode, BracketPair, Buffer, CodeAction, Completion, CursorShape,
+    Diagnostic, Language, LanguageRegistry, LanguageServerName, OffsetRangeExt, Point, Selection,
+    SelectionGoal, TransactionId,
 };
-use link_go_to_definition::{InlayHighlight, LinkGoToDefinitionState};
+use link_go_to_definition::{GoToDefinitionLink, InlayHighlight, LinkGoToDefinitionState};
 use lsp::{Documentation, LanguageServerId};
 pub use multi_buffer::{
     Anchor, AnchorRangeExt, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, ToOffset,
@@ -59,7 +60,7 @@ pub use multi_buffer::{
 };
 use ordered_float::OrderedFloat;
 use parking_lot::RwLock;
-use project::{FormatTrigger, Project};
+use project::{FormatTrigger, Location, Project};
 use rpc::proto::*;
 use scroll::{
     autoscroll::Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide,
@@ -69,6 +70,7 @@ use serde::{Deserialize, Serialize};
 use settings::{Settings, SettingsStore};
 use std::{
     any::TypeId,
+    borrow::Cow,
     cmp::{self, Reverse},
     ops::{ControlFlow, Deref, DerefMut, Range},
     path::Path,
@@ -80,7 +82,7 @@ use sum_tree::TreeMap;
 use text::Rope;
 use theme::ThemeColors;
 use util::{post_inc, RangeExt, ResultExt, TryFutureExt};
-use workspace::{ItemNavHistory, ViewId, Workspace};
+use workspace::{ItemNavHistory, SplitDirection, ViewId, Workspace};
 
 const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
 const MAX_LINE_LEN: usize = 1024;
@@ -389,6 +391,10 @@ impl InlayId {
 // todo!(revisit these actions)
 pub struct ShowCompletions;
 pub struct Rename;
+pub struct GoToDefinition;
+pub struct GoToTypeDefinition;
+pub struct GoToDefinitionSplit;
+pub struct GoToTypeDefinitionSplit;
 
 enum DocumentHighlightRead {}
 enum DocumentHighlightWrite {}
@@ -561,7 +567,7 @@ pub enum SelectPhase {
     Update {
         position: DisplayPoint,
         goal_column: u32,
-        scroll_position: gpui::Point<Pixels>,
+        scroll_position: gpui::Point<f32>,
     },
     End,
 }
@@ -1836,13 +1842,13 @@ impl Editor {
         Self::new(EditorMode::Full, buffer, project, cx)
     }
 
-    //     pub fn for_multibuffer(
-    //         buffer: Model<MultiBuffer>,
-    //         project: Option<Model<Project>>,
-    //         cx: &mut ViewContext<Self>,
-    //     ) -> Self {
-    //         Self::new(EditorMode::Full, buffer, project, None, cx)
-    //     }
+    pub fn for_multibuffer(
+        buffer: Model<MultiBuffer>,
+        project: Option<Model<Project>>,
+        cx: &mut ViewContext<Self>,
+    ) -> Self {
+        Self::new(EditorMode::Full, buffer, project, cx)
+    }
 
     pub fn clone(&self, cx: &mut ViewContext<Self>) -> Self {
         let mut clone = Self::new(
@@ -2048,9 +2054,9 @@ impl Editor {
     //         }
     //     }
 
-    //     pub fn replica_id(&self, cx: &AppContext) -> ReplicaId {
-    //         self.buffer.read(cx).replica_id()
-    //     }
+    pub fn replica_id(&self, cx: &AppContext) -> ReplicaId {
+        self.buffer.read(cx).replica_id()
+    }
 
     //     pub fn leader_peer_id(&self) -> Option<PeerId> {
     //         self.leader_peer_id
@@ -2060,13 +2066,13 @@ impl Editor {
         &self.buffer
     }
 
-    //     fn workspace(&self, cx: &AppContext) -> Option<ViewHandle<Workspace>> {
-    //         self.workspace.as_ref()?.0.upgrade(cx)
-    //     }
+    fn workspace(&self) -> Option<View<Workspace>> {
+        self.workspace.as_ref()?.0.upgrade()
+    }
 
-    //     pub fn title<'a>(&self, cx: &'a AppContext) -> Cow<'a, str> {
-    //         self.buffer().read(cx).title(cx)
-    //     }
+    pub fn title<'a>(&self, cx: &'a AppContext) -> Cow<'a, str> {
+        self.buffer().read(cx).title(cx)
+    }
 
     pub fn snapshot(&mut self, cx: &mut WindowContext) -> EditorSnapshot {
         EditorSnapshot {
@@ -2140,12 +2146,12 @@ impl Editor {
     //         self.collapse_matches = collapse_matches;
     //     }
 
-    //     pub fn range_for_match<T: std::marker::Copy>(&self, range: &Range<T>) -> Range<T> {
-    //         if self.collapse_matches {
-    //             return range.start..range.start;
-    //         }
-    //         range.clone()
-    //     }
+    pub fn range_for_match<T: std::marker::Copy>(&self, range: &Range<T>) -> Range<T> {
+        if self.collapse_matches {
+            return range.start..range.start;
+        }
+        range.clone()
+    }
 
     //     pub fn set_clip_at_line_ends(&mut self, clip: bool, cx: &mut ViewContext<Self>) {
     //         if self.display_map.read(cx).clip_at_line_ends != clip {
@@ -2383,253 +2389,253 @@ impl Editor {
     //         });
     //     }
 
-    //     fn select(&mut self, phase: SelectPhase, cx: &mut ViewContext<Self>) {
-    //         self.hide_context_menu(cx);
-
-    //         match phase {
-    //             SelectPhase::Begin {
-    //                 position,
-    //                 add,
-    //                 click_count,
-    //             } => self.begin_selection(position, add, click_count, cx),
-    //             SelectPhase::BeginColumnar {
-    //                 position,
-    //                 goal_column,
-    //             } => self.begin_columnar_selection(position, goal_column, cx),
-    //             SelectPhase::Extend {
-    //                 position,
-    //                 click_count,
-    //             } => self.extend_selection(position, click_count, cx),
-    //             SelectPhase::Update {
-    //                 position,
-    //                 goal_column,
-    //                 scroll_position,
-    //             } => self.update_selection(position, goal_column, scroll_position, cx),
-    //             SelectPhase::End => self.end_selection(cx),
-    //         }
-    //     }
-
-    //     fn extend_selection(
-    //         &mut self,
-    //         position: DisplayPoint,
-    //         click_count: usize,
-    //         cx: &mut ViewContext<Self>,
-    //     ) {
-    //         let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
-    //         let tail = self.selections.newest::<usize>(cx).tail();
-    //         self.begin_selection(position, false, click_count, cx);
-
-    //         let position = position.to_offset(&display_map, Bias::Left);
-    //         let tail_anchor = display_map.buffer_snapshot.anchor_before(tail);
+    fn select(&mut self, phase: SelectPhase, cx: &mut ViewContext<Self>) {
+        self.hide_context_menu(cx);
+
+        match phase {
+            SelectPhase::Begin {
+                position,
+                add,
+                click_count,
+            } => self.begin_selection(position, add, click_count, cx),
+            SelectPhase::BeginColumnar {
+                position,
+                goal_column,
+            } => self.begin_columnar_selection(position, goal_column, cx),
+            SelectPhase::Extend {
+                position,
+                click_count,
+            } => self.extend_selection(position, click_count, cx),
+            SelectPhase::Update {
+                position,
+                goal_column,
+                scroll_position,
+            } => self.update_selection(position, goal_column, scroll_position, cx),
+            SelectPhase::End => self.end_selection(cx),
+        }
+    }
 
-    //         let mut pending_selection = self
-    //             .selections
-    //             .pending_anchor()
-    //             .expect("extend_selection not called with pending selection");
-    //         if position >= tail {
-    //             pending_selection.start = tail_anchor;
-    //         } else {
-    //             pending_selection.end = tail_anchor;
-    //             pending_selection.reversed = true;
-    //         }
+    fn extend_selection(
+        &mut self,
+        position: DisplayPoint,
+        click_count: usize,
+        cx: &mut ViewContext<Self>,
+    ) {
+        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
+        let tail = self.selections.newest::<usize>(cx).tail();
+        self.begin_selection(position, false, click_count, cx);
+
+        let position = position.to_offset(&display_map, Bias::Left);
+        let tail_anchor = display_map.buffer_snapshot.anchor_before(tail);
+
+        let mut pending_selection = self
+            .selections
+            .pending_anchor()
+            .expect("extend_selection not called with pending selection");
+        if position >= tail {
+            pending_selection.start = tail_anchor;
+        } else {
+            pending_selection.end = tail_anchor;
+            pending_selection.reversed = true;
+        }
 
-    //         let mut pending_mode = self.selections.pending_mode().unwrap();
-    //         match &mut pending_mode {
-    //             SelectMode::Word(range) | SelectMode::Line(range) => *range = tail_anchor..tail_anchor,
-    //             _ => {}
-    //         }
+        let mut pending_mode = self.selections.pending_mode().unwrap();
+        match &mut pending_mode {
+            SelectMode::Word(range) | SelectMode::Line(range) => *range = tail_anchor..tail_anchor,
+            _ => {}
+        }
 
-    //         self.change_selections(Some(Autoscroll::fit()), cx, |s| {
-    //             s.set_pending(pending_selection, pending_mode)
-    //         });
-    //     }
+        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
+            s.set_pending(pending_selection, pending_mode)
+        });
+    }
 
-    //     fn begin_selection(
-    //         &mut self,
-    //         position: DisplayPoint,
-    //         add: bool,
-    //         click_count: usize,
-    //         cx: &mut ViewContext<Self>,
-    //     ) {
-    //         if !self.focused {
-    //             cx.focus_self();
-    //         }
+    fn begin_selection(
+        &mut self,
+        position: DisplayPoint,
+        add: bool,
+        click_count: usize,
+        cx: &mut ViewContext<Self>,
+    ) {
+        if !self.focused {
+            cx.focus(&self.focus_handle);
+        }
 
-    //         let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
-    //         let buffer = &display_map.buffer_snapshot;
-    //         let newest_selection = self.selections.newest_anchor().clone();
-    //         let position = display_map.clip_point(position, Bias::Left);
-
-    //         let start;
-    //         let end;
-    //         let mode;
-    //         let auto_scroll;
-    //         match click_count {
-    //             1 => {
-    //                 start = buffer.anchor_before(position.to_point(&display_map));
-    //                 end = start.clone();
-    //                 mode = SelectMode::Character;
-    //                 auto_scroll = true;
-    //             }
-    //             2 => {
-    //                 let range = movement::surrounding_word(&display_map, position);
-    //                 start = buffer.anchor_before(range.start.to_point(&display_map));
-    //                 end = buffer.anchor_before(range.end.to_point(&display_map));
-    //                 mode = SelectMode::Word(start.clone()..end.clone());
-    //                 auto_scroll = true;
-    //             }
-    //             3 => {
-    //                 let position = display_map
-    //                     .clip_point(position, Bias::Left)
-    //                     .to_point(&display_map);
-    //                 let line_start = display_map.prev_line_boundary(position).0;
-    //                 let next_line_start = buffer.clip_point(
-    //                     display_map.next_line_boundary(position).0 + Point::new(1, 0),
-    //                     Bias::Left,
-    //                 );
-    //                 start = buffer.anchor_before(line_start);
-    //                 end = buffer.anchor_before(next_line_start);
-    //                 mode = SelectMode::Line(start.clone()..end.clone());
-    //                 auto_scroll = true;
-    //             }
-    //             _ => {
-    //                 start = buffer.anchor_before(0);
-    //                 end = buffer.anchor_before(buffer.len());
-    //                 mode = SelectMode::All;
-    //                 auto_scroll = false;
-    //             }
-    //         }
+        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
+        let buffer = &display_map.buffer_snapshot;
+        let newest_selection = self.selections.newest_anchor().clone();
+        let position = display_map.clip_point(position, Bias::Left);
+
+        let start;
+        let end;
+        let mode;
+        let auto_scroll;
+        match click_count {
+            1 => {
+                start = buffer.anchor_before(position.to_point(&display_map));
+                end = start.clone();
+                mode = SelectMode::Character;
+                auto_scroll = true;
+            }
+            2 => {
+                let range = movement::surrounding_word(&display_map, position);
+                start = buffer.anchor_before(range.start.to_point(&display_map));
+                end = buffer.anchor_before(range.end.to_point(&display_map));
+                mode = SelectMode::Word(start.clone()..end.clone());
+                auto_scroll = true;
+            }
+            3 => {
+                let position = display_map
+                    .clip_point(position, Bias::Left)
+                    .to_point(&display_map);
+                let line_start = display_map.prev_line_boundary(position).0;
+                let next_line_start = buffer.clip_point(
+                    display_map.next_line_boundary(position).0 + Point::new(1, 0),
+                    Bias::Left,
+                );
+                start = buffer.anchor_before(line_start);
+                end = buffer.anchor_before(next_line_start);
+                mode = SelectMode::Line(start.clone()..end.clone());
+                auto_scroll = true;
+            }
+            _ => {
+                start = buffer.anchor_before(0);
+                end = buffer.anchor_before(buffer.len());
+                mode = SelectMode::All;
+                auto_scroll = false;
+            }
+        }
 
-    //         self.change_selections(auto_scroll.then(|| Autoscroll::newest()), cx, |s| {
-    //             if !add {
-    //                 s.clear_disjoint();
-    //             } else if click_count > 1 {
-    //                 s.delete(newest_selection.id)
-    //             }
+        self.change_selections(auto_scroll.then(|| Autoscroll::newest()), cx, |s| {
+            if !add {
+                s.clear_disjoint();
+            } else if click_count > 1 {
+                s.delete(newest_selection.id)
+            }
 
-    //             s.set_pending_anchor_range(start..end, mode);
-    //         });
-    //     }
+            s.set_pending_anchor_range(start..end, mode);
+        });
+    }
 
-    //     fn begin_columnar_selection(
-    //         &mut self,
-    //         position: DisplayPoint,
-    //         goal_column: u32,
-    //         cx: &mut ViewContext<Self>,
-    //     ) {
-    //         if !self.focused {
-    //             cx.focus_self();
-    //         }
+    fn begin_columnar_selection(
+        &mut self,
+        position: DisplayPoint,
+        goal_column: u32,
+        cx: &mut ViewContext<Self>,
+    ) {
+        if !self.focused {
+            cx.focus(&self.focus_handle);
+        }
 
-    //         let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
-    //         let tail = self.selections.newest::<Point>(cx).tail();
-    //         self.columnar_selection_tail = Some(display_map.buffer_snapshot.anchor_before(tail));
+        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
+        let tail = self.selections.newest::<Point>(cx).tail();
+        self.columnar_selection_tail = Some(display_map.buffer_snapshot.anchor_before(tail));
 
-    //         self.select_columns(
-    //             tail.to_display_point(&display_map),
-    //             position,
-    //             goal_column,
-    //             &display_map,
-    //             cx,
-    //         );
-    //     }
+        self.select_columns(
+            tail.to_display_point(&display_map),
+            position,
+            goal_column,
+            &display_map,
+            cx,
+        );
+    }
 
-    //     fn update_selection(
-    //         &mut self,
-    //         position: DisplayPoint,
-    //         goal_column: u32,
-    //         scroll_position: Vector2F,
-    //         cx: &mut ViewContext<Self>,
-    //     ) {
-    //         let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
+    fn update_selection(
+        &mut self,
+        position: DisplayPoint,
+        goal_column: u32,
+        scroll_position: gpui::Point<f32>,
+        cx: &mut ViewContext<Self>,
+    ) {
+        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 
-    //         if let Some(tail) = self.columnar_selection_tail.as_ref() {
-    //             let tail = tail.to_display_point(&display_map);
-    //             self.select_columns(tail, position, goal_column, &display_map, cx);
-    //         } else if let Some(mut pending) = self.selections.pending_anchor() {
-    //             let buffer = self.buffer.read(cx).snapshot(cx);
-    //             let head;
-    //             let tail;
-    //             let mode = self.selections.pending_mode().unwrap();
-    //             match &mode {
-    //                 SelectMode::Character => {
-    //                     head = position.to_point(&display_map);
-    //                     tail = pending.tail().to_point(&buffer);
-    //                 }
-    //                 SelectMode::Word(original_range) => {
-    //                     let original_display_range = original_range.start.to_display_point(&display_map)
-    //                         ..original_range.end.to_display_point(&display_map);
-    //                     let original_buffer_range = original_display_range.start.to_point(&display_map)
-    //                         ..original_display_range.end.to_point(&display_map);
-    //                     if movement::is_inside_word(&display_map, position)
-    //                         || original_display_range.contains(&position)
-    //                     {
-    //                         let word_range = movement::surrounding_word(&display_map, position);
-    //                         if word_range.start < original_display_range.start {
-    //                             head = word_range.start.to_point(&display_map);
-    //                         } else {
-    //                             head = word_range.end.to_point(&display_map);
-    //                         }
-    //                     } else {
-    //                         head = position.to_point(&display_map);
-    //                     }
+        if let Some(tail) = self.columnar_selection_tail.as_ref() {
+            let tail = tail.to_display_point(&display_map);
+            self.select_columns(tail, position, goal_column, &display_map, cx);
+        } else if let Some(mut pending) = self.selections.pending_anchor() {
+            let buffer = self.buffer.read(cx).snapshot(cx);
+            let head;
+            let tail;
+            let mode = self.selections.pending_mode().unwrap();
+            match &mode {
+                SelectMode::Character => {
+                    head = position.to_point(&display_map);
+                    tail = pending.tail().to_point(&buffer);
+                }
+                SelectMode::Word(original_range) => {
+                    let original_display_range = original_range.start.to_display_point(&display_map)
+                        ..original_range.end.to_display_point(&display_map);
+                    let original_buffer_range = original_display_range.start.to_point(&display_map)
+                        ..original_display_range.end.to_point(&display_map);
+                    if movement::is_inside_word(&display_map, position)
+                        || original_display_range.contains(&position)
+                    {
+                        let word_range = movement::surrounding_word(&display_map, position);
+                        if word_range.start < original_display_range.start {
+                            head = word_range.start.to_point(&display_map);
+                        } else {
+                            head = word_range.end.to_point(&display_map);
+                        }
+                    } else {
+                        head = position.to_point(&display_map);
+                    }
 
-    //                     if head <= original_buffer_range.start {
-    //                         tail = original_buffer_range.end;
-    //                     } else {
-    //                         tail = original_buffer_range.start;
-    //                     }
-    //                 }
-    //                 SelectMode::Line(original_range) => {
-    //                     let original_range = original_range.to_point(&display_map.buffer_snapshot);
-
-    //                     let position = display_map
-    //                         .clip_point(position, Bias::Left)
-    //                         .to_point(&display_map);
-    //                     let line_start = display_map.prev_line_boundary(position).0;
-    //                     let next_line_start = buffer.clip_point(
-    //                         display_map.next_line_boundary(position).0 + Point::new(1, 0),
-    //                         Bias::Left,
-    //                     );
+                    if head <= original_buffer_range.start {
+                        tail = original_buffer_range.end;
+                    } else {
+                        tail = original_buffer_range.start;
+                    }
+                }
+                SelectMode::Line(original_range) => {
+                    let original_range = original_range.to_point(&display_map.buffer_snapshot);
+
+                    let position = display_map
+                        .clip_point(position, Bias::Left)
+                        .to_point(&display_map);
+                    let line_start = display_map.prev_line_boundary(position).0;
+                    let next_line_start = buffer.clip_point(
+                        display_map.next_line_boundary(position).0 + Point::new(1, 0),
+                        Bias::Left,
+                    );
 
-    //                     if line_start < original_range.start {
-    //                         head = line_start
-    //                     } else {
-    //                         head = next_line_start
-    //                     }
+                    if line_start < original_range.start {
+                        head = line_start
+                    } else {
+                        head = next_line_start
+                    }
 
-    //                     if head <= original_range.start {
-    //                         tail = original_range.end;
-    //                     } else {
-    //                         tail = original_range.start;
-    //                     }
-    //                 }
-    //                 SelectMode::All => {
-    //                     return;
-    //                 }
-    //             };
+                    if head <= original_range.start {
+                        tail = original_range.end;
+                    } else {
+                        tail = original_range.start;
+                    }
+                }
+                SelectMode::All => {
+                    return;
+                }
+            };
 
-    //             if head < tail {
-    //                 pending.start = buffer.anchor_before(head);
-    //                 pending.end = buffer.anchor_before(tail);
-    //                 pending.reversed = true;
-    //             } else {
-    //                 pending.start = buffer.anchor_before(tail);
-    //                 pending.end = buffer.anchor_before(head);
-    //                 pending.reversed = false;
-    //             }
+            if head < tail {
+                pending.start = buffer.anchor_before(head);
+                pending.end = buffer.anchor_before(tail);
+                pending.reversed = true;
+            } else {
+                pending.start = buffer.anchor_before(tail);
+                pending.end = buffer.anchor_before(head);
+                pending.reversed = false;
+            }
 
-    //             self.change_selections(None, cx, |s| {
-    //                 s.set_pending(pending, mode);
-    //             });
-    //         } else {
-    //             error!("update_selection dispatched with no pending selection");
-    //             return;
-    //         }
+            self.change_selections(None, cx, |s| {
+                s.set_pending(pending, mode);
+            });
+        } else {
+            log::error!("update_selection dispatched with no pending selection");
+            return;
+        }
 
-    //         self.set_scroll_position(scroll_position, cx);
-    //         cx.notify();
-    //     }
+        self.set_scroll_position(scroll_position, cx);
+        cx.notify();
+    }
 
     fn end_selection(&mut self, cx: &mut ViewContext<Self>) {
         self.columnar_selection_tail.take();
@@ -7347,239 +7353,233 @@ impl Editor {
     //         }
     //     }
 
-    //     pub fn go_to_definition(&mut self, _: &GoToDefinition, cx: &mut ViewContext<Self>) {
-    //         self.go_to_definition_of_kind(GotoDefinitionKind::Symbol, false, cx);
-    //     }
+    pub fn go_to_definition(&mut self, _: &GoToDefinition, cx: &mut ViewContext<Self>) {
+        self.go_to_definition_of_kind(GotoDefinitionKind::Symbol, false, cx);
+    }
 
-    //     pub fn go_to_type_definition(&mut self, _: &GoToTypeDefinition, cx: &mut ViewContext<Self>) {
-    //         self.go_to_definition_of_kind(GotoDefinitionKind::Type, false, cx);
-    //     }
+    pub fn go_to_type_definition(&mut self, _: &GoToTypeDefinition, cx: &mut ViewContext<Self>) {
+        self.go_to_definition_of_kind(GotoDefinitionKind::Type, false, cx);
+    }
 
-    //     pub fn go_to_definition_split(&mut self, _: &GoToDefinitionSplit, cx: &mut ViewContext<Self>) {
-    //         self.go_to_definition_of_kind(GotoDefinitionKind::Symbol, true, cx);
-    //     }
+    pub fn go_to_definition_split(&mut self, _: &GoToDefinitionSplit, cx: &mut ViewContext<Self>) {
+        self.go_to_definition_of_kind(GotoDefinitionKind::Symbol, true, cx);
+    }
 
-    //     pub fn go_to_type_definition_split(
-    //         &mut self,
-    //         _: &GoToTypeDefinitionSplit,
-    //         cx: &mut ViewContext<Self>,
-    //     ) {
-    //         self.go_to_definition_of_kind(GotoDefinitionKind::Type, true, cx);
-    //     }
+    pub fn go_to_type_definition_split(
+        &mut self,
+        _: &GoToTypeDefinitionSplit,
+        cx: &mut ViewContext<Self>,
+    ) {
+        self.go_to_definition_of_kind(GotoDefinitionKind::Type, true, cx);
+    }
 
-    //     fn go_to_definition_of_kind(
-    //         &mut self,
-    //         kind: GotoDefinitionKind,
-    //         split: bool,
-    //         cx: &mut ViewContext<Self>,
-    //     ) {
-    //         let Some(workspace) = self.workspace(cx) else {
-    //             return;
-    //         };
-    //         let buffer = self.buffer.read(cx);
-    //         let head = self.selections.newest::<usize>(cx).head();
-    //         let (buffer, head) = if let Some(text_anchor) = buffer.text_anchor_for_position(head, cx) {
-    //             text_anchor
-    //         } else {
-    //             return;
-    //         };
+    fn go_to_definition_of_kind(
+        &mut self,
+        kind: GotoDefinitionKind,
+        split: bool,
+        cx: &mut ViewContext<Self>,
+    ) {
+        let Some(workspace) = self.workspace() else {
+            return;
+        };
+        let buffer = self.buffer.read(cx);
+        let head = self.selections.newest::<usize>(cx).head();
+        let (buffer, head) = if let Some(text_anchor) = buffer.text_anchor_for_position(head, cx) {
+            text_anchor
+        } else {
+            return;
+        };
 
-    //         let project = workspace.read(cx).project().clone();
-    //         let definitions = project.update(cx, |project, cx| match kind {
-    //             GotoDefinitionKind::Symbol => project.definition(&buffer, head, cx),
-    //             GotoDefinitionKind::Type => project.type_definition(&buffer, head, cx),
-    //         });
+        let project = workspace.read(cx).project().clone();
+        let definitions = project.update(cx, |project, cx| match kind {
+            GotoDefinitionKind::Symbol => project.definition(&buffer, head, cx),
+            GotoDefinitionKind::Type => project.type_definition(&buffer, head, cx),
+        });
 
-    //         cx.spawn_labeled("Fetching Definition...", |editor, mut cx| async move {
-    //             let definitions = definitions.await?;
-    //             editor.update(&mut cx, |editor, cx| {
-    //                 editor.navigate_to_definitions(
-    //                     definitions
-    //                         .into_iter()
-    //                         .map(GoToDefinitionLink::Text)
-    //                         .collect(),
-    //                     split,
-    //                     cx,
-    //                 );
-    //             })?;
-    //             Ok::<(), anyhow::Error>(())
-    //         })
-    //         .detach_and_log_err(cx);
-    //     }
+        cx.spawn(|editor, mut cx| async move {
+            let definitions = definitions.await?;
+            editor.update(&mut cx, |editor, cx| {
+                editor.navigate_to_definitions(
+                    definitions
+                        .into_iter()
+                        .map(GoToDefinitionLink::Text)
+                        .collect(),
+                    split,
+                    cx,
+                );
+            })?;
+            Ok::<(), anyhow::Error>(())
+        })
+        .detach_and_log_err(cx);
+    }
 
-    //     pub fn navigate_to_definitions(
-    //         &mut self,
-    //         mut definitions: Vec<GoToDefinitionLink>,
-    //         split: bool,
-    //         cx: &mut ViewContext<Editor>,
-    //     ) {
-    //         let Some(workspace) = self.workspace(cx) else {
-    //             return;
-    //         };
-    //         let pane = workspace.read(cx).active_pane().clone();
-    //         // If there is one definition, just open it directly
-    //         if definitions.len() == 1 {
-    //             let definition = definitions.pop().unwrap();
-    //             let target_task = match definition {
-    //                 GoToDefinitionLink::Text(link) => Task::Ready(Some(Ok(Some(link.target)))),
-    //                 GoToDefinitionLink::InlayHint(lsp_location, server_id) => {
-    //                     self.compute_target_location(lsp_location, server_id, cx)
-    //                 }
-    //             };
-    //             cx.spawn(|editor, mut cx| async move {
-    //                 let target = target_task.await.context("target resolution task")?;
-    //                 if let Some(target) = target {
-    //                     editor.update(&mut cx, |editor, cx| {
-    //                         let range = target.range.to_offset(target.buffer.read(cx));
-    //                         let range = editor.range_for_match(&range);
-    //                         if Some(&target.buffer) == editor.buffer.read(cx).as_singleton().as_ref() {
-    //                             editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
-    //                                 s.select_ranges([range]);
-    //                             });
-    //                         } else {
-    //                             cx.window_context().defer(move |cx| {
-    //                                 let target_editor: ViewHandle<Self> =
-    //                                     workspace.update(cx, |workspace, cx| {
-    //                                         if split {
-    //                                             workspace.split_project_item(target.buffer.clone(), cx)
-    //                                         } else {
-    //                                             workspace.open_project_item(target.buffer.clone(), cx)
-    //                                         }
-    //                                     });
-    //                                 target_editor.update(cx, |target_editor, cx| {
-    //                                     // When selecting a definition in a different buffer, disable the nav history
-    //                                     // to avoid creating a history entry at the previous cursor location.
-    //                                     pane.update(cx, |pane, _| pane.disable_history());
-    //                                     target_editor.change_selections(
-    //                                         Some(Autoscroll::fit()),
-    //                                         cx,
-    //                                         |s| {
-    //                                             s.select_ranges([range]);
-    //                                         },
-    //                                     );
-    //                                     pane.update(cx, |pane, _| pane.enable_history());
-    //                                 });
-    //                             });
-    //                         }
-    //                     })
-    //                 } else {
-    //                     Ok(())
-    //                 }
-    //             })
-    //             .detach_and_log_err(cx);
-    //         } else if !definitions.is_empty() {
-    //             let replica_id = self.replica_id(cx);
-    //             cx.spawn(|editor, mut cx| async move {
-    //                 let (title, location_tasks) = editor
-    //                     .update(&mut cx, |editor, cx| {
-    //                         let title = definitions
-    //                             .iter()
-    //                             .find_map(|definition| match definition {
-    //                                 GoToDefinitionLink::Text(link) => {
-    //                                     link.origin.as_ref().map(|origin| {
-    //                                         let buffer = origin.buffer.read(cx);
-    //                                         format!(
-    //                                             "Definitions for {}",
-    //                                             buffer
-    //                                                 .text_for_range(origin.range.clone())
-    //                                                 .collect::<String>()
-    //                                         )
-    //                                     })
-    //                                 }
-    //                                 GoToDefinitionLink::InlayHint(_, _) => None,
-    //                             })
-    //                             .unwrap_or("Definitions".to_string());
-    //                         let location_tasks = definitions
-    //                             .into_iter()
-    //                             .map(|definition| match definition {
-    //                                 GoToDefinitionLink::Text(link) => {
-    //                                     Task::Ready(Some(Ok(Some(link.target))))
-    //                                 }
-    //                                 GoToDefinitionLink::InlayHint(lsp_location, server_id) => {
-    //                                     editor.compute_target_location(lsp_location, server_id, cx)
-    //                                 }
-    //                             })
-    //                             .collect::<Vec<_>>();
-    //                         (title, location_tasks)
-    //                     })
-    //                     .context("location tasks preparation")?;
-
-    //                 let locations = futures::future::join_all(location_tasks)
-    //                     .await
-    //                     .into_iter()
-    //                     .filter_map(|location| location.transpose())
-    //                     .collect::<Result<_>>()
-    //                     .context("location tasks")?;
-    //                 workspace.update(&mut cx, |workspace, cx| {
-    //                     Self::open_locations_in_multibuffer(
-    //                         workspace, locations, replica_id, title, split, cx,
-    //                     )
-    //                 });
+    pub fn navigate_to_definitions(
+        &mut self,
+        mut definitions: Vec<GoToDefinitionLink>,
+        split: bool,
+        cx: &mut ViewContext<Editor>,
+    ) {
+        let Some(workspace) = self.workspace() else {
+            return;
+        };
+        let pane = workspace.read(cx).active_pane().clone();
+        // If there is one definition, just open it directly
+        if definitions.len() == 1 {
+            let definition = definitions.pop().unwrap();
+            let target_task = match definition {
+                GoToDefinitionLink::Text(link) => Task::Ready(Some(Ok(Some(link.target)))),
+                GoToDefinitionLink::InlayHint(lsp_location, server_id) => {
+                    self.compute_target_location(lsp_location, server_id, cx)
+                }
+            };
+            cx.spawn(|editor, mut cx| async move {
+                let target = target_task.await.context("target resolution task")?;
+                if let Some(target) = target {
+                    editor.update(&mut cx, |editor, cx| {
+                        let range = target.range.to_offset(target.buffer.read(cx));
+                        let range = editor.range_for_match(&range);
+                        if Some(&target.buffer) == editor.buffer.read(cx).as_singleton().as_ref() {
+                            editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
+                                s.select_ranges([range]);
+                            });
+                        } else {
+                            cx.window_context().defer(move |cx| {
+                                let target_editor: View<Self> =
+                                    workspace.update(cx, |workspace, cx| {
+                                        if split {
+                                            workspace.split_project_item(target.buffer.clone(), cx)
+                                        } else {
+                                            workspace.open_project_item(target.buffer.clone(), cx)
+                                        }
+                                    });
+                                target_editor.update(cx, |target_editor, cx| {
+                                    // When selecting a definition in a different buffer, disable the nav history
+                                    // to avoid creating a history entry at the previous cursor location.
+                                    pane.update(cx, |pane, _| pane.disable_history());
+                                    target_editor.change_selections(
+                                        Some(Autoscroll::fit()),
+                                        cx,
+                                        |s| {
+                                            s.select_ranges([range]);
+                                        },
+                                    );
+                                    pane.update(cx, |pane, _| pane.enable_history());
+                                });
+                            });
+                        }
+                    })
+                } else {
+                    Ok(())
+                }
+            })
+            .detach_and_log_err(cx);
+        } else if !definitions.is_empty() {
+            let replica_id = self.replica_id(cx);
+            cx.spawn(|editor, mut cx| async move {
+                let (title, location_tasks) = editor
+                    .update(&mut cx, |editor, cx| {
+                        let title = definitions
+                            .iter()
+                            .find_map(|definition| match definition {
+                                GoToDefinitionLink::Text(link) => {
+                                    link.origin.as_ref().map(|origin| {
+                                        let buffer = origin.buffer.read(cx);
+                                        format!(
+                                            "Definitions for {}",
+                                            buffer
+                                                .text_for_range(origin.range.clone())
+                                                .collect::<String>()
+                                        )
+                                    })
+                                }
+                                GoToDefinitionLink::InlayHint(_, _) => None,
+                            })
+                            .unwrap_or("Definitions".to_string());
+                        let location_tasks = definitions
+                            .into_iter()
+                            .map(|definition| match definition {
+                                GoToDefinitionLink::Text(link) => {
+                                    Task::Ready(Some(Ok(Some(link.target))))
+                                }
+                                GoToDefinitionLink::InlayHint(lsp_location, server_id) => {
+                                    editor.compute_target_location(lsp_location, server_id, cx)
+                                }
+                            })
+                            .collect::<Vec<_>>();
+                        (title, location_tasks)
+                    })
+                    .context("location tasks preparation")?;
+
+                let locations = futures::future::join_all(location_tasks)
+                    .await
+                    .into_iter()
+                    .filter_map(|location| location.transpose())
+                    .collect::<Result<_>>()
+                    .context("location tasks")?;
+                workspace.update(&mut cx, |workspace, cx| {
+                    Self::open_locations_in_multibuffer(
+                        workspace, locations, replica_id, title, split, cx,
+                    )
+                });
 
-    //                 anyhow::Ok(())
-    //             })
-    //             .detach_and_log_err(cx);
-    //         }
-    //     }
+                anyhow::Ok(())
+            })
+            .detach_and_log_err(cx);
+        }
+    }
 
-    //     fn compute_target_location(
-    //         &self,
-    //         lsp_location: lsp::Location,
-    //         server_id: LanguageServerId,
-    //         cx: &mut ViewContext<Editor>,
-    //     ) -> Task<anyhow::Result<Option<Location>>> {
-    //         let Some(project) = self.project.clone() else {
-    //             return Task::Ready(Some(Ok(None)));
-    //         };
+    fn compute_target_location(
+        &self,
+        lsp_location: lsp::Location,
+        server_id: LanguageServerId,
+        cx: &mut ViewContext<Editor>,
+    ) -> Task<anyhow::Result<Option<Location>>> {
+        let Some(project) = self.project.clone() else {
+            return Task::Ready(Some(Ok(None)));
+        };
 
-    //         cx.spawn(move |editor, mut cx| async move {
-    //             let location_task = editor.update(&mut cx, |editor, cx| {
-    //                 project.update(cx, |project, cx| {
-    //                     let language_server_name =
-    //                         editor.buffer.read(cx).as_singleton().and_then(|buffer| {
-    //                             project
-    //                                 .language_server_for_buffer(buffer.read(cx), server_id, cx)
-    //                                 .map(|(_, lsp_adapter)| {
-    //                                     LanguageServerName(Arc::from(lsp_adapter.name()))
-    //                                 })
-    //                         });
-    //                     language_server_name.map(|language_server_name| {
-    //                         project.open_local_buffer_via_lsp(
-    //                             lsp_location.uri.clone(),
-    //                             server_id,
-    //                             language_server_name,
-    //                             cx,
-    //                         )
-    //                     })
-    //                 })
-    //             })?;
-    //             let location = match location_task {
-    //                 Some(task) => Some({
-    //                     let target_buffer_handle = task.await.context("open local buffer")?;
-    //                     let range = {
-    //                         target_buffer_handle.update(&mut cx, |target_buffer, _| {
-    //                             let target_start = target_buffer.clip_point_utf16(
-    //                                 point_from_lsp(lsp_location.range.start),
-    //                                 Bias::Left,
-    //                             );
-    //                             let target_end = target_buffer.clip_point_utf16(
-    //                                 point_from_lsp(lsp_location.range.end),
-    //                                 Bias::Left,
-    //                             );
-    //                             target_buffer.anchor_after(target_start)
-    //                                 ..target_buffer.anchor_before(target_end)
-    //                         })
-    //                     };
-    //                     Location {
-    //                         buffer: target_buffer_handle,
-    //                         range,
-    //                     }
-    //                 }),
-    //                 None => None,
-    //             };
-    //             Ok(location)
-    //         })
-    //     }
+        cx.spawn(move |editor, mut cx| async move {
+            let location_task = editor.update(&mut cx, |editor, cx| {
+                project.update(cx, |project, cx| {
+                    let language_server_name =
+                        editor.buffer.read(cx).as_singleton().and_then(|buffer| {
+                            project
+                                .language_server_for_buffer(buffer.read(cx), server_id, cx)
+                                .map(|(_, lsp_adapter)| {
+                                    LanguageServerName(Arc::from(lsp_adapter.name()))
+                                })
+                        });
+                    language_server_name.map(|language_server_name| {
+                        project.open_local_buffer_via_lsp(
+                            lsp_location.uri.clone(),
+                            server_id,
+                            language_server_name,
+                            cx,
+                        )
+                    })
+                })
+            })?;
+            let location = match location_task {
+                Some(task) => Some({
+                    let target_buffer_handle = task.await.context("open local buffer")?;
+                    let range = target_buffer_handle.update(&mut cx, |target_buffer, _| {
+                        let target_start = target_buffer
+                            .clip_point_utf16(point_from_lsp(lsp_location.range.start), Bias::Left);
+                        let target_end = target_buffer
+                            .clip_point_utf16(point_from_lsp(lsp_location.range.end), Bias::Left);
+                        target_buffer.anchor_after(target_start)
+                            ..target_buffer.anchor_before(target_end)
+                    })?;
+                    Location {
+                        buffer: target_buffer_handle,
+                        range,
+                    }
+                }),
+                None => None,
+            };
+            Ok(location)
+        })
+    }
 
     //     pub fn find_all_references(
     //         workspace: &mut Workspace,

crates/editor2/src/items.rs 🔗

@@ -7,8 +7,9 @@ use anyhow::{anyhow, Context, Result};
 use collections::HashSet;
 use futures::future::try_join_all;
 use gpui::{
-    point, AnyElement, AppContext, AsyncAppContext, Entity, EntityId, FocusHandle, Model, Pixels,
-    SharedString, Subscription, Task, View, ViewContext, VisualContext, WeakView,
+    div, point, AnyElement, AppContext, AsyncAppContext, Entity, EntityId, FocusHandle, Model,
+    ParentElement, Pixels, SharedString, Styled, Subscription, Task, View, ViewContext,
+    VisualContext, WeakView,
 };
 use language::{
     proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, OffsetRangeExt, Point,
@@ -26,7 +27,7 @@ use std::{
     sync::Arc,
 };
 use text::Selection;
-use theme::ThemeVariant;
+use theme::{ActiveTheme, ThemeVariant};
 use util::{paths::PathExt, ResultExt, TryFutureExt};
 use workspace::item::{BreadcrumbText, FollowableItemHandle};
 use workspace::{
@@ -576,25 +577,21 @@ impl Item for Editor {
     }
 
     fn tab_content<T: 'static>(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<T> {
-        AnyElement::new(gpui::ParentElement::child(gpui::div(), "HEY"))
-
-        // Flex::row()
-        //     .with_child(Label::new(self.title(cx).to_string(), style.label.clone()).into_any())
-        //     .with_children(detail.and_then(|detail| {
-        //         let path = path_for_buffer(&self.buffer, detail, false, cx)?;
-        //         let description = path.to_string_lossy();
-        //         Some(
-        //             Label::new(
-        //                 util::truncate_and_trailoff(&description, MAX_TAB_TITLE_LEN),
-        //                 style.description.text.clone(),
-        //             )
-        //             .contained()
-        //             .with_style(style.description.container)
-        //             .aligned(),
-        //         )
-        //     }))
-        //     .align_children_center()
-        //     .into_any()
+        let theme = cx.theme();
+        AnyElement::new(
+            div()
+                .flex()
+                .flex_row()
+                .items_center()
+                .bg(gpui::white())
+                .text_color(gpui::white())
+                .child(self.title(cx).to_string())
+                .children(detail.and_then(|detail| {
+                    let path = path_for_buffer(&self.buffer, detail, false, cx)?;
+                    let description = path.to_string_lossy();
+                    Some(util::truncate_and_trailoff(&description, MAX_TAB_TITLE_LEN))
+                })),
+        )
     }
 
     fn for_each_project_item(
@@ -2,7 +2,8 @@ use crate::{
     display_map::DisplaySnapshot,
     element::PointForPosition,
     hover_popover::{self, InlayHover},
-    Anchor, DisplayPoint, Editor, EditorSnapshot, InlayId, SelectPhase,
+    Anchor, DisplayPoint, Editor, EditorSnapshot, GoToDefinition, GoToTypeDefinition, InlayId,
+    SelectPhase,
 };
 use gpui::{Task, ViewContext};
 use language::{Bias, ToOffset};
@@ -108,61 +109,59 @@ pub fn update_go_to_definition_link(
     shift_held: bool,
     cx: &mut ViewContext<Editor>,
 ) {
-    todo!("old version below");
-}
-//     let pending_nonempty_selection = editor.has_pending_nonempty_selection();
-
-//     // Store new mouse point as an anchor
-//     let snapshot = editor.snapshot(cx);
-//     let trigger_point = match origin {
-//         Some(GoToDefinitionTrigger::Text(p)) => {
-//             Some(TriggerPoint::Text(snapshot.buffer_snapshot.anchor_before(
-//                 p.to_offset(&snapshot.display_snapshot, Bias::Left),
-//             )))
-//         }
-//         Some(GoToDefinitionTrigger::InlayHint(p, lsp_location, language_server_id)) => {
-//             Some(TriggerPoint::InlayHint(p, lsp_location, language_server_id))
-//         }
-//         None => None,
-//     };
-
-//     // If the new point is the same as the previously stored one, return early
-//     if let (Some(a), Some(b)) = (
-//         &trigger_point,
-//         &editor.link_go_to_definition_state.last_trigger_point,
-//     ) {
-//         match (a, b) {
-//             (TriggerPoint::Text(anchor_a), TriggerPoint::Text(anchor_b)) => {
-//                 if anchor_a.cmp(anchor_b, &snapshot.buffer_snapshot).is_eq() {
-//                     return;
-//                 }
-//             }
-//             (TriggerPoint::InlayHint(range_a, _, _), TriggerPoint::InlayHint(range_b, _, _)) => {
-//                 if range_a == range_b {
-//                     return;
-//                 }
-//             }
-//             _ => {}
-//         }
-//     }
+    let pending_nonempty_selection = editor.has_pending_nonempty_selection();
+
+    // Store new mouse point as an anchor
+    let snapshot = editor.snapshot(cx);
+    let trigger_point = match origin {
+        Some(GoToDefinitionTrigger::Text(p)) => {
+            Some(TriggerPoint::Text(snapshot.buffer_snapshot.anchor_before(
+                p.to_offset(&snapshot.display_snapshot, Bias::Left),
+            )))
+        }
+        Some(GoToDefinitionTrigger::InlayHint(p, lsp_location, language_server_id)) => {
+            Some(TriggerPoint::InlayHint(p, lsp_location, language_server_id))
+        }
+        None => None,
+    };
+
+    // If the new point is the same as the previously stored one, return early
+    if let (Some(a), Some(b)) = (
+        &trigger_point,
+        &editor.link_go_to_definition_state.last_trigger_point,
+    ) {
+        match (a, b) {
+            (TriggerPoint::Text(anchor_a), TriggerPoint::Text(anchor_b)) => {
+                if anchor_a.cmp(anchor_b, &snapshot.buffer_snapshot).is_eq() {
+                    return;
+                }
+            }
+            (TriggerPoint::InlayHint(range_a, _, _), TriggerPoint::InlayHint(range_b, _, _)) => {
+                if range_a == range_b {
+                    return;
+                }
+            }
+            _ => {}
+        }
+    }
 
-//     editor.link_go_to_definition_state.last_trigger_point = trigger_point.clone();
+    editor.link_go_to_definition_state.last_trigger_point = trigger_point.clone();
 
-//     if pending_nonempty_selection {
-//         hide_link_definition(editor, cx);
-//         return;
-//     }
+    if pending_nonempty_selection {
+        hide_link_definition(editor, cx);
+        return;
+    }
 
-//     if cmd_held {
-//         if let Some(trigger_point) = trigger_point {
-//             let kind = trigger_point.definition_kind(shift_held);
-//             show_link_definition(kind, editor, trigger_point, snapshot, cx);
-//             return;
-//         }
-//     }
+    if cmd_held {
+        if let Some(trigger_point) = trigger_point {
+            let kind = trigger_point.definition_kind(shift_held);
+            show_link_definition(kind, editor, trigger_point, snapshot, cx);
+            return;
+        }
+    }
 
-//     hide_link_definition(editor, cx);
-// }
+    hide_link_definition(editor, cx);
+}
 
 pub fn update_inlay_link_and_hover_points(
     snapshot: &DisplaySnapshot,
@@ -353,204 +352,202 @@ pub fn show_link_definition(
     snapshot: EditorSnapshot,
     cx: &mut ViewContext<Editor>,
 ) {
-    todo!("old implementation below")
-}
-//     let same_kind = editor.link_go_to_definition_state.kind == Some(definition_kind);
-//     if !same_kind {
-//         hide_link_definition(editor, cx);
-//     }
-
-//     if editor.pending_rename.is_some() {
-//         return;
-//     }
-
-//     let trigger_anchor = trigger_point.anchor();
-//     let (buffer, buffer_position) = if let Some(output) = editor
-//         .buffer
-//         .read(cx)
-//         .text_anchor_for_position(trigger_anchor.clone(), cx)
-//     {
-//         output
-//     } else {
-//         return;
-//     };
-
-//     let excerpt_id = if let Some((excerpt_id, _, _)) = editor
-//         .buffer()
-//         .read(cx)
-//         .excerpt_containing(trigger_anchor.clone(), cx)
-//     {
-//         excerpt_id
-//     } else {
-//         return;
-//     };
+    let same_kind = editor.link_go_to_definition_state.kind == Some(definition_kind);
+    if !same_kind {
+        hide_link_definition(editor, cx);
+    }
 
-//     let project = if let Some(project) = editor.project.clone() {
-//         project
-//     } else {
-//         return;
-//     };
+    if editor.pending_rename.is_some() {
+        return;
+    }
 
-//     // Don't request again if the location is within the symbol region of a previous request with the same kind
-//     if let Some(symbol_range) = &editor.link_go_to_definition_state.symbol_range {
-//         if same_kind && symbol_range.point_within_range(&trigger_point, &snapshot) {
-//             return;
-//         }
-//     }
+    let trigger_anchor = trigger_point.anchor();
+    let (buffer, buffer_position) = if let Some(output) = editor
+        .buffer
+        .read(cx)
+        .text_anchor_for_position(trigger_anchor.clone(), cx)
+    {
+        output
+    } else {
+        return;
+    };
+
+    let excerpt_id = if let Some((excerpt_id, _, _)) = editor
+        .buffer()
+        .read(cx)
+        .excerpt_containing(trigger_anchor.clone(), cx)
+    {
+        excerpt_id
+    } else {
+        return;
+    };
+
+    let project = if let Some(project) = editor.project.clone() {
+        project
+    } else {
+        return;
+    };
+
+    // Don't request again if the location is within the symbol region of a previous request with the same kind
+    if let Some(symbol_range) = &editor.link_go_to_definition_state.symbol_range {
+        if same_kind && symbol_range.point_within_range(&trigger_point, &snapshot) {
+            return;
+        }
+    }
 
-//     let task = cx.spawn(|this, mut cx| {
-//         async move {
-//             let result = match &trigger_point {
-//                 TriggerPoint::Text(_) => {
-//                     // query the LSP for definition info
-//                     cx.update(|cx| {
-//                         project.update(cx, |project, cx| match definition_kind {
-//                             LinkDefinitionKind::Symbol => {
-//                                 project.definition(&buffer, buffer_position, cx)
-//                             }
+    let task = cx.spawn(|this, mut cx| {
+        async move {
+            let result = match &trigger_point {
+                TriggerPoint::Text(_) => {
+                    // query the LSP for definition info
+                    project
+                        .update(&mut cx, |project, cx| match definition_kind {
+                            LinkDefinitionKind::Symbol => {
+                                project.definition(&buffer, buffer_position, cx)
+                            }
+
+                            LinkDefinitionKind::Type => {
+                                project.type_definition(&buffer, buffer_position, cx)
+                            }
+                        })?
+                        .await
+                        .ok()
+                        .map(|definition_result| {
+                            (
+                                definition_result.iter().find_map(|link| {
+                                    link.origin.as_ref().map(|origin| {
+                                        let start = snapshot.buffer_snapshot.anchor_in_excerpt(
+                                            excerpt_id.clone(),
+                                            origin.range.start,
+                                        );
+                                        let end = snapshot.buffer_snapshot.anchor_in_excerpt(
+                                            excerpt_id.clone(),
+                                            origin.range.end,
+                                        );
+                                        RangeInEditor::Text(start..end)
+                                    })
+                                }),
+                                definition_result
+                                    .into_iter()
+                                    .map(GoToDefinitionLink::Text)
+                                    .collect(),
+                            )
+                        })
+                }
+                TriggerPoint::InlayHint(highlight, lsp_location, server_id) => Some((
+                    Some(RangeInEditor::Inlay(highlight.clone())),
+                    vec![GoToDefinitionLink::InlayHint(
+                        lsp_location.clone(),
+                        *server_id,
+                    )],
+                )),
+            };
+
+            this.update(&mut cx, |this, cx| {
+                // Clear any existing highlights
+                this.clear_highlights::<LinkGoToDefinitionState>(cx);
+                this.link_go_to_definition_state.kind = Some(definition_kind);
+                this.link_go_to_definition_state.symbol_range = result
+                    .as_ref()
+                    .and_then(|(symbol_range, _)| symbol_range.clone());
+
+                if let Some((symbol_range, definitions)) = result {
+                    this.link_go_to_definition_state.definitions = definitions.clone();
+
+                    let buffer_snapshot = buffer.read(cx).snapshot();
+
+                    // Only show highlight if there exists a definition to jump to that doesn't contain
+                    // the current location.
+                    let any_definition_does_not_contain_current_location =
+                        definitions.iter().any(|definition| {
+                            match &definition {
+                                GoToDefinitionLink::Text(link) => {
+                                    if link.target.buffer == buffer {
+                                        let range = &link.target.range;
+                                        // Expand range by one character as lsp definition ranges include positions adjacent
+                                        // but not contained by the symbol range
+                                        let start = buffer_snapshot.clip_offset(
+                                            range
+                                                .start
+                                                .to_offset(&buffer_snapshot)
+                                                .saturating_sub(1),
+                                            Bias::Left,
+                                        );
+                                        let end = buffer_snapshot.clip_offset(
+                                            range.end.to_offset(&buffer_snapshot) + 1,
+                                            Bias::Right,
+                                        );
+                                        let offset = buffer_position.to_offset(&buffer_snapshot);
+                                        !(start <= offset && end >= offset)
+                                    } else {
+                                        true
+                                    }
+                                }
+                                GoToDefinitionLink::InlayHint(_, _) => true,
+                            }
+                        });
+
+                    if any_definition_does_not_contain_current_location {
+                        // todo!()
+                        // // Highlight symbol using theme link definition highlight style
+                        // let style = theme::current(cx).editor.link_definition;
+                        // let highlight_range =
+                        //     symbol_range.unwrap_or_else(|| match &trigger_point {
+                        //         TriggerPoint::Text(trigger_anchor) => {
+                        //             let snapshot = &snapshot.buffer_snapshot;
+                        //             // If no symbol range returned from language server, use the surrounding word.
+                        //             let (offset_range, _) =
+                        //                 snapshot.surrounding_word(*trigger_anchor);
+                        //             RangeInEditor::Text(
+                        //                 snapshot.anchor_before(offset_range.start)
+                        //                     ..snapshot.anchor_after(offset_range.end),
+                        //             )
+                        //         }
+                        //         TriggerPoint::InlayHint(highlight, _, _) => {
+                        //             RangeInEditor::Inlay(highlight.clone())
+                        //         }
+                        //     });
+
+                        // match highlight_range {
+                        //     RangeInEditor::Text(text_range) => this
+                        //         .highlight_text::<LinkGoToDefinitionState>(
+                        //             vec![text_range],
+                        //             style,
+                        //             cx,
+                        //         ),
+                        //     RangeInEditor::Inlay(highlight) => this
+                        //         .highlight_inlays::<LinkGoToDefinitionState>(
+                        //             vec![highlight],
+                        //             style,
+                        //             cx,
+                        //         ),
+                        // }
+                    } else {
+                        hide_link_definition(this, cx);
+                    }
+                }
+            })?;
 
-//                             LinkDefinitionKind::Type => {
-//                                 project.type_definition(&buffer, buffer_position, cx)
-//                             }
-//                         })
-//                     })
-//                     .await
-//                     .ok()
-//                     .map(|definition_result| {
-//                         (
-//                             definition_result.iter().find_map(|link| {
-//                                 link.origin.as_ref().map(|origin| {
-//                                     let start = snapshot
-//                                         .buffer_snapshot
-//                                         .anchor_in_excerpt(excerpt_id.clone(), origin.range.start);
-//                                     let end = snapshot
-//                                         .buffer_snapshot
-//                                         .anchor_in_excerpt(excerpt_id.clone(), origin.range.end);
-//                                     RangeInEditor::Text(start..end)
-//                                 })
-//                             }),
-//                             definition_result
-//                                 .into_iter()
-//                                 .map(GoToDefinitionLink::Text)
-//                                 .collect(),
-//                         )
-//                     })
-//                 }
-//                 TriggerPoint::InlayHint(highlight, lsp_location, server_id) => Some((
-//                     Some(RangeInEditor::Inlay(highlight.clone())),
-//                     vec![GoToDefinitionLink::InlayHint(
-//                         lsp_location.clone(),
-//                         *server_id,
-//                     )],
-//                 )),
-//             };
+            Ok::<_, anyhow::Error>(())
+        }
+        .log_err()
+    });
 
-//             this.update(&mut cx, |this, cx| {
-//                 // Clear any existing highlights
-//                 this.clear_highlights::<LinkGoToDefinitionState>(cx);
-//                 this.link_go_to_definition_state.kind = Some(definition_kind);
-//                 this.link_go_to_definition_state.symbol_range = result
-//                     .as_ref()
-//                     .and_then(|(symbol_range, _)| symbol_range.clone());
-
-//                 if let Some((symbol_range, definitions)) = result {
-//                     this.link_go_to_definition_state.definitions = definitions.clone();
-
-//                     let buffer_snapshot = buffer.read(cx).snapshot();
-
-//                     // Only show highlight if there exists a definition to jump to that doesn't contain
-//                     // the current location.
-//                     let any_definition_does_not_contain_current_location =
-//                         definitions.iter().any(|definition| {
-//                             match &definition {
-//                                 GoToDefinitionLink::Text(link) => {
-//                                     if link.target.buffer == buffer {
-//                                         let range = &link.target.range;
-//                                         // Expand range by one character as lsp definition ranges include positions adjacent
-//                                         // but not contained by the symbol range
-//                                         let start = buffer_snapshot.clip_offset(
-//                                             range
-//                                                 .start
-//                                                 .to_offset(&buffer_snapshot)
-//                                                 .saturating_sub(1),
-//                                             Bias::Left,
-//                                         );
-//                                         let end = buffer_snapshot.clip_offset(
-//                                             range.end.to_offset(&buffer_snapshot) + 1,
-//                                             Bias::Right,
-//                                         );
-//                                         let offset = buffer_position.to_offset(&buffer_snapshot);
-//                                         !(start <= offset && end >= offset)
-//                                     } else {
-//                                         true
-//                                     }
-//                                 }
-//                                 GoToDefinitionLink::InlayHint(_, _) => true,
-//                             }
-//                         });
-
-//                     if any_definition_does_not_contain_current_location {
-//                         // todo!()
-//                         // // Highlight symbol using theme link definition highlight style
-//                         // let style = theme::current(cx).editor.link_definition;
-//                         // let highlight_range =
-//                         //     symbol_range.unwrap_or_else(|| match &trigger_point {
-//                         //         TriggerPoint::Text(trigger_anchor) => {
-//                         //             let snapshot = &snapshot.buffer_snapshot;
-//                         //             // If no symbol range returned from language server, use the surrounding word.
-//                         //             let (offset_range, _) =
-//                         //                 snapshot.surrounding_word(*trigger_anchor);
-//                         //             RangeInEditor::Text(
-//                         //                 snapshot.anchor_before(offset_range.start)
-//                         //                     ..snapshot.anchor_after(offset_range.end),
-//                         //             )
-//                         //         }
-//                         //         TriggerPoint::InlayHint(highlight, _, _) => {
-//                         //             RangeInEditor::Inlay(highlight.clone())
-//                         //         }
-//                         //     });
-
-//                         // match highlight_range {
-//                         //     RangeInEditor::Text(text_range) => this
-//                         //         .highlight_text::<LinkGoToDefinitionState>(
-//                         //             vec![text_range],
-//                         //             style,
-//                         //             cx,
-//                         //         ),
-//                         //     RangeInEditor::Inlay(highlight) => this
-//                         //         .highlight_inlays::<LinkGoToDefinitionState>(
-//                         //             vec![highlight],
-//                         //             style,
-//                         //             cx,
-//                         //         ),
-//                         // }
-//                     } else {
-//                         hide_link_definition(this, cx);
-//                     }
-//                 }
-//             })?;
+    editor.link_go_to_definition_state.task = Some(task);
+}
 
-//             Ok::<_, anyhow::Error>(())
-//         }
-//         .log_err()
-//     });
+pub fn hide_link_definition(editor: &mut Editor, cx: &mut ViewContext<Editor>) {
+    if editor.link_go_to_definition_state.symbol_range.is_some()
+        || !editor.link_go_to_definition_state.definitions.is_empty()
+    {
+        editor.link_go_to_definition_state.symbol_range.take();
+        editor.link_go_to_definition_state.definitions.clear();
+        cx.notify();
+    }
 
-//     editor.link_go_to_definition_state.task = Some(task);
-// }
+    editor.link_go_to_definition_state.task = None;
 
-pub fn hide_link_definition(editor: &mut Editor, cx: &mut ViewContext<Editor>) {
-    todo!()
-    // if editor.link_go_to_definition_state.symbol_range.is_some()
-    //     || !editor.link_go_to_definition_state.definitions.is_empty()
-    // {
-    //     editor.link_go_to_definition_state.symbol_range.take();
-    //     editor.link_go_to_definition_state.definitions.clear();
-    //     cx.notify();
-    // }
-
-    // editor.link_go_to_definition_state.task = None;
-
-    // editor.clear_highlights::<LinkGoToDefinitionState>(cx);
+    editor.clear_highlights::<LinkGoToDefinitionState>(cx);
 }
 
 pub fn go_to_fetched_definition(
@@ -578,35 +575,34 @@ fn go_to_fetched_definition_of_kind(
     split: bool,
     cx: &mut ViewContext<Editor>,
 ) {
-    todo!();
-    // let cached_definitions = editor.link_go_to_definition_state.definitions.clone();
-    // hide_link_definition(editor, cx);
-    // let cached_definitions_kind = editor.link_go_to_definition_state.kind;
-
-    // let is_correct_kind = cached_definitions_kind == Some(kind);
-    // if !cached_definitions.is_empty() && is_correct_kind {
-    //     if !editor.focused {
-    //         cx.focus_self();
-    //     }
-
-    //     editor.navigate_to_definitions(cached_definitions, split, cx);
-    // } else {
-    //     editor.select(
-    //         SelectPhase::Begin {
-    //             position: point.next_valid,
-    //             add: false,
-    //             click_count: 1,
-    //         },
-    //         cx,
-    //     );
-
-    //     if point.as_valid().is_some() {
-    //         match kind {
-    //             LinkDefinitionKind::Symbol => editor.go_to_definition(&Default::default(), cx),
-    //             LinkDefinitionKind::Type => editor.go_to_type_definition(&Default::default(), cx),
-    //         }
-    //     }
-    // }
+    let cached_definitions = editor.link_go_to_definition_state.definitions.clone();
+    hide_link_definition(editor, cx);
+    let cached_definitions_kind = editor.link_go_to_definition_state.kind;
+
+    let is_correct_kind = cached_definitions_kind == Some(kind);
+    if !cached_definitions.is_empty() && is_correct_kind {
+        if !editor.focused {
+            cx.focus(&editor.focus_handle);
+        }
+
+        editor.navigate_to_definitions(cached_definitions, split, cx);
+    } else {
+        editor.select(
+            SelectPhase::Begin {
+                position: point.next_valid,
+                add: false,
+                click_count: 1,
+            },
+            cx,
+        );
+
+        if point.as_valid().is_some() {
+            match kind {
+                LinkDefinitionKind::Symbol => editor.go_to_definition(&GoToDefinition, cx),
+                LinkDefinitionKind::Type => editor.go_to_type_definition(&GoToTypeDefinition, cx),
+            }
+        }
+    }
 }
 
 // #[cfg(test)]

crates/editor2/src/scroll.rs 🔗

@@ -346,8 +346,7 @@ impl Editor {
             cx,
         );
 
-        // todo!()
-        // self.refresh_inlay_hints(InlayHintRefreshReason::NewLinesShown, cx);
+        self.refresh_inlay_hints(InlayHintRefreshReason::NewLinesShown, cx);
     }
 
     //     pub fn scroll_position(&self, cx: &mut ViewContext<Self>) -> gpui::Point<Pixels> {

crates/workspace2/src/pane.rs 🔗

@@ -639,19 +639,19 @@ impl Pane {
     //             .pixel_position_of_cursor(cx)
     //     }
 
-    //     pub fn item_for_entry(
-    //         &self,
-    //         entry_id: ProjectEntryId,
-    //         cx: &AppContext,
-    //     ) -> Option<Box<dyn ItemHandle>> {
-    //         self.items.iter().find_map(|item| {
-    //             if item.is_singleton(cx) && item.project_entry_ids(cx).as_slice() == [entry_id] {
-    //                 Some(item.boxed_clone())
-    //             } else {
-    //                 None
-    //             }
-    //         })
-    //     }
+    pub fn item_for_entry(
+        &self,
+        entry_id: ProjectEntryId,
+        cx: &AppContext,
+    ) -> Option<Box<dyn ItemHandle>> {
+        self.items.iter().find_map(|item| {
+            if item.is_singleton(cx) && item.project_entry_ids(cx).as_slice() == [entry_id] {
+                Some(item.boxed_clone())
+            } else {
+                None
+            }
+        })
+    }
 
     pub fn index_for_item(&self, item: &dyn ItemHandle) -> Option<usize> {
         self.items.iter().position(|i| i.id() == item.id())

crates/workspace2/src/workspace2.rs 🔗

@@ -1999,22 +1999,22 @@ impl Workspace {
     //         }
     //     }
 
-    //     pub fn add_item(&mut self, item: Box<dyn ItemHandle>, cx: &mut ViewContext<Self>) {
-    //         self.active_pane
-    //             .update(cx, |pane, cx| pane.add_item(item, true, true, None, cx));
-    //     }
+    pub fn add_item(&mut self, item: Box<dyn ItemHandle>, cx: &mut ViewContext<Self>) {
+        self.active_pane
+            .update(cx, |pane, cx| pane.add_item(item, true, true, None, cx));
+    }
 
-    //     pub fn split_item(
-    //         &mut self,
-    //         split_direction: SplitDirection,
-    //         item: Box<dyn ItemHandle>,
-    //         cx: &mut ViewContext<Self>,
-    //     ) {
-    //         let new_pane = self.split_pane(self.active_pane.clone(), split_direction, cx);
-    //         new_pane.update(cx, move |new_pane, cx| {
-    //             new_pane.add_item(item, true, true, None, cx)
-    //         })
-    //     }
+    pub fn split_item(
+        &mut self,
+        split_direction: SplitDirection,
+        item: Box<dyn ItemHandle>,
+        cx: &mut ViewContext<Self>,
+    ) {
+        let new_pane = self.split_pane(self.active_pane.clone(), split_direction, cx);
+        new_pane.update(cx, move |new_pane, cx| {
+            new_pane.add_item(item, true, true, None, cx)
+        })
+    }
 
     //     pub fn open_abs_path(
     //         &mut self,
@@ -2144,53 +2144,55 @@ impl Workspace {
         })
     }
 
-    //     pub fn open_project_item<T>(
-    //         &mut self,
-    //         project_item: ModelHandle<T::Item>,
-    //         cx: &mut ViewContext<Self>,
-    //     ) -> View<T>
-    //     where
-    //         T: ProjectItem,
-    //     {
-    //         use project::Item as _;
+    pub fn open_project_item<T>(
+        &mut self,
+        project_item: Model<T::Item>,
+        cx: &mut ViewContext<Self>,
+    ) -> View<T>
+    where
+        T: ProjectItem,
+    {
+        use project2::Item as _;
 
-    //         let entry_id = project_item.read(cx).entry_id(cx);
-    //         if let Some(item) = entry_id
-    //             .and_then(|entry_id| self.active_pane().read(cx).item_for_entry(entry_id, cx))
-    //             .and_then(|item| item.downcast())
-    //         {
-    //             self.activate_item(&item, cx);
-    //             return item;
-    //         }
+        let entry_id = project_item.read(cx).entry_id(cx);
+        if let Some(item) = entry_id
+            .and_then(|entry_id| self.active_pane().read(cx).item_for_entry(entry_id, cx))
+            .and_then(|item| item.downcast())
+        {
+            self.activate_item(&item, cx);
+            return item;
+        }
 
-    //         let item = cx.build_view(|cx| T::for_project_item(self.project().clone(), project_item, cx));
-    //         self.add_item(Box::new(item.clone()), cx);
-    //         item
-    //     }
+        let item =
+            cx.build_view(|cx| T::for_project_item(self.project().clone(), project_item, cx));
+        self.add_item(Box::new(item.clone()), cx);
+        item
+    }
 
-    //     pub fn split_project_item<T>(
-    //         &mut self,
-    //         project_item: ModelHandle<T::Item>,
-    //         cx: &mut ViewContext<Self>,
-    //     ) -> View<T>
-    //     where
-    //         T: ProjectItem,
-    //     {
-    //         use project::Item as _;
+    pub fn split_project_item<T>(
+        &mut self,
+        project_item: Model<T::Item>,
+        cx: &mut ViewContext<Self>,
+    ) -> View<T>
+    where
+        T: ProjectItem,
+    {
+        use project2::Item as _;
 
-    //         let entry_id = project_item.read(cx).entry_id(cx);
-    //         if let Some(item) = entry_id
-    //             .and_then(|entry_id| self.active_pane().read(cx).item_for_entry(entry_id, cx))
-    //             .and_then(|item| item.downcast())
-    //         {
-    //             self.activate_item(&item, cx);
-    //             return item;
-    //         }
+        let entry_id = project_item.read(cx).entry_id(cx);
+        if let Some(item) = entry_id
+            .and_then(|entry_id| self.active_pane().read(cx).item_for_entry(entry_id, cx))
+            .and_then(|item| item.downcast())
+        {
+            self.activate_item(&item, cx);
+            return item;
+        }
 
-    //         let item = cx.build_view(|cx| T::for_project_item(self.project().clone(), project_item, cx));
-    //         self.split_item(SplitDirection::Right, Box::new(item.clone()), cx);
-    //         item
-    //     }
+        let item =
+            cx.build_view(|cx| T::for_project_item(self.project().clone(), project_item, cx));
+        self.split_item(SplitDirection::Right, Box::new(item.clone()), cx);
+        item
+    }
 
     //     pub fn open_shared_screen(&mut self, peer_id: PeerId, cx: &mut ViewContext<Self>) {
     //         if let Some(shared_screen) = self.shared_screen_for_peer(peer_id, &self.active_pane, cx) {
@@ -2200,19 +2202,19 @@ impl Workspace {
     //         }
     //     }
 
-    //     pub fn activate_item(&mut self, item: &dyn ItemHandle, cx: &mut ViewContext<Self>) -> bool {
-    //         let result = self.panes.iter().find_map(|pane| {
-    //             pane.read(cx)
-    //                 .index_for_item(item)
-    //                 .map(|ix| (pane.clone(), ix))
-    //         });
-    //         if let Some((pane, ix)) = result {
-    //             pane.update(cx, |pane, cx| pane.activate_item(ix, true, true, cx));
-    //             true
-    //         } else {
-    //             false
-    //         }
-    //     }
+    pub fn activate_item(&mut self, item: &dyn ItemHandle, cx: &mut ViewContext<Self>) -> bool {
+        let result = self.panes.iter().find_map(|pane| {
+            pane.read(cx)
+                .index_for_item(item)
+                .map(|ix| (pane.clone(), ix))
+        });
+        if let Some((pane, ix)) = result {
+            pane.update(cx, |pane, cx| pane.activate_item(ix, true, true, cx));
+            true
+        } else {
+            false
+        }
+    }
 
     //     fn activate_pane_at_index(&mut self, action: &ActivatePane, cx: &mut ViewContext<Self>) {
     //         let panes = self.center.panes();