@@ -22,7 +22,7 @@ mod editor_tests;
pub mod test;
use ::git::diff::DiffHunk;
use aho_corasick::AhoCorasick;
-use anyhow::{Context as _, Result};
+use anyhow::{anyhow, Context as _, Result};
use blink_manager::BlinkManager;
use client::{ClickhouseEvent, Client, Collaborator, ParticipantIndex, TelemetrySettings};
use clock::ReplicaId;
@@ -43,8 +43,8 @@ use gpui::{
AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Component, Context,
EventEmitter, FocusHandle, FontFeatures, FontStyle, FontWeight, HighlightStyle, Hsla,
InputHandler, KeyContext, Model, MouseButton, ParentElement, Pixels, Render,
- StatelessInteractive, Styled, Subscription, Task, TextStyle, UniformListScrollHandle, View,
- ViewContext, VisualContext, WeakView, WindowContext,
+ StatefulInteractive, StatelessInteractive, Styled, Subscription, Task, TextStyle,
+ UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WindowContext,
};
use highlight_matching_bracket::refresh_matching_bracket_highlights;
use hover_popover::{hide_hover, HoverState};
@@ -69,7 +69,7 @@ pub use multi_buffer::{
};
use ordered_float::OrderedFloat;
use parking_lot::{Mutex, RwLock};
-use project::{FormatTrigger, Location, Project, ProjectTransaction};
+use project::{FormatTrigger, Location, Project, ProjectPath, ProjectTransaction};
use rand::prelude::*;
use rpc::proto::*;
use scroll::{
@@ -97,7 +97,7 @@ use text::{OffsetUtf16, Rope};
use theme::{
ActiveTheme, DiagnosticStyle, PlayerColor, SyntaxTheme, Theme, ThemeColors, ThemeSettings,
};
-use ui::{IconButton, StyledExt};
+use ui::{v_stack, HighlightedLabel, IconButton, StyledExt, TextTooltip};
use util::{post_inc, RangeExt, ResultExt, TryFutureExt};
use workspace::{
item::ItemEvent, searchable::SearchEvent, ItemNavHistory, SplitDirection, ViewId, Workspace,
@@ -7588,53 +7588,47 @@ impl Editor {
})
}
- // pub fn find_all_references(
- // workspace: &mut Workspace,
- // _: &FindAllReferences,
- // cx: &mut ViewContext<Workspace>,
- // ) -> Option<Task<Result<()>>> {
- // let active_item = workspace.active_item(cx)?;
- // let editor_handle = active_item.act_as::<Self>(cx)?;
-
- // let editor = editor_handle.read(cx);
- // let buffer = editor.buffer.read(cx);
- // let head = editor.selections.newest::<usize>(cx).head();
- // let (buffer, head) = buffer.text_anchor_for_position(head, cx)?;
- // let replica_id = editor.replica_id(cx);
-
- // let project = workspace.project().clone();
- // let references = project.update(cx, |project, cx| project.references(&buffer, head, cx));
- // Some(cx.spawn_labeled(
- // "Finding All References...",
- // |workspace, mut cx| async move {
- // let locations = references.await?;
- // if locations.is_empty() {
- // return Ok(());
- // }
+ pub fn find_all_references(
+ &mut self,
+ _: &FindAllReferences,
+ cx: &mut ViewContext<Self>,
+ ) -> Option<Task<Result<()>>> {
+ let buffer = self.buffer.read(cx);
+ let head = self.selections.newest::<usize>(cx).head();
+ let (buffer, head) = buffer.text_anchor_for_position(head, cx)?;
+ let replica_id = self.replica_id(cx);
- // workspace.update(&mut cx, |workspace, cx| {
- // let title = locations
- // .first()
- // .as_ref()
- // .map(|location| {
- // let buffer = location.buffer.read(cx);
- // format!(
- // "References to `{}`",
- // buffer
- // .text_for_range(location.range.clone())
- // .collect::<String>()
- // )
- // })
- // .unwrap();
- // Self::open_locations_in_multibuffer(
- // workspace, locations, replica_id, title, false, cx,
- // );
- // })?;
+ let workspace = self.workspace()?;
+ let project = workspace.read(cx).project().clone();
+ let references = project.update(cx, |project, cx| project.references(&buffer, head, cx));
+ Some(cx.spawn(|_, mut cx| async move {
+ let locations = references.await?;
+ if locations.is_empty() {
+ return Ok(());
+ }
+
+ workspace.update(&mut cx, |workspace, cx| {
+ let title = locations
+ .first()
+ .as_ref()
+ .map(|location| {
+ let buffer = location.buffer.read(cx);
+ format!(
+ "References to `{}`",
+ buffer
+ .text_for_range(location.range.clone())
+ .collect::<String>()
+ )
+ })
+ .unwrap();
+ Self::open_locations_in_multibuffer(
+ workspace, locations, replica_id, title, false, cx,
+ );
+ })?;
- // Ok(())
- // },
- // ))
- // }
+ Ok(())
+ }))
+ }
/// Opens a multibuffer with the given project locations in it
pub fn open_locations_in_multibuffer(
@@ -7685,7 +7679,7 @@ impl Editor {
editor.update(cx, |editor, cx| {
editor.highlight_background::<Self>(
ranges_to_highlight,
- |theme| todo!("theme.editor.highlighted_line_background"),
+ |theme| theme.editor_highlighted_line_background,
cx,
);
});
@@ -8869,46 +8863,50 @@ impl Editor {
// });
// }
- // fn jump(
- // workspace: &mut Workspace,
- // path: ProjectPath,
- // position: Point,
- // anchor: language::Anchor,
- // cx: &mut ViewContext<Workspace>,
- // ) {
- // let editor = workspace.open_path(path, None, true, cx);
- // cx.spawn(|_, mut cx| async move {
- // let editor = editor
- // .await?
- // .downcast::<Editor>()
- // .ok_or_else(|| anyhow!("opened item was not an editor"))?
- // .downgrade();
- // editor.update(&mut cx, |editor, cx| {
- // let buffer = editor
- // .buffer()
- // .read(cx)
- // .as_singleton()
- // .ok_or_else(|| anyhow!("cannot jump in a multi-buffer"))?;
- // let buffer = buffer.read(cx);
- // let cursor = if buffer.can_resolve(&anchor) {
- // language::ToPoint::to_point(&anchor, buffer)
- // } else {
- // buffer.clip_point(position, Bias::Left)
- // };
+ fn jump(
+ &mut self,
+ path: ProjectPath,
+ position: Point,
+ anchor: language::Anchor,
+ cx: &mut ViewContext<Self>,
+ ) {
+ let workspace = self.workspace();
+ cx.spawn(|_, mut cx| async move {
+ let workspace = workspace.ok_or_else(|| anyhow!("cannot jump without workspace"))?;
+ let editor = workspace.update(&mut cx, |workspace, cx| {
+ workspace.open_path(path, None, true, cx)
+ })?;
+ let editor = editor
+ .await?
+ .downcast::<Editor>()
+ .ok_or_else(|| anyhow!("opened item was not an editor"))?
+ .downgrade();
+ editor.update(&mut cx, |editor, cx| {
+ let buffer = editor
+ .buffer()
+ .read(cx)
+ .as_singleton()
+ .ok_or_else(|| anyhow!("cannot jump in a multi-buffer"))?;
+ let buffer = buffer.read(cx);
+ let cursor = if buffer.can_resolve(&anchor) {
+ language::ToPoint::to_point(&anchor, buffer)
+ } else {
+ buffer.clip_point(position, Bias::Left)
+ };
- // let nav_history = editor.nav_history.take();
- // editor.change_selections(Some(Autoscroll::newest()), cx, |s| {
- // s.select_ranges([cursor..cursor]);
- // });
- // editor.nav_history = nav_history;
+ let nav_history = editor.nav_history.take();
+ editor.change_selections(Some(Autoscroll::newest()), cx, |s| {
+ s.select_ranges([cursor..cursor]);
+ });
+ editor.nav_history = nav_history;
- // anyhow::Ok(())
- // })??;
+ anyhow::Ok(())
+ })??;
- // anyhow::Ok(())
- // })
- // .detach_and_log_err(cx);
- // }
+ anyhow::Ok(())
+ })
+ .detach_and_log_err(cx);
+ }
fn marked_text_ranges(&self, cx: &AppContext) -> Option<Vec<Range<OffsetUtf16>>> {
let snapshot = self.buffer.read(cx).read(cx);
@@ -9973,43 +9971,22 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend
}
let message = diagnostic.message;
Arc::new(move |cx: &mut BlockContext| {
- todo!()
- // let message = message.clone();
- // let settings = ThemeSettings::get_global(cx);
- // let tooltip_style = settings.theme.tooltip.clone();
- // let theme = &settings.theme.editor;
- // let style = diagnostic_style(diagnostic.severity, is_valid, theme);
- // let font_size = (style.text_scale_factor * settings.buffer_font_size(cx)).round();
- // let anchor_x = cx.anchor_x;
- // enum BlockContextToolip {}
- // MouseEventHandler::new::<BlockContext, _>(cx.block_id, cx, |_, _| {
- // Flex::column()
- // .with_children(highlighted_lines.iter().map(|(line, highlights)| {
- // Label::new(
- // line.clone(),
- // style.message.clone().with_font_size(font_size),
- // )
- // .with_highlights(highlights.clone())
- // .contained()
- // .with_margin_left(anchor_x)
- // }))
- // .aligned()
- // .left()
- // .into_any()
- // })
- // .with_cursor_style(CursorStyle::PointingHand)
- // .on_click(MouseButton::Left, move |_, _, cx| {
- // cx.write_to_clipboard(ClipboardItem::new(message.clone()));
- // })
- // // We really need to rethink this ID system...
- // .with_tooltip::<BlockContextToolip>(
- // cx.block_id,
- // "Copy diagnostic message",
- // None,
- // tooltip_style,
- // cx,
- // )
- // .into_any()
+ let message = message.clone();
+ v_stack()
+ .id(cx.block_id)
+ .size_full()
+ .bg(gpui::red())
+ .children(highlighted_lines.iter().map(|(line, highlights)| {
+ div()
+ .child(HighlightedLabel::new(line.clone(), highlights.clone()))
+ .ml(cx.anchor_x)
+ }))
+ .cursor_pointer()
+ .on_click(move |_, _, cx| {
+ cx.write_to_clipboard(ClipboardItem::new(message.clone()));
+ })
+ .tooltip(|_, cx| cx.build_view(|cx| TextTooltip::new("Copy diagnostic message")))
+ .render()
})
}
@@ -1,5 +1,8 @@
use crate::{
- display_map::{BlockStyle, DisplaySnapshot, FoldStatus, HighlightedChunk, ToDisplayPoint},
+ display_map::{
+ BlockContext, BlockStyle, DisplaySnapshot, FoldStatus, HighlightedChunk, ToDisplayPoint,
+ TransformBlock,
+ },
editor_settings::ShowScrollbar,
git::{diff_hunk_to_display, DisplayDiffHunk},
hover_popover::hover_at,
@@ -15,17 +18,19 @@ use crate::{
use anyhow::Result;
use collections::{BTreeMap, HashMap};
use gpui::{
- black, hsla, point, px, relative, size, transparent_black, Action, AnyElement, AvailableSpace,
- BorrowAppContext, BorrowWindow, Bounds, ContentMask, Corners, DispatchPhase, Edges, Element,
- ElementId, ElementInputHandler, Entity, FocusHandle, GlobalElementId, Hsla, InputHandler,
- KeyContext, KeyDownEvent, KeyMatch, Line, LineLayout, Modifiers, MouseButton, MouseDownEvent,
- MouseMoveEvent, MouseUpEvent, Pixels, ScrollWheelEvent, ShapedGlyph, Size, Style, TextRun,
- TextStyle, TextSystem, ViewContext, WindowContext, WrappedLineLayout,
+ point, px, relative, size, transparent_black, Action, AnyElement, AvailableSpace, BorrowWindow,
+ Bounds, Component, ContentMask, Corners, DispatchPhase, Edges, Element, ElementId,
+ ElementInputHandler, Entity, Hsla, Line, MouseButton, MouseDownEvent, MouseMoveEvent,
+ MouseUpEvent, ParentElement, Pixels, ScrollWheelEvent, Size, Style, Styled, TextRun, TextStyle,
+ ViewContext, WindowContext,
};
use itertools::Itertools;
use language::language_settings::ShowWhitespaceSetting;
use multi_buffer::Anchor;
-use project::project_settings::{GitGutterSetting, ProjectSettings};
+use project::{
+ project_settings::{GitGutterSetting, ProjectSettings},
+ ProjectPath,
+};
use settings::Settings;
use smallvec::SmallVec;
use std::{
@@ -39,6 +44,7 @@ use std::{
};
use sum_tree::Bias;
use theme::{ActiveTheme, PlayerColor};
+use ui::{h_stack, IconButton};
use util::ResultExt;
use workspace::item::Item;
@@ -1171,30 +1177,31 @@ impl EditorElement {
}
}
- // fn paint_blocks(
- // &mut self,
- // bounds: Bounds<Pixels>,
- // visible_bounds: Bounds<Pixels>,
- // layout: &mut LayoutState,
- // editor: &mut Editor,
- // cx: &mut ViewContext<Editor>,
- // ) {
- // let scroll_position = layout.position_map.snapshot.scroll_position();
- // let scroll_left = scroll_position.x * layout.position_map.em_width;
- // let scroll_top = scroll_position.y * layout.position_map.line_height;
-
- // for block in &mut layout.blocks {
- // let mut origin = bounds.origin
- // + point(
- // 0.,
- // block.row as f32 * layout.position_map.line_height - scroll_top,
- // );
- // if !matches!(block.style, BlockStyle::Sticky) {
- // origin += point(-scroll_left, 0.);
- // }
- // block.element.paint(origin, visible_bounds, editor, cx);
- // }
- // }
+ fn paint_blocks(
+ &mut self,
+ bounds: Bounds<Pixels>,
+ layout: &mut LayoutState,
+ editor: &mut Editor,
+ cx: &mut ViewContext<Editor>,
+ ) {
+ let scroll_position = layout.position_map.snapshot.scroll_position();
+ let scroll_left = scroll_position.x * layout.position_map.em_width;
+ let scroll_top = scroll_position.y * layout.position_map.line_height;
+
+ for block in &mut layout.blocks {
+ let mut origin = bounds.origin
+ + point(
+ Pixels::ZERO,
+ block.row as f32 * layout.position_map.line_height - scroll_top,
+ );
+ if !matches!(block.style, BlockStyle::Sticky) {
+ origin += point(-scroll_left, Pixels::ZERO);
+ }
+ block
+ .element
+ .draw(origin, block.available_space, editor, cx);
+ }
+ }
fn column_pixels(&self, column: usize, cx: &ViewContext<Editor>) -> Pixels {
let style = &self.style;
@@ -1741,22 +1748,22 @@ impl EditorElement {
.unwrap()
.width;
let scroll_width = longest_line_width.max(max_visible_line_width) + overscroll.width;
- // todo!("blocks")
- // let (scroll_width, blocks) = self.layout_blocks(
- // start_row..end_row,
- // &snapshot,
- // size.x,
- // scroll_width,
- // gutter_padding,
- // gutter_width,
- // em_width,
- // gutter_width + gutter_margin,
- // line_height,
- // &style,
- // &line_layouts,
- // editor,
- // cx,
- // );
+
+ let (scroll_width, blocks) = self.layout_blocks(
+ start_row..end_row,
+ &snapshot,
+ bounds.size.width,
+ scroll_width,
+ gutter_padding,
+ gutter_width,
+ em_width,
+ gutter_width + gutter_margin,
+ line_height,
+ &style,
+ &line_layouts,
+ editor,
+ cx,
+ );
let scroll_max = point(
f32::from((scroll_width - text_size.width) / em_width).max(0.0),
@@ -1937,7 +1944,7 @@ impl EditorElement {
fold_ranges,
line_number_layouts,
display_hunks,
- // blocks,
+ blocks,
selections,
context_menu,
code_actions_indicator,
@@ -1948,226 +1955,177 @@ impl EditorElement {
}
}
- // #[allow(clippy::too_many_arguments)]
- // fn layout_blocks(
- // &mut self,
- // rows: Range<u32>,
- // snapshot: &EditorSnapshot,
- // editor_width: f32,
- // scroll_width: f32,
- // gutter_padding: f32,
- // gutter_width: f32,
- // em_width: f32,
- // text_x: f32,
- // line_height: f32,
- // style: &EditorStyle,
- // line_layouts: &[LineWithInvisibles],
- // editor: &mut Editor,
- // cx: &mut ViewContext<Editor>,
- // ) -> (f32, Vec<BlockLayout>) {
- // let mut block_id = 0;
- // let scroll_x = snapshot.scroll_anchor.offset.x;
- // let (fixed_blocks, non_fixed_blocks) = snapshot
- // .blocks_in_range(rows.clone())
- // .partition::<Vec<_>, _>(|(_, block)| match block {
- // TransformBlock::ExcerptHeader { .. } => false,
- // TransformBlock::Custom(block) => block.style() == BlockStyle::Fixed,
- // });
- // let mut render_block = |block: &TransformBlock, width: f32, block_id: usize| {
- // let mut element = match block {
- // TransformBlock::Custom(block) => {
- // let align_to = block
- // .position()
- // .to_point(&snapshot.buffer_snapshot)
- // .to_display_point(snapshot);
- // let anchor_x = text_x
- // + if rows.contains(&align_to.row()) {
- // line_layouts[(align_to.row() - rows.start) as usize]
- // .line
- // .x_for_index(align_to.column() as usize)
- // } else {
- // layout_line(align_to.row(), snapshot, style, cx.text_layout_cache())
- // .x_for_index(align_to.column() as usize)
- // };
-
- // block.render(&mut BlockContext {
- // view_context: cx,
- // anchor_x,
- // gutter_padding,
- // line_height,
- // scroll_x,
- // gutter_width,
- // em_width,
- // block_id,
- // })
- // }
- // TransformBlock::ExcerptHeader {
- // id,
- // buffer,
- // range,
- // starts_new_buffer,
- // ..
- // } => {
- // let tooltip_style = theme::current(cx).tooltip.clone();
- // let include_root = editor
- // .project
- // .as_ref()
- // .map(|project| project.read(cx).visible_worktrees(cx).count() > 1)
- // .unwrap_or_default();
- // let jump_icon = project::File::from_dyn(buffer.file()).map(|file| {
- // let jump_path = ProjectPath {
- // worktree_id: file.worktree_id(cx),
- // path: file.path.clone(),
- // };
- // let jump_anchor = range
- // .primary
- // .as_ref()
- // .map_or(range.context.start, |primary| primary.start);
- // let jump_position = language::ToPoint::to_point(&jump_anchor, buffer);
-
- // enum JumpIcon {}
- // MouseEventHandler::new::<JumpIcon, _>((*id).into(), cx, |state, _| {
- // let style = style.jump_icon.style_for(state);
- // Svg::new("icons/arrow_up_right.svg")
- // .with_color(style.color)
- // .constrained()
- // .with_width(style.icon_width)
- // .aligned()
- // .contained()
- // .with_style(style.container)
- // .constrained()
- // .with_width(style.button_width)
- // .with_height(style.button_width)
- // })
- // .with_cursor_style(CursorStyle::PointingHand)
- // .on_click(MouseButton::Left, move |_, editor, cx| {
- // if let Some(workspace) = editor
- // .workspace
- // .as_ref()
- // .and_then(|(workspace, _)| workspace.upgrade(cx))
- // {
- // workspace.update(cx, |workspace, cx| {
- // Editor::jump(
- // workspace,
- // jump_path.clone(),
- // jump_position,
- // jump_anchor,
- // cx,
- // );
- // });
- // }
- // })
- // .with_tooltip::<JumpIcon>(
- // (*id).into(),
- // "Jump to Buffer".to_string(),
- // Some(Box::new(crate::OpenExcerpts)),
- // tooltip_style.clone(),
- // cx,
- // )
- // .aligned()
- // .flex_float()
- // });
-
- // if *starts_new_buffer {
- // let editor_font_size = style.text.font_size;
- // let style = &style.diagnostic_path_header;
- // let font_size = (style.text_scale_factor * editor_font_size).round();
-
- // let path = buffer.resolve_file_path(cx, include_root);
- // let mut filename = None;
- // let mut parent_path = None;
- // // Can't use .and_then() because `.file_name()` and `.parent()` return references :(
- // if let Some(path) = path {
- // filename = path.file_name().map(|f| f.to_string_lossy.to_string());
- // parent_path =
- // path.parent().map(|p| p.to_string_lossy.to_string() + "/");
- // }
+ #[allow(clippy::too_many_arguments)]
+ fn layout_blocks(
+ &mut self,
+ rows: Range<u32>,
+ snapshot: &EditorSnapshot,
+ editor_width: Pixels,
+ scroll_width: Pixels,
+ gutter_padding: Pixels,
+ gutter_width: Pixels,
+ em_width: Pixels,
+ text_x: Pixels,
+ line_height: Pixels,
+ style: &EditorStyle,
+ line_layouts: &[LineWithInvisibles],
+ editor: &mut Editor,
+ cx: &mut ViewContext<Editor>,
+ ) -> (Pixels, Vec<BlockLayout>) {
+ let mut block_id = 0;
+ let scroll_x = snapshot.scroll_anchor.offset.x;
+ let (fixed_blocks, non_fixed_blocks) = snapshot
+ .blocks_in_range(rows.clone())
+ .partition::<Vec<_>, _>(|(_, block)| match block {
+ TransformBlock::ExcerptHeader { .. } => false,
+ TransformBlock::Custom(block) => block.style() == BlockStyle::Fixed,
+ });
+ let mut render_block = |block: &TransformBlock,
+ available_space: Size<AvailableSpace>,
+ block_id: usize,
+ editor: &mut Editor,
+ cx: &mut ViewContext<Editor>| {
+ let mut element = match block {
+ TransformBlock::Custom(block) => {
+ let align_to = block
+ .position()
+ .to_point(&snapshot.buffer_snapshot)
+ .to_display_point(snapshot);
+ let anchor_x = text_x
+ + if rows.contains(&align_to.row()) {
+ line_layouts[(align_to.row() - rows.start) as usize]
+ .line
+ .x_for_index(align_to.column() as usize)
+ } else {
+ layout_line(align_to.row(), snapshot, style, cx)
+ .unwrap()
+ .x_for_index(align_to.column() as usize)
+ };
+
+ block.render(&mut BlockContext {
+ view_context: cx,
+ anchor_x,
+ gutter_padding,
+ line_height,
+ // scroll_x,
+ gutter_width,
+ em_width,
+ block_id,
+ })
+ }
+ TransformBlock::ExcerptHeader {
+ id,
+ buffer,
+ range,
+ starts_new_buffer,
+ ..
+ } => {
+ let include_root = editor
+ .project
+ .as_ref()
+ .map(|project| project.read(cx).visible_worktrees(cx).count() > 1)
+ .unwrap_or_default();
+ let jump_icon = project::File::from_dyn(buffer.file()).map(|file| {
+ let jump_path = ProjectPath {
+ worktree_id: file.worktree_id(cx),
+ path: file.path.clone(),
+ };
+ let jump_anchor = range
+ .primary
+ .as_ref()
+ .map_or(range.context.start, |primary| primary.start);
+ let jump_position = language::ToPoint::to_point(&jump_anchor, buffer);
+
+ // todo!("avoid ElementId collision risk here")
+ let icon_button_id: usize = id.clone().into();
+ IconButton::new(icon_button_id, ui::Icon::ArrowUpRight)
+ .on_click(move |editor: &mut Editor, cx| {
+ editor.jump(jump_path.clone(), jump_position, jump_anchor, cx);
+ })
+ .tooltip("Jump to Buffer") // todo!(pass an action as well to show key binding)
+ });
- // Flex::row()
- // .with_child(
- // Label::new(
- // filename.unwrap_or_else(|| "untitled".to_string()),
- // style.filename.text.clone().with_font_size(font_size),
- // )
- // .contained()
- // .with_style(style.filename.container)
- // .aligned(),
- // )
- // .with_children(parent_path.map(|path| {
- // Label::new(path, style.path.text.clone().with_font_size(font_size))
- // .contained()
- // .with_style(style.path.container)
- // .aligned()
- // }))
- // .with_children(jump_icon)
- // .contained()
- // .with_style(style.container)
- // .with_padding_left(gutter_padding)
- // .with_padding_right(gutter_padding)
- // .expanded()
- // .into_any_named("path header block")
- // } else {
- // let text_style = style.text.clone();
- // Flex::row()
- // .with_child(Label::new("⋯", text_style))
- // .with_children(jump_icon)
- // .contained()
- // .with_padding_left(gutter_padding)
- // .with_padding_right(gutter_padding)
- // .expanded()
- // .into_any_named("collapsed context")
- // }
- // }
- // };
-
- // element.layout(
- // SizeConstraint {
- // min: gpui::Point::<Pixels>::zero(),
- // max: point(width, block.height() as f32 * line_height),
- // },
- // editor,
- // cx,
- // );
- // element
- // };
-
- // let mut fixed_block_max_width = 0f32;
- // let mut blocks = Vec::new();
- // for (row, block) in fixed_blocks {
- // let element = render_block(block, f32::INFINITY, block_id);
- // block_id += 1;
- // fixed_block_max_width = fixed_block_max_width.max(element.size().x + em_width);
- // blocks.push(BlockLayout {
- // row,
- // element,
- // style: BlockStyle::Fixed,
- // });
- // }
- // for (row, block) in non_fixed_blocks {
- // let style = match block {
- // TransformBlock::Custom(block) => block.style(),
- // TransformBlock::ExcerptHeader { .. } => BlockStyle::Sticky,
- // };
- // let width = match style {
- // BlockStyle::Sticky => editor_width,
- // BlockStyle::Flex => editor_width
- // .max(fixed_block_max_width)
- // .max(gutter_width + scroll_width),
- // BlockStyle::Fixed => unreachable!(),
- // };
- // let element = render_block(block, width, block_id);
- // block_id += 1;
- // blocks.push(BlockLayout {
- // row,
- // element,
- // style,
- // });
- // }
- // (
- // scroll_width.max(fixed_block_max_width - gutter_width),
- // blocks,
- // )
- // }
+ let element = if *starts_new_buffer {
+ let path = buffer.resolve_file_path(cx, include_root);
+ let mut filename = None;
+ let mut parent_path = None;
+ // Can't use .and_then() because `.file_name()` and `.parent()` return references :(
+ if let Some(path) = path {
+ filename = path.file_name().map(|f| f.to_string_lossy().to_string());
+ parent_path =
+ path.parent().map(|p| p.to_string_lossy().to_string() + "/");
+ }
+
+ h_stack()
+ .size_full()
+ .bg(gpui::red())
+ .child(filename.unwrap_or_else(|| "untitled".to_string()))
+ .children(parent_path)
+ .children(jump_icon) // .p_x(gutter_padding)
+ } else {
+ let text_style = style.text.clone();
+ h_stack()
+ .size_full()
+ .bg(gpui::red())
+ .child("⋯")
+ .children(jump_icon) // .p_x(gutter_padding)
+ };
+ element.render()
+ }
+ };
+
+ let size = element.measure(available_space, editor, cx);
+ (element, size)
+ };
+
+ let mut fixed_block_max_width = Pixels::ZERO;
+ let mut blocks = Vec::new();
+ for (row, block) in fixed_blocks {
+ let available_space = size(
+ AvailableSpace::MinContent,
+ AvailableSpace::Definite(block.height() as f32 * line_height),
+ );
+ let (element, element_size) =
+ render_block(block, available_space, block_id, editor, cx);
+ block_id += 1;
+ fixed_block_max_width = fixed_block_max_width.max(element_size.width + em_width);
+ blocks.push(BlockLayout {
+ row,
+ element,
+ available_space,
+ style: BlockStyle::Fixed,
+ });
+ }
+ for (row, block) in non_fixed_blocks {
+ let style = match block {
+ TransformBlock::Custom(block) => block.style(),
+ TransformBlock::ExcerptHeader { .. } => BlockStyle::Sticky,
+ };
+ let width = match style {
+ BlockStyle::Sticky => editor_width,
+ BlockStyle::Flex => editor_width
+ .max(fixed_block_max_width)
+ .max(gutter_width + scroll_width),
+ BlockStyle::Fixed => unreachable!(),
+ };
+ let available_space = size(
+ AvailableSpace::Definite(width),
+ AvailableSpace::Definite(block.height() as f32 * line_height),
+ );
+ let (element, _) = render_block(block, available_space, block_id, editor, cx);
+ block_id += 1;
+ blocks.push(BlockLayout {
+ row,
+ element,
+ available_space,
+ style,
+ });
+ }
+ (
+ scroll_width.max(fixed_block_max_width - gutter_width),
+ blocks,
+ )
+ }
fn paint_mouse_listeners(
&mut self,
@@ -2613,7 +2571,11 @@ impl Element<Editor> for EditorElement {
});
// on_action(cx, Editor::rename); todo!()
// on_action(cx, Editor::confirm_rename); todo!()
- // on_action(cx, Editor::find_all_references); todo!()
+ register_action(cx, |editor, action, cx| {
+ editor
+ .find_all_references(action, cx)
+ .map(|task| task.detach_and_log_err(cx));
+ });
register_action(cx, Editor::next_copilot_suggestion);
register_action(cx, Editor::previous_copilot_suggestion);
register_action(cx, Editor::copilot_suggest);
@@ -2670,11 +2632,18 @@ impl Element<Editor> for EditorElement {
&layout.position_map,
cx,
);
+
self.paint_background(gutter_bounds, text_bounds, &layout, cx);
if layout.gutter_size.width > Pixels::ZERO {
self.paint_gutter(gutter_bounds, &mut layout, editor, cx);
}
+
self.paint_text(text_bounds, &mut layout, editor, cx);
+
+ if !layout.blocks.is_empty() {
+ self.paint_blocks(bounds, &mut layout, editor, cx);
+ }
+
let input_handler = ElementInputHandler::new(bounds, cx);
cx.handle_input(&editor.focus_handle, input_handler);
});
@@ -3295,7 +3264,7 @@ pub struct LayoutState {
highlighted_rows: Option<Range<u32>>,
line_number_layouts: Vec<Option<gpui::Line>>,
display_hunks: Vec<DisplayDiffHunk>,
- // blocks: Vec<BlockLayout>,
+ blocks: Vec<BlockLayout>,
highlighted_ranges: Vec<(Range<DisplayPoint>, Hsla)>,
fold_ranges: Vec<(BufferRow, Range<DisplayPoint>, Hsla)>,
selections: Vec<(PlayerColor, Vec<SelectionLayout>)>,
@@ -3398,6 +3367,7 @@ impl PositionMap {
struct BlockLayout {
row: u32,
element: AnyElement<Editor>,
+ available_space: Size<AvailableSpace>,
style: BlockStyle,
}