Merge branch 'main' into instrument-keyboard-events
This commit is contained in:
@@ -1015,7 +1015,6 @@ pub mod tests {
|
||||
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
||||
.unwrap_or(10);
|
||||
|
||||
let _test_platform = &cx.test_platform;
|
||||
let mut tab_size = rng.gen_range(1..=4);
|
||||
let buffer_start_excerpt_header_height = rng.gen_range(1..=5);
|
||||
let excerpt_header_height = rng.gen_range(1..=5);
|
||||
|
||||
+26
-12
@@ -99,8 +99,8 @@ use sum_tree::TreeMap;
|
||||
use text::{OffsetUtf16, Rope};
|
||||
use theme::{ActiveTheme, PlayerColor, StatusColors, SyntaxTheme, ThemeColors, ThemeSettings};
|
||||
use ui::{
|
||||
h_stack, prelude::*, ButtonSize, ButtonStyle, Icon, IconButton, IconSize, ListItem, Popover,
|
||||
Tooltip,
|
||||
h_stack, prelude::*, ButtonSize, ButtonStyle, IconButton, IconName, IconSize, ListItem,
|
||||
Popover, Tooltip,
|
||||
};
|
||||
use util::{post_inc, RangeExt, ResultExt, TryFutureExt};
|
||||
use workspace::{searchable::SearchEvent, ItemNavHistory, Pane, SplitDirection, ViewId, Workspace};
|
||||
@@ -507,7 +507,7 @@ pub enum SoftWrap {
|
||||
Column(u32),
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
#[derive(Clone)]
|
||||
pub struct EditorStyle {
|
||||
pub background: Hsla,
|
||||
pub local_player: PlayerColor,
|
||||
@@ -519,6 +519,24 @@ pub struct EditorStyle {
|
||||
pub suggestions_style: HighlightStyle,
|
||||
}
|
||||
|
||||
impl Default for EditorStyle {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
background: Hsla::default(),
|
||||
local_player: PlayerColor::default(),
|
||||
text: TextStyle::default(),
|
||||
scrollbar_width: Pixels::default(),
|
||||
syntax: Default::default(),
|
||||
// HACK: Status colors don't have a real default.
|
||||
// We should look into removing the status colors from the editor
|
||||
// style and retrieve them directly from the theme.
|
||||
status: StatusColors::dark(),
|
||||
inlays_style: HighlightStyle::default(),
|
||||
suggestions_style: HighlightStyle::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type CompletionId = usize;
|
||||
|
||||
// type GetFieldEditorTheme = dyn Fn(&theme::Theme) -> theme::FieldEditor;
|
||||
@@ -1811,10 +1829,6 @@ impl Editor {
|
||||
this.end_selection(cx);
|
||||
this.scroll_manager.show_scrollbar(cx);
|
||||
|
||||
// todo!("use a different mechanism")
|
||||
// let editor_created_event = EditorCreated(cx.handle());
|
||||
// cx.emit_global(editor_created_event);
|
||||
|
||||
if mode == EditorMode::Full {
|
||||
let should_auto_hide_scrollbars = cx.should_auto_hide_scrollbars();
|
||||
cx.set_global(ScrollbarAutoHide(should_auto_hide_scrollbars));
|
||||
@@ -4223,7 +4237,7 @@ impl Editor {
|
||||
) -> Option<IconButton> {
|
||||
if self.available_code_actions.is_some() {
|
||||
Some(
|
||||
IconButton::new("code_actions_indicator", ui::Icon::Bolt)
|
||||
IconButton::new("code_actions_indicator", ui::IconName::Bolt)
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_color(Color::Muted)
|
||||
.selected(is_active)
|
||||
@@ -4257,7 +4271,7 @@ impl Editor {
|
||||
fold_data
|
||||
.map(|(fold_status, buffer_row, active)| {
|
||||
(active || gutter_hovered || fold_status == FoldStatus::Folded).then(|| {
|
||||
IconButton::new(ix as usize, ui::Icon::ChevronDown)
|
||||
IconButton::new(ix as usize, ui::IconName::ChevronDown)
|
||||
.on_click(cx.listener(move |editor, _e, cx| match fold_status {
|
||||
FoldStatus::Folded => {
|
||||
editor.unfold_at(&UnfoldAt { buffer_row }, cx);
|
||||
@@ -4269,7 +4283,7 @@ impl Editor {
|
||||
.icon_color(ui::Color::Muted)
|
||||
.icon_size(ui::IconSize::Small)
|
||||
.selected(fold_status == FoldStatus::Folded)
|
||||
.selected_icon(ui::Icon::ChevronRight)
|
||||
.selected_icon(ui::IconName::ChevronRight)
|
||||
.size(ui::ButtonSize::None)
|
||||
})
|
||||
})
|
||||
@@ -7036,7 +7050,7 @@ impl Editor {
|
||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||
let selection = self.selections.newest::<usize>(cx);
|
||||
|
||||
// If there is an active Diagnostic Popover. Jump to it's diagnostic instead.
|
||||
// If there is an active Diagnostic Popover jump to its diagnostic instead.
|
||||
if direction == Direction::Next {
|
||||
if let Some(popover) = self.hover_state.diagnostic_popover.as_ref() {
|
||||
let (group_id, jump_to) = popover.activation_info();
|
||||
@@ -9743,7 +9757,7 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, _is_valid: bool) -> Ren
|
||||
),
|
||||
)
|
||||
.child(
|
||||
IconButton::new(("copy-block", cx.block_id), Icon::Copy)
|
||||
IconButton::new(("copy-block", cx.block_id), IconName::Copy)
|
||||
.icon_color(Color::Muted)
|
||||
.size(ButtonSize::Compact)
|
||||
.style(ButtonStyle::Transparent)
|
||||
|
||||
@@ -539,7 +539,6 @@ fn test_clone(cx: &mut TestAppContext) {
|
||||
);
|
||||
}
|
||||
|
||||
//todo!(editor navigate)
|
||||
#[gpui::test]
|
||||
async fn test_navigation_history(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
@@ -993,7 +992,6 @@ fn test_move_cursor_multibyte(cx: &mut TestAppContext) {
|
||||
});
|
||||
}
|
||||
|
||||
//todo!(finish editor tests)
|
||||
#[gpui::test]
|
||||
fn test_move_cursor_different_line_lengths(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
@@ -1259,7 +1257,6 @@ fn test_prev_next_word_boundary(cx: &mut TestAppContext) {
|
||||
});
|
||||
}
|
||||
|
||||
//todo!(finish editor tests)
|
||||
#[gpui::test]
|
||||
fn test_prev_next_word_bounds_with_soft_wrap(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
@@ -1318,7 +1315,6 @@ fn test_prev_next_word_bounds_with_soft_wrap(cx: &mut TestAppContext) {
|
||||
});
|
||||
}
|
||||
|
||||
//todo!(simulate_resize)
|
||||
#[gpui::test]
|
||||
async fn test_move_start_of_paragraph_end_of_paragraph(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
@@ -2546,7 +2542,6 @@ fn test_delete_line(cx: &mut TestAppContext) {
|
||||
});
|
||||
}
|
||||
|
||||
//todo!(select_anchor_ranges)
|
||||
#[gpui::test]
|
||||
fn test_join_lines_with_single_selection(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
@@ -3114,7 +3109,6 @@ fn test_move_line_up_down_with_blocks(cx: &mut TestAppContext) {
|
||||
});
|
||||
}
|
||||
|
||||
//todo!(test_transpose)
|
||||
#[gpui::test]
|
||||
fn test_transpose(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
@@ -4860,7 +4854,6 @@ async fn test_delete_autoclose_pair(cx: &mut gpui::TestAppContext) {
|
||||
});
|
||||
}
|
||||
|
||||
// todo!(select_anchor_ranges)
|
||||
#[gpui::test]
|
||||
async fn test_snippets(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
@@ -6455,7 +6448,6 @@ fn test_highlighted_ranges(cx: &mut TestAppContext) {
|
||||
});
|
||||
}
|
||||
|
||||
// todo!(following)
|
||||
#[gpui::test]
|
||||
async fn test_following(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
@@ -7094,7 +7086,6 @@ async fn test_move_to_enclosing_bracket(cx: &mut gpui::TestAppContext) {
|
||||
);
|
||||
}
|
||||
|
||||
// todo!(completions)
|
||||
#[gpui::test(iterations = 10)]
|
||||
async fn test_copilot(executor: BackgroundExecutor, cx: &mut gpui::TestAppContext) {
|
||||
// flaky
|
||||
|
||||
@@ -28,7 +28,7 @@ use gpui::{
|
||||
AnchorCorner, AnyElement, AvailableSpace, BorrowWindow, Bounds, ContentMask, Corners,
|
||||
CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Hsla, InteractiveBounds,
|
||||
InteractiveElement, IntoElement, ModifiersChangedEvent, MouseButton, MouseDownEvent,
|
||||
MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, ScrollWheelEvent, ShapedLine,
|
||||
MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine,
|
||||
SharedString, Size, StackingOrder, StatefulInteractiveElement, Style, Styled, TextRun,
|
||||
TextStyle, View, ViewContext, WindowContext,
|
||||
};
|
||||
@@ -581,41 +581,6 @@ impl EditorElement {
|
||||
}
|
||||
}
|
||||
|
||||
fn scroll(
|
||||
editor: &mut Editor,
|
||||
event: &ScrollWheelEvent,
|
||||
position_map: &PositionMap,
|
||||
bounds: &InteractiveBounds,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) {
|
||||
if !bounds.visibly_contains(&event.position, cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
let line_height = position_map.line_height;
|
||||
let max_glyph_width = position_map.em_width;
|
||||
let (delta, axis) = match event.delta {
|
||||
gpui::ScrollDelta::Pixels(mut pixels) => {
|
||||
//Trackpad
|
||||
let axis = position_map.snapshot.ongoing_scroll.filter(&mut pixels);
|
||||
(pixels, axis)
|
||||
}
|
||||
|
||||
gpui::ScrollDelta::Lines(lines) => {
|
||||
//Not trackpad
|
||||
let pixels = point(lines.x * max_glyph_width, lines.y * line_height);
|
||||
(pixels, None)
|
||||
}
|
||||
};
|
||||
|
||||
let scroll_position = position_map.snapshot.scroll_position();
|
||||
let x = f32::from((scroll_position.x * max_glyph_width - delta.x) / max_glyph_width);
|
||||
let y = f32::from((scroll_position.y * line_height - delta.y) / line_height);
|
||||
let scroll_position = point(x, y).clamp(&point(0., 0.), &position_map.scroll_max);
|
||||
editor.scroll(scroll_position, axis, cx);
|
||||
cx.stop_propagation();
|
||||
}
|
||||
|
||||
fn paint_background(
|
||||
&self,
|
||||
gutter_bounds: Bounds<Pixels>,
|
||||
@@ -839,9 +804,22 @@ impl EditorElement {
|
||||
|
||||
let start_row = display_row_range.start;
|
||||
let end_row = display_row_range.end;
|
||||
// If we're in a multibuffer, row range span might include an
|
||||
// excerpt header, so if we were to draw the marker straight away,
|
||||
// the hunk might include the rows of that header.
|
||||
// Making the range inclusive doesn't quite cut it, as we rely on the exclusivity for the soft wrap.
|
||||
// Instead, we simply check whether the range we're dealing with includes
|
||||
// any custom elements and if so, we stop painting the diff hunk on the first row of that custom element.
|
||||
let end_row_in_current_excerpt = layout
|
||||
.position_map
|
||||
.snapshot
|
||||
.blocks_in_range(start_row..end_row)
|
||||
.next()
|
||||
.map(|(start_row, _)| start_row)
|
||||
.unwrap_or(end_row);
|
||||
|
||||
let start_y = start_row as f32 * line_height - scroll_top;
|
||||
let end_y = end_row as f32 * line_height - scroll_top;
|
||||
let end_y = end_row_in_current_excerpt as f32 * line_height - scroll_top;
|
||||
|
||||
let width = 0.275 * line_height;
|
||||
let highlight_origin = bounds.origin + point(-width, start_y);
|
||||
@@ -2450,6 +2428,64 @@ impl EditorElement {
|
||||
)
|
||||
}
|
||||
|
||||
fn paint_scroll_wheel_listener(
|
||||
&mut self,
|
||||
interactive_bounds: &InteractiveBounds,
|
||||
layout: &LayoutState,
|
||||
cx: &mut WindowContext,
|
||||
) {
|
||||
cx.on_mouse_event({
|
||||
let position_map = layout.position_map.clone();
|
||||
let editor = self.editor.clone();
|
||||
let interactive_bounds = interactive_bounds.clone();
|
||||
let mut delta = ScrollDelta::default();
|
||||
|
||||
move |event: &ScrollWheelEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& interactive_bounds.visibly_contains(&event.position, cx)
|
||||
{
|
||||
delta = delta.coalesce(event.delta);
|
||||
editor.update(cx, |editor, cx| {
|
||||
let position = event.position;
|
||||
let position_map: &PositionMap = &position_map;
|
||||
let bounds = &interactive_bounds;
|
||||
if !bounds.visibly_contains(&position, cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
let line_height = position_map.line_height;
|
||||
let max_glyph_width = position_map.em_width;
|
||||
let (delta, axis) = match delta {
|
||||
gpui::ScrollDelta::Pixels(mut pixels) => {
|
||||
//Trackpad
|
||||
let axis = position_map.snapshot.ongoing_scroll.filter(&mut pixels);
|
||||
(pixels, axis)
|
||||
}
|
||||
|
||||
gpui::ScrollDelta::Lines(lines) => {
|
||||
//Not trackpad
|
||||
let pixels =
|
||||
point(lines.x * max_glyph_width, lines.y * line_height);
|
||||
(pixels, None)
|
||||
}
|
||||
};
|
||||
|
||||
let scroll_position = position_map.snapshot.scroll_position();
|
||||
let x = f32::from(
|
||||
(scroll_position.x * max_glyph_width - delta.x) / max_glyph_width,
|
||||
);
|
||||
let y =
|
||||
f32::from((scroll_position.y * line_height - delta.y) / line_height);
|
||||
let scroll_position =
|
||||
point(x, y).clamp(&point(0., 0.), &position_map.scroll_max);
|
||||
editor.scroll(scroll_position, axis, cx);
|
||||
cx.stop_propagation();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn paint_mouse_listeners(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
@@ -2463,21 +2499,7 @@ impl EditorElement {
|
||||
stacking_order: cx.stacking_order().clone(),
|
||||
};
|
||||
|
||||
cx.on_mouse_event({
|
||||
let position_map = layout.position_map.clone();
|
||||
let editor = self.editor.clone();
|
||||
let interactive_bounds = interactive_bounds.clone();
|
||||
|
||||
move |event: &ScrollWheelEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& interactive_bounds.visibly_contains(&event.position, cx)
|
||||
{
|
||||
editor.update(cx, |editor, cx| {
|
||||
Self::scroll(editor, event, &position_map, &interactive_bounds, cx)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
self.paint_scroll_wheel_listener(&interactive_bounds, layout, cx);
|
||||
|
||||
cx.on_mouse_event({
|
||||
let position_map = layout.position_map.clone();
|
||||
|
||||
@@ -16,7 +16,7 @@ use lsp::DiagnosticSeverity;
|
||||
use project::{HoverBlock, HoverBlockKind, InlayHintLabelPart, Project};
|
||||
use settings::Settings;
|
||||
use std::{ops::Range, sync::Arc, time::Duration};
|
||||
use ui::{StyledExt, Tooltip};
|
||||
use ui::{prelude::*, Tooltip};
|
||||
use util::TryFutureExt;
|
||||
use workspace::Workspace;
|
||||
|
||||
@@ -514,6 +514,8 @@ impl DiagnosticPopover {
|
||||
None => self.local_diagnostic.diagnostic.message.clone(),
|
||||
};
|
||||
|
||||
let status_colors = cx.theme().status();
|
||||
|
||||
struct DiagnosticColors {
|
||||
pub background: Hsla,
|
||||
pub border: Hsla,
|
||||
@@ -521,24 +523,24 @@ impl DiagnosticPopover {
|
||||
|
||||
let diagnostic_colors = match self.local_diagnostic.diagnostic.severity {
|
||||
DiagnosticSeverity::ERROR => DiagnosticColors {
|
||||
background: style.status.error_background,
|
||||
border: style.status.error_border,
|
||||
background: status_colors.error_background,
|
||||
border: status_colors.error_border,
|
||||
},
|
||||
DiagnosticSeverity::WARNING => DiagnosticColors {
|
||||
background: style.status.warning_background,
|
||||
border: style.status.warning_border,
|
||||
background: status_colors.warning_background,
|
||||
border: status_colors.warning_border,
|
||||
},
|
||||
DiagnosticSeverity::INFORMATION => DiagnosticColors {
|
||||
background: style.status.info_background,
|
||||
border: style.status.info_border,
|
||||
background: status_colors.info_background,
|
||||
border: status_colors.info_border,
|
||||
},
|
||||
DiagnosticSeverity::HINT => DiagnosticColors {
|
||||
background: style.status.hint_background,
|
||||
border: style.status.hint_border,
|
||||
background: status_colors.hint_background,
|
||||
border: status_colors.hint_border,
|
||||
},
|
||||
_ => DiagnosticColors {
|
||||
background: style.status.ignored_background,
|
||||
border: style.status.ignored_border,
|
||||
background: status_colors.ignored_background,
|
||||
border: status_colors.ignored_border,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ pub fn up_by_rows(
|
||||
text_layout_details: &TextLayoutDetails,
|
||||
) -> (DisplayPoint, SelectionGoal) {
|
||||
let mut goal_x = match goal {
|
||||
SelectionGoal::HorizontalPosition(x) => x.into(), // todo!("Can the fields in SelectionGoal by Pixels? We should extract a geometry crate and depend on that.")
|
||||
SelectionGoal::HorizontalPosition(x) => x.into(),
|
||||
SelectionGoal::WrappedHorizontalPosition((_, x)) => x.into(),
|
||||
SelectionGoal::HorizontalRange { end, .. } => end.into(),
|
||||
_ => map.x_for_display_point(start, text_layout_details),
|
||||
|
||||
@@ -384,10 +384,12 @@ impl Editor {
|
||||
) {
|
||||
hide_hover(self, cx);
|
||||
let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1);
|
||||
let top_row = scroll_anchor
|
||||
.anchor
|
||||
.to_point(&self.buffer().read(cx).snapshot(cx))
|
||||
.row;
|
||||
let snapshot = &self.buffer().read(cx).snapshot(cx);
|
||||
if !scroll_anchor.anchor.is_valid(snapshot) {
|
||||
log::warn!("Invalid scroll anchor: {:?}", scroll_anchor);
|
||||
return;
|
||||
}
|
||||
let top_row = scroll_anchor.anchor.to_point(snapshot).row;
|
||||
self.scroll_manager
|
||||
.set_anchor(scroll_anchor, top_row, false, false, workspace_id, cx);
|
||||
}
|
||||
|
||||
@@ -11,10 +11,9 @@ impl Editor {
|
||||
return;
|
||||
}
|
||||
|
||||
// todo!()
|
||||
// if self.mouse_context_menu.read(cx).visible() {
|
||||
// return None;
|
||||
// }
|
||||
if self.mouse_context_menu.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
cx.propagate();
|
||||
|
||||
@@ -60,8 +60,7 @@ pub fn assert_text_with_selections(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub(crate) fn build_editor(buffer: Model<MultiBuffer>, cx: &mut ViewContext<Editor>) -> Editor {
|
||||
// todo!()
|
||||
Editor::new(EditorMode::Full, buffer, None, /*None,*/ cx)
|
||||
Editor::new(EditorMode::Full, buffer, None, cx)
|
||||
}
|
||||
|
||||
pub(crate) fn build_editor_with_project(
|
||||
@@ -69,6 +68,5 @@ pub(crate) fn build_editor_with_project(
|
||||
buffer: Model<MultiBuffer>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) -> Editor {
|
||||
// todo!()
|
||||
Editor::new(EditorMode::Full, buffer, Some(project), /*None,*/ cx)
|
||||
Editor::new(EditorMode::Full, buffer, Some(project), cx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user