Get editor2 compiling with a ton of code commented out

This commit is contained in:
Nathan Sobo 2023-11-02 23:35:20 -06:00
parent f3b8a9d8c2
commit fbee6b5352
12 changed files with 582 additions and 552 deletions

View file

@ -241,7 +241,7 @@ impl DisplayMap {
pub fn set_font(&self, font: Font, font_size: Pixels, cx: &mut ModelContext<Self>) -> bool { pub fn set_font(&self, font: Font, font_size: Pixels, cx: &mut ModelContext<Self>) -> bool {
self.wrap_map self.wrap_map
.update(cx, |map, cx| map.set_font(font, font_size, cx)) .update(cx, |map, cx| map.set_font_with_size(font, font_size, cx))
} }
pub fn set_fold_ellipses_color(&mut self, color: Hsla) -> bool { pub fn set_fold_ellipses_color(&mut self, color: Hsla) -> bool {
@ -1388,7 +1388,7 @@ pub fn next_rows(display_row: u32, display_map: &DisplaySnapshot) -> impl Iterat
// ); // );
// // Re-wrap on font size changes // // Re-wrap on font size changes
// map.update(cx, |map, cx| map.set_font(font_id, font_size + 3., cx)); // map.update(cx, |map, cx| map.set_font_with_size(font_id, font_size + 3., cx));
// let snapshot = map.update(cx, |map, cx| map.snapshot(cx)); // let snapshot = map.update(cx, |map, cx| map.snapshot(cx));
// assert_eq!( // assert_eq!(

View file

@ -1629,7 +1629,8 @@ mod tests {
} }
fn init_test(cx: &mut gpui::AppContext) { fn init_test(cx: &mut gpui::AppContext) {
cx.set_global(SettingsStore::test(cx)); let store = SettingsStore::test(cx);
cx.set_global(store);
} }
impl FoldMap { impl FoldMap {

View file

@ -1889,7 +1889,8 @@ mod tests {
} }
fn init_test(cx: &mut AppContext) { fn init_test(cx: &mut AppContext) {
cx.set_global(SettingsStore::test(cx)); let store = SettingsStore::test(cx);
cx.set_global(store);
theme::init(cx); theme::init(cx);
} }
} }

View file

@ -23,7 +23,7 @@ pub struct WrapMap {
edits_since_sync: Patch<u32>, edits_since_sync: Patch<u32>,
wrap_width: Option<Pixels>, wrap_width: Option<Pixels>,
background_task: Option<Task<()>>, background_task: Option<Task<()>>,
font: (Font, Pixels), font_with_size: (Font, Pixels),
} }
#[derive(Clone)] #[derive(Clone)]
@ -76,7 +76,7 @@ impl WrapMap {
) -> (Model<Self>, WrapSnapshot) { ) -> (Model<Self>, WrapSnapshot) {
let handle = cx.build_model(|cx| { let handle = cx.build_model(|cx| {
let mut this = Self { let mut this = Self {
font: (font, font_size), font_with_size: (font, font_size),
wrap_width: None, wrap_width: None,
pending_edits: Default::default(), pending_edits: Default::default(),
interpolated_edits: Default::default(), interpolated_edits: Default::default(),
@ -116,9 +116,16 @@ impl WrapMap {
(self.snapshot.clone(), mem::take(&mut self.edits_since_sync)) (self.snapshot.clone(), mem::take(&mut self.edits_since_sync))
} }
pub fn set_font(&mut self, font: Font, font_size: Pixels, cx: &mut ModelContext<Self>) -> bool { pub fn set_font_with_size(
if (font, font_size) != self.font { &mut self,
self.font = (font, font_size); font: Font,
font_size: Pixels,
cx: &mut ModelContext<Self>,
) -> bool {
let font_with_size = (font, font_size);
if font_with_size != self.font_with_size {
self.font_with_size = font_with_size;
self.rewrap(cx); self.rewrap(cx);
true true
} else { } else {
@ -149,10 +156,9 @@ impl WrapMap {
let mut new_snapshot = self.snapshot.clone(); let mut new_snapshot = self.snapshot.clone();
let mut edits = Patch::default(); let mut edits = Patch::default();
let text_system = cx.text_system().clone(); let text_system = cx.text_system().clone();
let (font_id, font_size) = self.font; let (font, font_size) = self.font_with_size.clone();
let task = cx.background_executor().spawn(async move { let task = cx.background_executor().spawn(async move {
if let Some(mut line_wrapper) = if let Some(mut line_wrapper) = text_system.line_wrapper(font, font_size).log_err()
text_system.line_wrapper(font_id, font_size).log_err()
{ {
let tab_snapshot = new_snapshot.tab_snapshot.clone(); let tab_snapshot = new_snapshot.tab_snapshot.clone();
let range = TabPoint::zero()..tab_snapshot.max_point(); let range = TabPoint::zero()..tab_snapshot.max_point();
@ -236,11 +242,11 @@ impl WrapMap {
let pending_edits = self.pending_edits.clone(); let pending_edits = self.pending_edits.clone();
let mut snapshot = self.snapshot.clone(); let mut snapshot = self.snapshot.clone();
let text_system = cx.text_system().clone(); let text_system = cx.text_system().clone();
let (font_id, font_size) = self.font; let (font, font_size) = self.font_with_size.clone();
let update_task = cx.background_executor().spawn(async move { let update_task = cx.background_executor().spawn(async move {
let mut edits = Patch::default(); let mut edits = Patch::default();
if let Some(mut line_wrapper) = if let Some(mut line_wrapper) =
text_system.line_wrapper(font_id, font_size).log_err() text_system.line_wrapper(font, font_size).log_err()
{ {
for (tab_snapshot, tab_edits) in pending_edits { for (tab_snapshot, tab_edits) in pending_edits {
let wrap_edits = snapshot let wrap_edits = snapshot

View file

@ -35,8 +35,8 @@ pub use element::{
use futures::FutureExt; use futures::FutureExt;
use fuzzy::{StringMatch, StringMatchCandidate}; use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{ use gpui::{
AnyElement, AppContext, BackgroundExecutor, Element, EventEmitter, Model, Pixels, Render, AnyElement, AppContext, BackgroundExecutor, Context, Element, EventEmitter, Model, Pixels,
Subscription, Task, TextStyle, View, ViewContext, WeakView, WindowContext, Render, Subscription, Task, TextStyle, View, ViewContext, WeakView, WindowContext,
}; };
use hover_popover::HoverState; use hover_popover::HoverState;
pub use items::MAX_TAB_TITLE_LEN; pub use items::MAX_TAB_TITLE_LEN;
@ -64,7 +64,7 @@ use std::{
cmp::Reverse, cmp::Reverse,
ops::{Deref, DerefMut, Range}, ops::{Deref, DerefMut, Range},
sync::Arc, sync::Arc,
time::Duration, time::{Duration, Instant},
}; };
pub use sum_tree::Bias; pub use sum_tree::Bias;
use util::{ResultExt, TryFutureExt}; use util::{ResultExt, TryFutureExt};
@ -1810,14 +1810,14 @@ impl Editor {
// ) // )
// } // }
// pub fn for_buffer( pub fn for_buffer(
// buffer: Model<Buffer>, buffer: Model<Buffer>,
// project: Option<Model<Project>>, project: Option<Model<Project>>,
// cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
// ) -> Self { ) -> Self {
// let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
// Self::new(EditorMode::Full, buffer, project, None, cx) Self::new(EditorMode::Full, buffer, project, cx)
// } }
// pub fn for_multibuffer( // pub fn for_multibuffer(
// buffer: Model<MultiBuffer>, // buffer: Model<MultiBuffer>,
@ -1827,33 +1827,37 @@ impl Editor {
// Self::new(EditorMode::Full, buffer, project, None, cx) // Self::new(EditorMode::Full, buffer, project, None, cx)
// } // }
// pub fn clone(&self, cx: &mut ViewContext<Self>) -> Self { pub fn clone(&self, cx: &mut ViewContext<Self>) -> Self {
// let mut clone = Self::new( let mut clone = Self::new(
// self.mode, self.mode,
// self.buffer.clone(), self.buffer.clone(),
// self.project.clone(), self.project.clone(),
// todo!
// self.get_field_editor_theme.clone(), // self.get_field_editor_theme.clone(),
// cx, cx,
// ); );
// self.display_map.update(cx, |display_map, cx| { self.display_map.update(cx, |display_map, cx| {
// let snapshot = display_map.snapshot(cx); let snapshot = display_map.snapshot(cx);
// clone.display_map.update(cx, |display_map, cx| { clone.display_map.update(cx, |display_map, cx| {
// display_map.set_state(&snapshot, cx); display_map.set_state(&snapshot, cx);
// }); });
// }); });
// clone.selections.clone_state(&self.selections); clone.selections.clone_state(&self.selections);
// clone.scroll_manager.clone_state(&self.scroll_manager); clone.scroll_manager.clone_state(&self.scroll_manager);
// clone.searchable = self.searchable; clone.searchable = self.searchable;
// clone clone
// } }
// fn new( fn new(
// mode: EditorMode, mode: EditorMode,
// buffer: Model<MultiBuffer>, buffer: Model<MultiBuffer>,
// project: Option<Model<Project>>, project: Option<Model<Project>>,
// todo!()
// get_field_editor_theme: Option<Arc<GetFieldEditorTheme>>, // get_field_editor_theme: Option<Arc<GetFieldEditorTheme>>,
// cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
// ) -> Self { ) -> Self {
todo!("old version below")
}
// let editor_view_id = cx.view_id(); // let editor_view_id = cx.view_id();
// let display_map = cx.add_model(|cx| { // let display_map = cx.add_model(|cx| {
// let settings = settings::get::<ThemeSettings>(cx); // let settings = settings::get::<ThemeSettings>(cx);
@ -2316,19 +2320,19 @@ impl Editor {
// result // result
// } // }
// pub fn edit<I, S, T>(&mut self, edits: I, cx: &mut ViewContext<Self>) pub fn edit<I, S, T>(&mut self, edits: I, cx: &mut ViewContext<Self>)
// where where
// I: IntoIterator<Item = (Range<S>, T)>, I: IntoIterator<Item = (Range<S>, T)>,
// S: ToOffset, S: ToOffset,
// T: Into<Arc<str>>, T: Into<Arc<str>>,
// { {
// if self.read_only { if self.read_only {
// return; return;
// } }
// self.buffer self.buffer
// .update(cx, |buffer, cx| buffer.edit(edits, None, cx)); .update(cx, |buffer, cx| buffer.edit(edits, None, cx));
// } }
// pub fn edit_with_autoindent<I, S, T>(&mut self, edits: I, cx: &mut ViewContext<Self>) // pub fn edit_with_autoindent<I, S, T>(&mut self, edits: I, cx: &mut ViewContext<Self>)
// where // where
@ -8058,17 +8062,18 @@ impl Editor {
// }); // });
// } // }
// pub fn transact( pub fn transact(
// &mut self, &mut self,
// cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
// update: impl FnOnce(&mut Self, &mut ViewContext<Self>), update: impl FnOnce(&mut Self, &mut ViewContext<Self>),
// ) -> Option<TransactionId> { ) -> Option<TransactionId> {
// self.start_transaction_at(Instant::now(), cx); self.start_transaction_at(Instant::now(), cx);
// update(self, cx); update(self, cx);
// self.end_transaction_at(Instant::now(), cx) self.end_transaction_at(Instant::now(), cx)
// } }
// fn start_transaction_at(&mut self, now: Instant, cx: &mut ViewContext<Self>) { fn start_transaction_at(&mut self, now: Instant, cx: &mut ViewContext<Self>) {
todo!()
// self.end_selection(cx); // self.end_selection(cx);
// if let Some(tx_id) = self // if let Some(tx_id) = self
// .buffer // .buffer
@ -8077,13 +8082,14 @@ impl Editor {
// self.selection_history // self.selection_history
// .insert_transaction(tx_id, self.selections.disjoint_anchors()); // .insert_transaction(tx_id, self.selections.disjoint_anchors());
// } // }
// } }
// fn end_transaction_at( fn end_transaction_at(
// &mut self, &mut self,
// now: Instant, now: Instant,
// cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
// ) -> Option<TransactionId> { ) -> Option<TransactionId> {
todo!()
// if let Some(tx_id) = self // if let Some(tx_id) = self
// .buffer // .buffer
// .update(cx, |buffer, cx| buffer.end_transaction_at(now, cx)) // .update(cx, |buffer, cx| buffer.end_transaction_at(now, cx))
@ -8099,7 +8105,7 @@ impl Editor {
// } else { // } else {
// None // None
// } // }
// } }
// pub fn fold(&mut self, _: &Fold, cx: &mut ViewContext<Self>) { // pub fn fold(&mut self, _: &Fold, cx: &mut ViewContext<Self>) {
// let mut fold_ranges = Vec::new(); // let mut fold_ranges = Vec::new();
@ -9304,7 +9310,7 @@ impl Render for Editor {
// let style = self.style(cx); // let style = self.style(cx);
// let font_changed = self.display_map.update(cx, |map, cx| { // let font_changed = self.display_map.update(cx, |map, cx| {
// map.set_fold_ellipses_color(style.folds.ellipses.text_color); // map.set_fold_ellipses_color(style.folds.ellipses.text_color);
// map.set_font(style.text.font_id, style.text.font_size, cx) // map.set_font_with_size(style.text.font_id, style.text.font_size, cx)
// }); // });
// if font_changed { // if font_changed {

View file

@ -2704,10 +2704,11 @@ impl PositionMap {
let y = position.y.max(px(0.)).min(self.size.width); let y = position.y.max(px(0.)).min(self.size.width);
let x = position.x + (scroll_position.x * self.em_width); let x = position.x + (scroll_position.x * self.em_width);
let row = (f32::from(y / self.line_height) + scroll_position.y) as u32; let row = (f32::from(y / self.line_height) + scroll_position.y) as u32;
let (column, x_overshoot_after_line_end) = if let Some(line) = self let (column, x_overshoot_after_line_end) = if let Some(line) = self
.line_layouts .line_layouts
.get(row as usize - scroll_position.y.into()) .get(row as usize - scroll_position.y as usize)
.map(|LineWithInvisibles { line, .. }| line) .map(|&LineWithInvisibles { ref line, .. }| line)
{ {
if let Some(ix) = line.index_for_x(x) { if let Some(ix) = line.index_for_x(x) {
(ix as u32, px(0.)) (ix as u32, px(0.))

View file

@ -3,12 +3,12 @@ use crate::{
movement::surrounding_word, persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor, movement::surrounding_word, persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor,
Event, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, NavigationData, ToPoint as _, Event, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, NavigationData, ToPoint as _,
}; };
use anyhow::{Context, Result}; use anyhow::{anyhow, Context, Result};
use collections::HashSet; use collections::HashSet;
use futures::future::try_join_all; use futures::future::try_join_all;
use gpui::{ use gpui::{
point, AnyElement, AppContext, AsyncAppContext, Entity, EntityId, Model, Pixels, SharedString, point, AnyElement, AppContext, AsyncAppContext, Entity, EntityId, Model, Pixels, SharedString,
Subscription, Task, View, ViewContext, WeakView, Subscription, Task, View, ViewContext, VisualContext, WeakView,
}; };
use language::{ use language::{
proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, OffsetRangeExt, Point, proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, OffsetRangeExt, Point,
@ -566,11 +566,9 @@ impl Item for Editor {
Some(file_path.into()) Some(file_path.into())
} }
fn tab_description<'a>(&'a self, detail: usize, cx: &'a AppContext) -> Option<SharedString> { fn tab_description<'a>(&self, detail: usize, cx: &'a AppContext) -> Option<SharedString> {
match path_for_buffer(&self.buffer, detail, true, cx)? { let path = path_for_buffer(&self.buffer, detail, true, cx)?;
Cow::Borrowed(path) => Some(path.to_string_lossy().into()), Some(path.to_string_lossy().to_string().into())
Cow::Owned(path) => Some(path.to_string_lossy().to_string().into()),
}
} }
fn tab_content<T: 'static>(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<T> { fn tab_content<T: 'static>(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<T> {
@ -613,11 +611,11 @@ impl Item for Editor {
&self, &self,
_workspace_id: WorkspaceId, _workspace_id: WorkspaceId,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> Option<View<Self>> ) -> Option<View<Editor>>
where where
Self: Sized, Self: Sized,
{ {
Some(self.clone()) Some(cx.build_view(|cx| self.clone(cx)))
} }
fn set_nav_history(&mut self, history: ItemNavHistory, _: &mut ViewContext<Self>) { fn set_nav_history(&mut self, history: ItemNavHistory, _: &mut ViewContext<Self>) {
@ -706,7 +704,9 @@ impl Item for Editor {
.as_singleton() .as_singleton()
.expect("cannot call save_as on an excerpt list"); .expect("cannot call save_as on an excerpt list");
let file_extension = abs_path.extension().map(|a| a.to_string_lossy.to_string()); let file_extension = abs_path
.extension()
.map(|a| a.to_string_lossy().to_string());
self.report_editor_event("save", file_extension, cx); self.report_editor_event("save", file_extension, cx);
project.update(cx, |project, cx| { project.update(cx, |project, cx| {
@ -807,7 +807,7 @@ impl Item for Editor {
fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) { fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
let workspace_id = workspace.database_id(); let workspace_id = workspace.database_id();
let item_id = cx.view_id(); let item_id = cx.view().entity_id().as_u64() as ItemId;
self.workspace = Some((workspace.weak_handle(), workspace.database_id())); self.workspace = Some((workspace.weak_handle(), workspace.database_id()));
fn serialize( fn serialize(
@ -835,7 +835,12 @@ impl Item for Editor {
cx.subscribe(&buffer, |this, buffer, event, cx| { cx.subscribe(&buffer, |this, buffer, event, cx| {
if let Some((_, workspace_id)) = this.workspace.as_ref() { if let Some((_, workspace_id)) = this.workspace.as_ref() {
if let language::Event::FileHandleChanged = event { if let language::Event::FileHandleChanged = event {
serialize(buffer, *workspace_id, cx.view_id(), cx); serialize(
buffer,
*workspace_id,
cx.view().entity_id().as_u64() as ItemId,
cx,
);
} }
} }
}) })
@ -877,10 +882,11 @@ impl Item for Editor {
let (_, project_item) = project_item.await?; let (_, project_item) = project_item.await?;
let buffer = project_item let buffer = project_item
.downcast::<Buffer>() .downcast::<Buffer>()
.context("Project item at stored path was not a buffer")?; .map_err(|_| anyhow!("Project item at stored path was not a buffer"))?;
Ok(pane.update(&mut cx, |_, cx| { Ok(pane.update(&mut cx, |_, cx| {
cx.add_view(|cx| { cx.build_view(|cx| {
let mut editor = Editor::for_buffer(buffer, Some(project), cx); let mut editor = Editor::for_buffer(buffer, Some(project), cx);
editor.read_scroll_position_from_db(item_id, workspace_id, cx); editor.read_scroll_position_from_db(item_id, workspace_id, cx);
editor editor
}) })

View file

@ -108,59 +108,61 @@ pub fn update_go_to_definition_link(
shift_held: bool, shift_held: bool,
cx: &mut ViewContext<Editor>, cx: &mut ViewContext<Editor>,
) { ) {
let pending_nonempty_selection = editor.has_pending_nonempty_selection(); todo!("old version below");
}
// let pending_nonempty_selection = editor.has_pending_nonempty_selection();
// Store new mouse point as an anchor // // Store new mouse point as an anchor
let snapshot = editor.snapshot(cx); // let snapshot = editor.snapshot(cx);
let trigger_point = match origin { // let trigger_point = match origin {
Some(GoToDefinitionTrigger::Text(p)) => { // Some(GoToDefinitionTrigger::Text(p)) => {
Some(TriggerPoint::Text(snapshot.buffer_snapshot.anchor_before( // Some(TriggerPoint::Text(snapshot.buffer_snapshot.anchor_before(
p.to_offset(&snapshot.display_snapshot, Bias::Left), // p.to_offset(&snapshot.display_snapshot, Bias::Left),
))) // )))
} // }
Some(GoToDefinitionTrigger::InlayHint(p, lsp_location, language_server_id)) => { // Some(GoToDefinitionTrigger::InlayHint(p, lsp_location, language_server_id)) => {
Some(TriggerPoint::InlayHint(p, lsp_location, language_server_id)) // Some(TriggerPoint::InlayHint(p, lsp_location, language_server_id))
} // }
None => None, // None => None,
}; // };
// If the new point is the same as the previously stored one, return early // // If the new point is the same as the previously stored one, return early
if let (Some(a), Some(b)) = ( // if let (Some(a), Some(b)) = (
&trigger_point, // &trigger_point,
&editor.link_go_to_definition_state.last_trigger_point, // &editor.link_go_to_definition_state.last_trigger_point,
) { // ) {
match (a, b) { // match (a, b) {
(TriggerPoint::Text(anchor_a), TriggerPoint::Text(anchor_b)) => { // (TriggerPoint::Text(anchor_a), TriggerPoint::Text(anchor_b)) => {
if anchor_a.cmp(anchor_b, &snapshot.buffer_snapshot).is_eq() { // if anchor_a.cmp(anchor_b, &snapshot.buffer_snapshot).is_eq() {
return; // return;
} // }
} // }
(TriggerPoint::InlayHint(range_a, _, _), TriggerPoint::InlayHint(range_b, _, _)) => { // (TriggerPoint::InlayHint(range_a, _, _), TriggerPoint::InlayHint(range_b, _, _)) => {
if range_a == range_b { // if range_a == range_b {
return; // 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 { // if pending_nonempty_selection {
hide_link_definition(editor, cx); // hide_link_definition(editor, cx);
return; // return;
} // }
if cmd_held { // if cmd_held {
if let Some(trigger_point) = trigger_point { // if let Some(trigger_point) = trigger_point {
let kind = trigger_point.definition_kind(shift_held); // let kind = trigger_point.definition_kind(shift_held);
show_link_definition(kind, editor, trigger_point, snapshot, cx); // show_link_definition(kind, editor, trigger_point, snapshot, cx);
return; // return;
} // }
} // }
hide_link_definition(editor, cx); // hide_link_definition(editor, cx);
} // }
pub fn update_inlay_link_and_hover_points( pub fn update_inlay_link_and_hover_points(
snapshot: &DisplaySnapshot, snapshot: &DisplaySnapshot,
@ -351,201 +353,204 @@ pub fn show_link_definition(
snapshot: EditorSnapshot, snapshot: EditorSnapshot,
cx: &mut ViewContext<Editor>, cx: &mut ViewContext<Editor>,
) { ) {
let same_kind = editor.link_go_to_definition_state.kind == Some(definition_kind); todo!("old implementation below")
if !same_kind {
hide_link_definition(editor, cx);
} }
// let same_kind = editor.link_go_to_definition_state.kind == Some(definition_kind);
if editor.pending_rename.is_some() { // if !same_kind {
return; // hide_link_definition(editor, cx);
}
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)
}
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()) // 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 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)
// }
// 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,
// } // }
// }); // });
// match highlight_range { // if any_definition_does_not_contain_current_location {
// RangeInEditor::Text(text_range) => this // // todo!()
// .highlight_text::<LinkGoToDefinitionState>( // // // Highlight symbol using theme link definition highlight style
// vec![text_range], // // let style = theme::current(cx).editor.link_definition;
// style, // // let highlight_range =
// cx, // // symbol_range.unwrap_or_else(|| match &trigger_point {
// ), // // TriggerPoint::Text(trigger_anchor) => {
// RangeInEditor::Inlay(highlight) => this // // let snapshot = &snapshot.buffer_snapshot;
// .highlight_inlays::<LinkGoToDefinitionState>( // // // If no symbol range returned from language server, use the surrounding word.
// vec![highlight], // // let (offset_range, _) =
// style, // // snapshot.surrounding_word(*trigger_anchor);
// cx, // // 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);
// } // }
} else { // }
hide_link_definition(this, cx); // })?;
}
}
})?;
Ok::<_, anyhow::Error>(()) // Ok::<_, anyhow::Error>(())
} // }
.log_err() // .log_err()
}); // });
editor.link_go_to_definition_state.task = Some(task); // editor.link_go_to_definition_state.task = Some(task);
} // }
pub fn hide_link_definition(editor: &mut Editor, cx: &mut ViewContext<Editor>) { pub fn hide_link_definition(editor: &mut Editor, cx: &mut ViewContext<Editor>) {
if editor.link_go_to_definition_state.symbol_range.is_some() todo!()
|| !editor.link_go_to_definition_state.definitions.is_empty() // 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(); // editor.link_go_to_definition_state.symbol_range.take();
cx.notify(); // editor.link_go_to_definition_state.definitions.clear();
} // cx.notify();
// }
editor.link_go_to_definition_state.task = None; // editor.link_go_to_definition_state.task = None;
editor.clear_highlights::<LinkGoToDefinitionState>(cx); // editor.clear_highlights::<LinkGoToDefinitionState>(cx);
} }
pub fn go_to_fetched_definition( pub fn go_to_fetched_definition(

View file

@ -1,7 +1,8 @@
use super::{Bias, DisplayPoint, DisplaySnapshot, SelectionGoal, ToDisplayPoint}; use super::{Bias, DisplayPoint, DisplaySnapshot, SelectionGoal, ToDisplayPoint};
use crate::{char_kind, CharKind, EditorStyle, ToOffset, ToPoint}; use crate::{char_kind, CharKind, EditorStyle, ToOffset, ToPoint};
use gpui::TextSystem; use gpui::{px, TextSystem};
use language::Point; use language::Point;
use serde::de::IntoDeserializer;
use std::ops::Range; use std::ops::Range;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -93,9 +94,9 @@ pub fn up_by_rows(
text_layout_details: &TextLayoutDetails, text_layout_details: &TextLayoutDetails,
) -> (DisplayPoint, SelectionGoal) { ) -> (DisplayPoint, SelectionGoal) {
let mut goal_x = match goal { let mut goal_x = match goal {
SelectionGoal::HorizontalPosition(x) => x, SelectionGoal::HorizontalPosition(x) => x.into(), // todo!("Can the fields in SelectionGoal by Pixels? We should extract a geometry crate and depend on that.")
SelectionGoal::WrappedHorizontalPosition((_, x)) => x, SelectionGoal::WrappedHorizontalPosition((_, x)) => x.into(),
SelectionGoal::HorizontalRange { end, .. } => end, SelectionGoal::HorizontalRange { end, .. } => end.into(),
_ => map.x_for_point(start, text_layout_details), _ => map.x_for_point(start, text_layout_details),
}; };
@ -110,14 +111,17 @@ pub fn up_by_rows(
return (start, goal); return (start, goal);
} else { } else {
point = DisplayPoint::new(0, 0); point = DisplayPoint::new(0, 0);
goal_x = 0.0; goal_x = px(0.);
} }
let mut clipped_point = map.clip_point(point, Bias::Left); let mut clipped_point = map.clip_point(point, Bias::Left);
if clipped_point.row() < point.row() { if clipped_point.row() < point.row() {
clipped_point = map.clip_point(point, Bias::Right); clipped_point = map.clip_point(point, Bias::Right);
} }
(clipped_point, SelectionGoal::HorizontalPosition(goal_x)) (
clipped_point,
SelectionGoal::HorizontalPosition(goal_x.into()),
)
} }
pub fn down_by_rows( pub fn down_by_rows(
@ -129,9 +133,9 @@ pub fn down_by_rows(
text_layout_details: &TextLayoutDetails, text_layout_details: &TextLayoutDetails,
) -> (DisplayPoint, SelectionGoal) { ) -> (DisplayPoint, SelectionGoal) {
let mut goal_x = match goal { let mut goal_x = match goal {
SelectionGoal::HorizontalPosition(x) => x, SelectionGoal::HorizontalPosition(x) => x.into(),
SelectionGoal::WrappedHorizontalPosition((_, x)) => x, SelectionGoal::WrappedHorizontalPosition((_, x)) => x.into(),
SelectionGoal::HorizontalRange { end, .. } => end, SelectionGoal::HorizontalRange { end, .. } => end.into(),
_ => map.x_for_point(start, text_layout_details), _ => map.x_for_point(start, text_layout_details),
}; };
@ -150,7 +154,10 @@ pub fn down_by_rows(
if clipped_point.row() > point.row() { if clipped_point.row() > point.row() {
clipped_point = map.clip_point(point, Bias::Left); clipped_point = map.clip_point(point, Bias::Left);
} }
(clipped_point, SelectionGoal::HorizontalPosition(goal_x)) (
clipped_point,
SelectionGoal::HorizontalPosition(goal_x.into()),
)
} }
pub fn line_beginning( pub fn line_beginning(

View file

@ -3,7 +3,6 @@ use std::path::PathBuf;
use db::sqlez_macros::sql; use db::sqlez_macros::sql;
use db::{define_connection, query}; use db::{define_connection, query};
use gpui::EntityId;
use workspace::{ItemId, WorkspaceDb, WorkspaceId}; use workspace::{ItemId, WorkspaceDb, WorkspaceId};
define_connection!( define_connection!(
@ -67,7 +66,7 @@ impl EditorDb {
query! { query! {
pub async fn save_scroll_position( pub async fn save_scroll_position(
item_id: EntityId, item_id: ItemId,
workspace_id: WorkspaceId, workspace_id: WorkspaceId,
top_row: u32, top_row: u32,
vertical_offset: f32, vertical_offset: f32,

View file

@ -16,7 +16,7 @@ use std::{
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use util::ResultExt; use util::ResultExt;
use workspace::WorkspaceId; use workspace::{ItemId, WorkspaceId};
use self::{ use self::{
autoscroll::{Autoscroll, AutoscrollStrategy}, autoscroll::{Autoscroll, AutoscrollStrategy},
@ -228,7 +228,7 @@ impl ScrollManager {
self.show_scrollbar(cx); self.show_scrollbar(cx);
self.autoscroll_request.take(); self.autoscroll_request.take();
if let Some(workspace_id) = workspace_id { if let Some(workspace_id) = workspace_id {
let item_id = cx.view().entity_id(); let item_id = cx.view().entity_id().as_u64() as ItemId;
cx.foreground_executor() cx.foreground_executor()
.spawn(async move { .spawn(async move {
@ -355,31 +355,31 @@ impl Editor {
// self.scroll_manager.anchor.scroll_position(&display_map) // self.scroll_manager.anchor.scroll_position(&display_map)
// } // }
// pub fn set_scroll_anchor(&mut self, scroll_anchor: ScrollAnchor, cx: &mut ViewContext<Self>) { pub fn set_scroll_anchor(&mut self, scroll_anchor: ScrollAnchor, cx: &mut ViewContext<Self>) {
// hide_hover(self, cx); hide_hover(self, cx);
// let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1); let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1);
// let top_row = scroll_anchor let top_row = scroll_anchor
// .anchor .anchor
// .to_point(&self.buffer().read(cx).snapshot(cx)) .to_point(&self.buffer().read(cx).snapshot(cx))
// .row; .row;
// self.scroll_manager self.scroll_manager
// .set_anchor(scroll_anchor, top_row, true, false, workspace_id, cx); .set_anchor(scroll_anchor, top_row, true, false, workspace_id, cx);
// } }
// pub(crate) fn set_scroll_anchor_remote( pub(crate) fn set_scroll_anchor_remote(
// &mut self, &mut self,
// scroll_anchor: ScrollAnchor, scroll_anchor: ScrollAnchor,
// cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
// ) { ) {
// hide_hover(self, cx); hide_hover(self, cx);
// let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1); let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1);
// let top_row = scroll_anchor let top_row = scroll_anchor
// .anchor .anchor
// .to_point(&self.buffer().read(cx).snapshot(cx)) .to_point(&self.buffer().read(cx).snapshot(cx))
// .row; .row;
// self.scroll_manager self.scroll_manager
// .set_anchor(scroll_anchor, top_row, false, false, workspace_id, cx); .set_anchor(scroll_anchor, top_row, false, false, workspace_id, cx);
// } }
// pub fn scroll_screen(&mut self, amount: &ScrollAmount, cx: &mut ViewContext<Self>) { // pub fn scroll_screen(&mut self, amount: &ScrollAmount, cx: &mut ViewContext<Self>) {
// if matches!(self.mode, EditorMode::SingleLine) { // if matches!(self.mode, EditorMode::SingleLine) {
@ -426,24 +426,24 @@ impl Editor {
// Ordering::Greater // Ordering::Greater
// } // }
// pub fn read_scroll_position_from_db( pub fn read_scroll_position_from_db(
// &mut self, &mut self,
// item_id: usize, item_id: usize,
// workspace_id: WorkspaceId, workspace_id: WorkspaceId,
// cx: &mut ViewContext<Editor>, cx: &mut ViewContext<Editor>,
// ) { ) {
// let scroll_position = DB.get_scroll_position(item_id, workspace_id); let scroll_position = DB.get_scroll_position(item_id, workspace_id);
// if let Ok(Some((top_row, x, y))) = scroll_position { if let Ok(Some((top_row, x, y))) = scroll_position {
// let top_anchor = self let top_anchor = self
// .buffer() .buffer()
// .read(cx) .read(cx)
// .snapshot(cx) .snapshot(cx)
// .anchor_at(Point::new(top_row as u32, 0), Bias::Left); .anchor_at(Point::new(top_row as u32, 0), Bias::Left);
// let scroll_anchor = ScrollAnchor { let scroll_anchor = ScrollAnchor {
// offset: Point::new(x, y), offset: gpui::Point::new(x, y),
// anchor: top_anchor, anchor: top_anchor,
// }; };
// self.set_scroll_anchor(scroll_anchor, cx); self.set_scroll_anchor(scroll_anchor, cx);
// } }
// } }
} }

View file

@ -1,5 +1,3 @@
use gpui::Pixels;
use crate::{Anchor, BufferSnapshot, TextDimension}; use crate::{Anchor, BufferSnapshot, TextDimension};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::ops::Range; use std::ops::Range;
@ -7,8 +5,8 @@ use std::ops::Range;
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
pub enum SelectionGoal { pub enum SelectionGoal {
None, None,
HorizontalPosition(Pixels), HorizontalPosition(f32), // todo!("Can we use pixels here without adding a runtime gpui dependency?")
HorizontalRange { start: Pixels, end: Pixels }, HorizontalRange { start: f32, end: f32 },
WrappedHorizontalPosition((u32, f32)), WrappedHorizontalPosition((u32, f32)),
} }