Use offset to restore navigation position if anchor can't be resolved
This commit is contained in:
parent
d480738cc5
commit
d5acbe1e32
4 changed files with 39 additions and 12 deletions
|
@ -426,6 +426,11 @@ struct ClipboardSelection {
|
||||||
is_entire_line: bool,
|
is_entire_line: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct NavigationData {
|
||||||
|
anchor: Anchor,
|
||||||
|
offset: usize,
|
||||||
|
}
|
||||||
|
|
||||||
impl Editor {
|
impl Editor {
|
||||||
pub fn single_line(build_settings: BuildSettings, cx: &mut ViewContext<Self>) -> Self {
|
pub fn single_line(build_settings: BuildSettings, cx: &mut ViewContext<Self>) -> Self {
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, String::new(), cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, String::new(), cx));
|
||||||
|
@ -2438,9 +2443,12 @@ impl Editor {
|
||||||
|
|
||||||
fn push_to_navigation_history(&self, cx: &mut ViewContext<Self>) {
|
fn push_to_navigation_history(&self, cx: &mut ViewContext<Self>) {
|
||||||
if let Some(navigation) = &self.navigation {
|
if let Some(navigation) = &self.navigation {
|
||||||
|
let buffer = self.buffer.read(cx).read(cx);
|
||||||
if let Some(last_selection) = self.selections.iter().max_by_key(|s| s.id) {
|
if let Some(last_selection) = self.selections.iter().max_by_key(|s| s.id) {
|
||||||
let cursor = last_selection.head();
|
let anchor = last_selection.head();
|
||||||
navigation.push(Some(cursor), cx);
|
let offset = anchor.to_offset(&buffer);
|
||||||
|
drop(buffer);
|
||||||
|
navigation.push(Some(NavigationData { anchor, offset }), cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::{Anchor, Autoscroll, Editor, Event, MultiBuffer, ToOffset, ToPoint as _};
|
use crate::{Autoscroll, Editor, Event, MultiBuffer, NavigationData, ToOffset, ToPoint as _};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
elements::*, AppContext, Entity, ModelContext, ModelHandle, MutableAppContext, RenderContext,
|
elements::*, AppContext, Entity, ModelContext, ModelHandle, MutableAppContext, RenderContext,
|
||||||
Subscription, Task, View, ViewContext, ViewHandle, WeakModelHandle,
|
Subscription, Task, View, ViewContext, ViewHandle, WeakModelHandle,
|
||||||
};
|
};
|
||||||
use language::{Buffer, Diagnostic, File as _};
|
use language::{Bias, Buffer, Diagnostic, File as _};
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
use project::{File, ProjectPath, Worktree};
|
use project::{File, ProjectPath, Worktree};
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
@ -106,8 +106,15 @@ impl ItemView for Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn navigate(&mut self, data: Box<dyn std::any::Any>, cx: &mut ViewContext<Self>) {
|
fn navigate(&mut self, data: Box<dyn std::any::Any>, cx: &mut ViewContext<Self>) {
|
||||||
if let Some(anchor) = data.downcast_ref::<Anchor>() {
|
if let Some(data) = data.downcast_ref::<NavigationData>() {
|
||||||
let offset = anchor.to_offset(&self.buffer.read(cx).read(cx));
|
let buffer = self.buffer.read(cx).read(cx);
|
||||||
|
let offset = if buffer.can_resolve(&data.anchor) {
|
||||||
|
data.anchor.to_offset(&buffer)
|
||||||
|
} else {
|
||||||
|
buffer.clip_offset(data.offset, Bias::Left)
|
||||||
|
};
|
||||||
|
|
||||||
|
drop(buffer);
|
||||||
self.select_ranges([offset..offset], Some(Autoscroll::Fit), cx);
|
self.select_ranges([offset..offset], Some(Autoscroll::Fit), cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1545,6 +1545,18 @@ impl MultiBufferSnapshot {
|
||||||
panic!("excerpt not found");
|
panic!("excerpt not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn can_resolve(&self, anchor: &Anchor) -> bool {
|
||||||
|
if anchor.excerpt_id == ExcerptId::min() || anchor.excerpt_id == ExcerptId::max() {
|
||||||
|
true
|
||||||
|
} else if let Some((buffer_id, buffer_snapshot)) =
|
||||||
|
self.buffer_snapshot_for_excerpt(&anchor.excerpt_id)
|
||||||
|
{
|
||||||
|
anchor.buffer_id == buffer_id && buffer_snapshot.can_resolve(&anchor.text_anchor)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn range_contains_excerpt_boundary<T: ToOffset>(&self, range: Range<T>) -> bool {
|
pub fn range_contains_excerpt_boundary<T: ToOffset>(&self, range: Range<T>) -> bool {
|
||||||
let start = range.start.to_offset(self);
|
let start = range.start.to_offset(self);
|
||||||
let end = range.end.to_offset(self);
|
let end = range.end.to_offset(self);
|
||||||
|
|
|
@ -1131,12 +1131,6 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_resolve(&self, anchor: &Anchor) -> bool {
|
|
||||||
*anchor == Anchor::min()
|
|
||||||
|| *anchor == Anchor::max()
|
|
||||||
|| self.version.observed(anchor.timestamp)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn peek_undo_stack(&self) -> Option<&Transaction> {
|
pub fn peek_undo_stack(&self) -> Option<&Transaction> {
|
||||||
self.history.undo_stack.last()
|
self.history.undo_stack.last()
|
||||||
}
|
}
|
||||||
|
@ -1648,6 +1642,12 @@ impl BufferSnapshot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn can_resolve(&self, anchor: &Anchor) -> bool {
|
||||||
|
*anchor == Anchor::min()
|
||||||
|
|| *anchor == Anchor::max()
|
||||||
|
|| self.version.observed(anchor.timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clip_offset(&self, offset: usize, bias: Bias) -> usize {
|
pub fn clip_offset(&self, offset: usize, bias: Bias) -> usize {
|
||||||
self.visible_text.clip_offset(offset, bias)
|
self.visible_text.clip_offset(offset, bias)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue