Merge branch 'main' into multibuffer-following

This commit is contained in:
Max Brunsfeld 2022-12-12 11:47:39 -08:00
commit f797dfb88f
175 changed files with 16722 additions and 8699 deletions

View file

@ -9,6 +9,8 @@ mod link_go_to_definition;
mod mouse_context_menu;
pub mod movement;
mod multi_buffer;
mod persistence;
pub mod scroll;
pub mod selections_collection;
#[cfg(test)]
@ -32,13 +34,13 @@ use gpui::{
elements::*,
executor,
fonts::{self, HighlightStyle, TextStyle},
geometry::vector::{vec2f, Vector2F},
geometry::vector::Vector2F,
impl_actions, impl_internal_actions,
platform::CursorStyle,
serde_json::json,
text_layout, AnyViewHandle, AppContext, AsyncAppContext, Axis, ClipboardItem, Element,
ElementBox, Entity, ModelHandle, MouseButton, MutableAppContext, RenderContext, Subscription,
Task, View, ViewContext, ViewHandle, WeakViewHandle,
AnyViewHandle, AppContext, AsyncAppContext, ClipboardItem, Element, ElementBox, Entity,
ModelHandle, MouseButton, MutableAppContext, RenderContext, Subscription, Task, View,
ViewContext, ViewHandle, WeakViewHandle,
};
use highlight_matching_bracket::refresh_matching_bracket_highlights;
use hover_popover::{hide_hover, HoverState};
@ -60,11 +62,13 @@ pub use multi_buffer::{
use multi_buffer::{MultiBufferChunks, ToOffsetUtf16};
use ordered_float::OrderedFloat;
use project::{FormatTrigger, LocationLink, Project, ProjectPath, ProjectTransaction};
use scroll::{
autoscroll::Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide,
};
use selections_collection::{resolve_multiple, MutableSelectionsCollection, SelectionsCollection};
use serde::{Deserialize, Serialize};
use settings::Settings;
use smallvec::SmallVec;
use smol::Timer;
use snippet::Snippet;
use std::{
any::TypeId,
@ -80,16 +84,14 @@ use std::{
pub use sum_tree::Bias;
use theme::{DiagnosticStyle, Theme};
use util::{post_inc, ResultExt, TryFutureExt};
use workspace::{ItemNavHistory, Workspace};
use workspace::{ItemNavHistory, Workspace, WorkspaceId};
use crate::git::diff_hunk_to_display;
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
const SCROLLBAR_SHOW_INTERVAL: Duration = Duration::from_secs(1);
const MAX_LINE_LEN: usize = 1024;
const MIN_NAVIGATION_HISTORY_ROW_DELTA: i64 = 10;
const MAX_SELECTION_HISTORY_LEN: usize = 1024;
pub const SCROLL_EVENT_SEPARATION: Duration = Duration::from_millis(28);
pub const FORMAT_TIMEOUT: Duration = Duration::from_secs(2);
@ -99,12 +101,6 @@ pub struct SelectNext {
pub replace_newest: bool,
}
#[derive(Clone, PartialEq)]
pub struct Scroll {
pub scroll_position: Vector2F,
pub axis: Option<Axis>,
}
#[derive(Clone, PartialEq)]
pub struct Select(pub SelectPhase);
@ -257,7 +253,7 @@ impl_actions!(
]
);
impl_internal_actions!(editor, [Scroll, Select, Jump]);
impl_internal_actions!(editor, [Select, Jump]);
enum DocumentHighlightRead {}
enum DocumentHighlightWrite {}
@ -269,12 +265,8 @@ pub enum Direction {
Next,
}
#[derive(Default)]
struct ScrollbarAutoHide(bool);
pub fn init(cx: &mut MutableAppContext) {
cx.add_action(Editor::new_file);
cx.add_action(Editor::scroll);
cx.add_action(Editor::select);
cx.add_action(Editor::cancel);
cx.add_action(Editor::newline);
@ -304,12 +296,9 @@ pub fn init(cx: &mut MutableAppContext) {
cx.add_action(Editor::redo);
cx.add_action(Editor::move_up);
cx.add_action(Editor::move_page_up);
cx.add_action(Editor::page_up);
cx.add_action(Editor::move_down);
cx.add_action(Editor::move_page_down);
cx.add_action(Editor::page_down);
cx.add_action(Editor::next_screen);
cx.add_action(Editor::move_left);
cx.add_action(Editor::move_right);
cx.add_action(Editor::move_to_previous_word_start);
@ -369,9 +358,11 @@ pub fn init(cx: &mut MutableAppContext) {
hover_popover::init(cx);
link_go_to_definition::init(cx);
mouse_context_menu::init(cx);
scroll::actions::init(cx);
workspace::register_project_item::<Editor>(cx);
workspace::register_followable_item::<Editor>(cx);
workspace::register_deserializable_item::<Editor>(cx);
}
trait InvalidationRegion {
@ -409,46 +400,6 @@ pub enum SelectMode {
All,
}
#[derive(PartialEq, Eq)]
pub enum Autoscroll {
Next,
Strategy(AutoscrollStrategy),
}
impl Autoscroll {
pub fn fit() -> Self {
Self::Strategy(AutoscrollStrategy::Fit)
}
pub fn newest() -> Self {
Self::Strategy(AutoscrollStrategy::Newest)
}
pub fn center() -> Self {
Self::Strategy(AutoscrollStrategy::Center)
}
}
#[derive(PartialEq, Eq, Default)]
pub enum AutoscrollStrategy {
Fit,
Newest,
#[default]
Center,
Top,
Bottom,
}
impl AutoscrollStrategy {
fn next(&self) -> Self {
match self {
AutoscrollStrategy::Center => AutoscrollStrategy::Top,
AutoscrollStrategy::Top => AutoscrollStrategy::Bottom,
_ => AutoscrollStrategy::Center,
}
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum EditorMode {
SingleLine,
@ -475,74 +426,12 @@ type CompletionId = usize;
type GetFieldEditorTheme = dyn Fn(&theme::Theme) -> theme::FieldEditor;
type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option<HighlightStyle>;
#[derive(Clone, Copy)]
pub struct OngoingScroll {
last_timestamp: Instant,
axis: Option<Axis>,
}
impl OngoingScroll {
fn initial() -> OngoingScroll {
OngoingScroll {
last_timestamp: Instant::now() - SCROLL_EVENT_SEPARATION,
axis: None,
}
}
fn update(&mut self, axis: Option<Axis>) {
self.last_timestamp = Instant::now();
self.axis = axis;
}
pub fn filter(&self, delta: &mut Vector2F) -> Option<Axis> {
const UNLOCK_PERCENT: f32 = 1.9;
const UNLOCK_LOWER_BOUND: f32 = 6.;
let mut axis = self.axis;
let x = delta.x().abs();
let y = delta.y().abs();
let duration = Instant::now().duration_since(self.last_timestamp);
if duration > SCROLL_EVENT_SEPARATION {
//New ongoing scroll will start, determine axis
axis = if x <= y {
Some(Axis::Vertical)
} else {
Some(Axis::Horizontal)
};
} else if x.max(y) >= UNLOCK_LOWER_BOUND {
//Check if the current ongoing will need to unlock
match axis {
Some(Axis::Vertical) => {
if x > y && x >= y * UNLOCK_PERCENT {
axis = None;
}
}
Some(Axis::Horizontal) => {
if y > x && y >= x * UNLOCK_PERCENT {
axis = None;
}
}
None => {}
}
}
match axis {
Some(Axis::Vertical) => *delta = vec2f(0., delta.y()),
Some(Axis::Horizontal) => *delta = vec2f(delta.x(), 0.),
None => {}
}
axis
}
}
pub struct Editor {
handle: WeakViewHandle<Self>,
buffer: ModelHandle<MultiBuffer>,
display_map: ModelHandle<DisplayMap>,
pub selections: SelectionsCollection,
pub scroll_manager: ScrollManager,
columnar_selection_tail: Option<Anchor>,
add_selections_state: Option<AddSelectionsState>,
select_next_state: Option<SelectNextState>,
@ -552,10 +441,6 @@ pub struct Editor {
select_larger_syntax_node_stack: Vec<Box<[Selection<usize>]>>,
ime_transaction: Option<TransactionId>,
active_diagnostics: Option<ActiveDiagnosticGroup>,
ongoing_scroll: OngoingScroll,
scroll_position: Vector2F,
scroll_top_anchor: Anchor,
autoscroll_request: Option<(Autoscroll, bool)>,
soft_wrap_mode_override: Option<settings::SoftWrap>,
get_field_editor_theme: Option<Arc<GetFieldEditorTheme>>,
override_text_style: Option<Box<OverrideTextStyle>>,
@ -563,10 +448,7 @@ pub struct Editor {
focused: bool,
blink_manager: ModelHandle<BlinkManager>,
show_local_selections: bool,
show_scrollbars: bool,
hide_scrollbar_task: Option<Task<()>>,
mode: EditorMode,
vertical_scroll_margin: f32,
placeholder_text: Option<Arc<str>>,
highlighted_rows: Option<Range<u32>>,
#[allow(clippy::type_complexity)]
@ -582,13 +464,12 @@ pub struct Editor {
pending_rename: Option<RenameState>,
searchable: bool,
cursor_shape: CursorShape,
workspace_id: Option<WorkspaceId>,
keymap_context_layers: BTreeMap<TypeId, gpui::keymap::Context>,
input_enabled: bool,
leader_replica_id: Option<u16>,
hover_state: HoverState,
link_go_to_definition_state: LinkGoToDefinitionState,
visible_line_count: Option<f32>,
last_autoscroll: Option<(Vector2F, f32, f32, AutoscrollStrategy)>,
_subscriptions: Vec<Subscription>,
}
@ -597,9 +478,8 @@ pub struct EditorSnapshot {
pub display_snapshot: DisplaySnapshot,
pub placeholder_text: Option<Arc<str>>,
is_focused: bool,
scroll_anchor: ScrollAnchor,
ongoing_scroll: OngoingScroll,
scroll_position: Vector2F,
scroll_top_anchor: Anchor,
}
#[derive(Clone, Debug)]
@ -1087,12 +967,9 @@ pub struct ClipboardSelection {
#[derive(Debug)]
pub struct NavigationData {
// Matching offsets for anchor and scroll_top_anchor allows us to recreate the anchor if the buffer
// has since been closed
cursor_anchor: Anchor,
cursor_position: Point,
scroll_position: Vector2F,
scroll_top_anchor: Anchor,
scroll_anchor: ScrollAnchor,
scroll_top_row: u32,
}
@ -1160,9 +1037,8 @@ impl Editor {
display_map.set_state(&snapshot, cx);
});
});
clone.selections.set_state(&self.selections);
clone.scroll_position = self.scroll_position;
clone.scroll_top_anchor = self.scroll_top_anchor;
clone.selections.clone_state(&self.selections);
clone.scroll_manager.clone_state(&self.scroll_manager);
clone.searchable = self.searchable;
clone
}
@ -1197,6 +1073,7 @@ impl Editor {
buffer: buffer.clone(),
display_map: display_map.clone(),
selections,
scroll_manager: ScrollManager::new(),
columnar_selection_tail: None,
add_selections_state: None,
select_next_state: None,
@ -1209,17 +1086,10 @@ impl Editor {
soft_wrap_mode_override: None,
get_field_editor_theme,
project,
ongoing_scroll: OngoingScroll::initial(),
scroll_position: Vector2F::zero(),
scroll_top_anchor: Anchor::min(),
autoscroll_request: None,
focused: false,
blink_manager: blink_manager.clone(),
show_local_selections: true,
show_scrollbars: true,
hide_scrollbar_task: None,
mode,
vertical_scroll_margin: 3.0,
placeholder_text: None,
highlighted_rows: None,
background_highlights: Default::default(),
@ -1235,13 +1105,12 @@ impl Editor {
searchable: true,
override_text_style: None,
cursor_shape: Default::default(),
workspace_id: None,
keymap_context_layers: Default::default(),
input_enabled: true,
leader_replica_id: None,
hover_state: Default::default(),
link_go_to_definition_state: Default::default(),
visible_line_count: None,
last_autoscroll: None,
_subscriptions: vec![
cx.observe(&buffer, Self::on_buffer_changed),
cx.subscribe(&buffer, Self::on_buffer_event),
@ -1250,7 +1119,7 @@ impl Editor {
],
};
this.end_selection(cx);
this.make_scrollbar_visible(cx);
this.scroll_manager.show_scrollbar(cx);
let editor_created_event = EditorCreated(cx.handle());
cx.emit_global(editor_created_event);
@ -1303,9 +1172,8 @@ impl Editor {
EditorSnapshot {
mode: self.mode,
display_snapshot: self.display_map.update(cx, |map, cx| map.snapshot(cx)),
ongoing_scroll: self.ongoing_scroll,
scroll_position: self.scroll_position,
scroll_top_anchor: self.scroll_top_anchor,
scroll_anchor: self.scroll_manager.anchor(),
ongoing_scroll: self.scroll_manager.ongoing_scroll(),
placeholder_text: self.placeholder_text.clone(),
is_focused: self
.handle
@ -1344,64 +1212,6 @@ impl Editor {
cx.notify();
}
pub fn set_vertical_scroll_margin(&mut self, margin_rows: usize, cx: &mut ViewContext<Self>) {
self.vertical_scroll_margin = margin_rows as f32;
cx.notify();
}
pub fn set_scroll_position(&mut self, scroll_position: Vector2F, cx: &mut ViewContext<Self>) {
self.set_scroll_position_internal(scroll_position, true, cx);
}
fn set_scroll_position_internal(
&mut self,
scroll_position: Vector2F,
local: bool,
cx: &mut ViewContext<Self>,
) {
let map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
if scroll_position.y() <= 0. {
self.scroll_top_anchor = Anchor::min();
self.scroll_position = scroll_position.max(vec2f(0., 0.));
} else {
let scroll_top_buffer_offset =
DisplayPoint::new(scroll_position.y() as u32, 0).to_offset(&map, Bias::Right);
let anchor = map
.buffer_snapshot
.anchor_at(scroll_top_buffer_offset, Bias::Right);
self.scroll_position = vec2f(
scroll_position.x(),
scroll_position.y() - anchor.to_display_point(&map).row() as f32,
);
self.scroll_top_anchor = anchor;
}
self.make_scrollbar_visible(cx);
self.autoscroll_request.take();
hide_hover(self, cx);
cx.emit(Event::ScrollPositionChanged { local });
cx.notify();
}
fn set_visible_line_count(&mut self, lines: f32) {
self.visible_line_count = Some(lines)
}
fn set_scroll_top_anchor(
&mut self,
anchor: Anchor,
position: Vector2F,
cx: &mut ViewContext<Self>,
) {
self.scroll_top_anchor = anchor;
self.scroll_position = position;
self.make_scrollbar_visible(cx);
cx.emit(Event::ScrollPositionChanged { local: false });
cx.notify();
}
pub fn set_cursor_shape(&mut self, cursor_shape: CursorShape, cx: &mut ViewContext<Self>) {
self.cursor_shape = cursor_shape;
cx.notify();
@ -1427,199 +1237,6 @@ impl Editor {
self.input_enabled = input_enabled;
}
pub fn scroll_position(&self, cx: &mut ViewContext<Self>) -> Vector2F {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
compute_scroll_position(&display_map, self.scroll_position, &self.scroll_top_anchor)
}
pub fn clamp_scroll_left(&mut self, max: f32) -> bool {
if max < self.scroll_position.x() {
self.scroll_position.set_x(max);
true
} else {
false
}
}
pub fn autoscroll_vertically(
&mut self,
viewport_height: f32,
line_height: f32,
cx: &mut ViewContext<Self>,
) -> bool {
let visible_lines = viewport_height / line_height;
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let mut scroll_position =
compute_scroll_position(&display_map, self.scroll_position, &self.scroll_top_anchor);
let max_scroll_top = if matches!(self.mode, EditorMode::AutoHeight { .. }) {
(display_map.max_point().row() as f32 - visible_lines + 1.).max(0.)
} else {
display_map.max_point().row() as f32
};
if scroll_position.y() > max_scroll_top {
scroll_position.set_y(max_scroll_top);
self.set_scroll_position(scroll_position, cx);
}
let (autoscroll, local) = if let Some(autoscroll) = self.autoscroll_request.take() {
autoscroll
} else {
return false;
};
let first_cursor_top;
let last_cursor_bottom;
if let Some(highlighted_rows) = &self.highlighted_rows {
first_cursor_top = highlighted_rows.start as f32;
last_cursor_bottom = first_cursor_top + 1.;
} else if autoscroll == Autoscroll::newest() {
let newest_selection = self.selections.newest::<Point>(cx);
first_cursor_top = newest_selection.head().to_display_point(&display_map).row() as f32;
last_cursor_bottom = first_cursor_top + 1.;
} else {
let selections = self.selections.all::<Point>(cx);
first_cursor_top = selections
.first()
.unwrap()
.head()
.to_display_point(&display_map)
.row() as f32;
last_cursor_bottom = selections
.last()
.unwrap()
.head()
.to_display_point(&display_map)
.row() as f32
+ 1.0;
}
let margin = if matches!(self.mode, EditorMode::AutoHeight { .. }) {
0.
} else {
((visible_lines - (last_cursor_bottom - first_cursor_top)) / 2.0).floor()
};
if margin < 0.0 {
return false;
}
let strategy = match autoscroll {
Autoscroll::Strategy(strategy) => strategy,
Autoscroll::Next => {
let last_autoscroll = &self.last_autoscroll;
if let Some(last_autoscroll) = last_autoscroll {
if self.scroll_position == last_autoscroll.0
&& first_cursor_top == last_autoscroll.1
&& last_cursor_bottom == last_autoscroll.2
{
last_autoscroll.3.next()
} else {
AutoscrollStrategy::default()
}
} else {
AutoscrollStrategy::default()
}
}
};
match strategy {
AutoscrollStrategy::Fit | AutoscrollStrategy::Newest => {
let margin = margin.min(self.vertical_scroll_margin);
let target_top = (first_cursor_top - margin).max(0.0);
let target_bottom = last_cursor_bottom + margin;
let start_row = scroll_position.y();
let end_row = start_row + visible_lines;
if target_top < start_row {
scroll_position.set_y(target_top);
self.set_scroll_position_internal(scroll_position, local, cx);
} else if target_bottom >= end_row {
scroll_position.set_y(target_bottom - visible_lines);
self.set_scroll_position_internal(scroll_position, local, cx);
}
}
AutoscrollStrategy::Center => {
scroll_position.set_y((first_cursor_top - margin).max(0.0));
self.set_scroll_position_internal(scroll_position, local, cx);
}
AutoscrollStrategy::Top => {
scroll_position.set_y((first_cursor_top).max(0.0));
self.set_scroll_position_internal(scroll_position, local, cx);
}
AutoscrollStrategy::Bottom => {
scroll_position.set_y((last_cursor_bottom - visible_lines).max(0.0));
self.set_scroll_position_internal(scroll_position, local, cx);
}
}
self.last_autoscroll = Some((
self.scroll_position,
first_cursor_top,
last_cursor_bottom,
strategy,
));
true
}
pub fn autoscroll_horizontally(
&mut self,
start_row: u32,
viewport_width: f32,
scroll_width: f32,
max_glyph_width: f32,
layouts: &[text_layout::Line],
cx: &mut ViewContext<Self>,
) -> bool {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let selections = self.selections.all::<Point>(cx);
let mut target_left;
let mut target_right;
if self.highlighted_rows.is_some() {
target_left = 0.0_f32;
target_right = 0.0_f32;
} else {
target_left = std::f32::INFINITY;
target_right = 0.0_f32;
for selection in selections {
let head = selection.head().to_display_point(&display_map);
if head.row() >= start_row && head.row() < start_row + layouts.len() as u32 {
let start_column = head.column().saturating_sub(3);
let end_column = cmp::min(display_map.line_len(head.row()), head.column() + 3);
target_left = target_left.min(
layouts[(head.row() - start_row) as usize]
.x_for_index(start_column as usize),
);
target_right = target_right.max(
layouts[(head.row() - start_row) as usize].x_for_index(end_column as usize)
+ max_glyph_width,
);
}
}
}
target_right = target_right.min(scroll_width);
if target_right - target_left > viewport_width {
return false;
}
let scroll_left = self.scroll_position.x() * max_glyph_width;
let scroll_right = scroll_left + viewport_width;
if target_left < scroll_left {
self.scroll_position.set_x(target_left / max_glyph_width);
true
} else if target_right > scroll_right {
self.scroll_position
.set_x((target_right - viewport_width) / max_glyph_width);
true
} else {
false
}
}
fn selections_did_change(
&mut self,
local: bool,
@ -1742,11 +1359,6 @@ impl Editor {
});
}
fn scroll(&mut self, action: &Scroll, cx: &mut ViewContext<Self>) {
self.ongoing_scroll.update(action.axis);
self.set_scroll_position(action.scroll_position, cx);
}
fn select(&mut self, Select(phase): &Select, cx: &mut ViewContext<Self>) {
self.hide_context_menu(cx);
@ -2810,7 +2422,7 @@ impl Editor {
let all_edits_within_excerpt = buffer.read_with(&cx, |buffer, _| {
let excerpt_range = excerpt_range.to_offset(buffer);
buffer
.edited_ranges_for_transaction(transaction)
.edited_ranges_for_transaction::<usize>(transaction)
.all(|range| {
excerpt_range.start <= range.start
&& excerpt_range.end >= range.end
@ -4069,23 +3681,6 @@ impl Editor {
})
}
pub fn next_screen(&mut self, _: &NextScreen, cx: &mut ViewContext<Editor>) {
if self.take_rename(true, cx).is_some() {
return;
}
if let Some(_) = self.context_menu.as_mut() {
return;
}
if matches!(self.mode, EditorMode::SingleLine) {
cx.propagate_action();
return;
}
self.request_autoscroll(Autoscroll::Next, cx);
}
pub fn move_up(&mut self, _: &MoveUp, cx: &mut ViewContext<Self>) {
if self.take_rename(true, cx).is_some() {
return;
@ -4119,10 +3714,13 @@ impl Editor {
return;
}
if let Some(context_menu) = self.context_menu.as_mut() {
if context_menu.select_first(cx) {
return;
}
if self
.context_menu
.as_mut()
.map(|menu| menu.select_first(cx))
.unwrap_or(false)
{
return;
}
if matches!(self.mode, EditorMode::SingleLine) {
@ -4130,9 +3728,10 @@ impl Editor {
return;
}
let row_count = match self.visible_line_count {
Some(row_count) => row_count as u32 - 1,
None => return,
let row_count = if let Some(row_count) = self.visible_line_count() {
row_count as u32 - 1
} else {
return;
};
let autoscroll = if action.center_cursor {
@ -4154,32 +3753,6 @@ impl Editor {
});
}
pub fn page_up(&mut self, _: &PageUp, cx: &mut ViewContext<Self>) {
if self.take_rename(true, cx).is_some() {
return;
}
if let Some(context_menu) = self.context_menu.as_mut() {
if context_menu.select_first(cx) {
return;
}
}
if matches!(self.mode, EditorMode::SingleLine) {
cx.propagate_action();
return;
}
let lines = match self.visible_line_count {
Some(lines) => lines,
None => return,
};
let cur_position = self.scroll_position(cx);
let new_pos = cur_position - vec2f(0., lines + 1.);
self.set_scroll_position(new_pos, cx);
}
pub fn select_up(&mut self, _: &SelectUp, cx: &mut ViewContext<Self>) {
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.move_heads_with(|map, head, goal| movement::up(map, head, goal, false))
@ -4217,10 +3790,13 @@ impl Editor {
return;
}
if let Some(context_menu) = self.context_menu.as_mut() {
if context_menu.select_last(cx) {
return;
}
if self
.context_menu
.as_mut()
.map(|menu| menu.select_last(cx))
.unwrap_or(false)
{
return;
}
if matches!(self.mode, EditorMode::SingleLine) {
@ -4228,9 +3804,10 @@ impl Editor {
return;
}
let row_count = match self.visible_line_count {
Some(row_count) => row_count as u32 - 1,
None => return,
let row_count = if let Some(row_count) = self.visible_line_count() {
row_count as u32 - 1
} else {
return;
};
let autoscroll = if action.center_cursor {
@ -4252,32 +3829,6 @@ impl Editor {
});
}
pub fn page_down(&mut self, _: &PageDown, cx: &mut ViewContext<Self>) {
if self.take_rename(true, cx).is_some() {
return;
}
if let Some(context_menu) = self.context_menu.as_mut() {
if context_menu.select_last(cx) {
return;
}
}
if matches!(self.mode, EditorMode::SingleLine) {
cx.propagate_action();
return;
}
let lines = match self.visible_line_count {
Some(lines) => lines,
None => return,
};
let cur_position = self.scroll_position(cx);
let new_pos = cur_position + vec2f(0., lines - 1.);
self.set_scroll_position(new_pos, cx);
}
pub fn select_down(&mut self, _: &SelectDown, cx: &mut ViewContext<Self>) {
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.move_heads_with(|map, head, goal| movement::down(map, head, goal, false))
@ -4598,18 +4149,19 @@ impl Editor {
fn push_to_nav_history(
&self,
position: Anchor,
cursor_anchor: Anchor,
new_position: Option<Point>,
cx: &mut ViewContext<Self>,
) {
if let Some(nav_history) = &self.nav_history {
let buffer = self.buffer.read(cx).read(cx);
let point = position.to_point(&buffer);
let scroll_top_row = self.scroll_top_anchor.to_point(&buffer).row;
let cursor_position = cursor_anchor.to_point(&buffer);
let scroll_state = self.scroll_manager.anchor();
let scroll_top_row = scroll_state.top_row(&buffer);
drop(buffer);
if let Some(new_position) = new_position {
let row_delta = (new_position.row as i64 - point.row as i64).abs();
let row_delta = (new_position.row as i64 - cursor_position.row as i64).abs();
if row_delta < MIN_NAVIGATION_HISTORY_ROW_DELTA {
return;
}
@ -4617,10 +4169,9 @@ impl Editor {
nav_history.push(
Some(NavigationData {
cursor_anchor: position,
cursor_position: point,
scroll_position: self.scroll_position,
scroll_top_anchor: self.scroll_top_anchor,
cursor_anchor,
cursor_position,
scroll_anchor: scroll_state,
scroll_top_row,
}),
cx,
@ -5918,16 +5469,6 @@ impl Editor {
});
}
pub fn request_autoscroll(&mut self, autoscroll: Autoscroll, cx: &mut ViewContext<Self>) {
self.autoscroll_request = Some((autoscroll, true));
cx.notify();
}
fn request_autoscroll_remotely(&mut self, autoscroll: Autoscroll, cx: &mut ViewContext<Self>) {
self.autoscroll_request = Some((autoscroll, false));
cx.notify();
}
pub fn transact(
&mut self,
cx: &mut ViewContext<Self>,
@ -6336,31 +5877,6 @@ impl Editor {
self.blink_manager.read(cx).visible() && self.focused
}
pub fn show_scrollbars(&self) -> bool {
self.show_scrollbars
}
fn make_scrollbar_visible(&mut self, cx: &mut ViewContext<Self>) {
if !self.show_scrollbars {
self.show_scrollbars = true;
cx.notify();
}
if cx.default_global::<ScrollbarAutoHide>().0 {
self.hide_scrollbar_task = Some(cx.spawn_weak(|this, mut cx| async move {
Timer::after(SCROLLBAR_SHOW_INTERVAL).await;
if let Some(this) = this.upgrade(&cx) {
this.update(&mut cx, |this, cx| {
this.show_scrollbars = false;
cx.notify();
});
}
}));
} else {
self.hide_scrollbar_task = None;
}
}
fn on_buffer_changed(&mut self, _: ModelHandle<MultiBuffer>, cx: &mut ViewContext<Self>) {
cx.notify();
}
@ -6568,11 +6084,7 @@ impl EditorSnapshot {
}
pub fn scroll_position(&self) -> Vector2F {
compute_scroll_position(
&self.display_snapshot,
self.scroll_position,
&self.scroll_top_anchor,
)
self.scroll_anchor.scroll_position(&self.display_snapshot)
}
}
@ -6584,20 +6096,6 @@ impl Deref for EditorSnapshot {
}
}
fn compute_scroll_position(
snapshot: &DisplaySnapshot,
mut scroll_position: Vector2F,
scroll_top_anchor: &Anchor,
) -> Vector2F {
if *scroll_top_anchor != Anchor::min() {
let scroll_top = scroll_top_anchor.to_display_point(snapshot).row() as f32;
scroll_position.set_y(scroll_top + scroll_position.y());
} else {
scroll_position.set_y(0.);
}
scroll_position
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Event {
ExcerptsAdded {
@ -6622,7 +6120,6 @@ pub enum Event {
local: bool,
},
Closed,
IgnoredInput,
}
pub struct EditorFocused(pub ViewHandle<Editor>);
@ -6808,7 +6305,6 @@ impl View for Editor {
cx: &mut ViewContext<Self>,
) {
if !self.input_enabled {
cx.emit(Event::IgnoredInput);
return;
}
@ -6845,7 +6341,6 @@ impl View for Editor {
cx: &mut ViewContext<Self>,
) {
if !self.input_enabled {
cx.emit(Event::IgnoredInput);
return;
}