Re-introduce auto-height in editor2 (#3471)

Release Notes:

- N/A
This commit is contained in:
Antonio Scandurra
2023-12-01 12:02:45 +01:00
committed by GitHub
14 changed files with 211 additions and 698 deletions
+1 -1
View File
@@ -162,7 +162,7 @@ impl WrapMap {
{
let tab_snapshot = new_snapshot.tab_snapshot.clone();
let range = TabPoint::zero()..tab_snapshot.max_point();
let edits = new_snapshot
edits = new_snapshot
.update(
tab_snapshot,
&[TabEdit {
+18 -18
View File
@@ -1734,21 +1734,11 @@ impl Editor {
// Self::new(EditorMode::Full, buffer, None, field_editor_style, cx)
// }
// pub fn auto_height(
// max_lines: usize,
// field_editor_style: Option<Arc<GetFieldEditorTheme>>,
// cx: &mut ViewContext<Self>,
// ) -> Self {
// let buffer = cx.build_model(|cx| Buffer::new(0, cx.model_id() as u64, String::new()));
// let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
// Self::new(
// EditorMode::AutoHeight { max_lines },
// buffer,
// None,
// field_editor_style,
// cx,
// )
// }
pub fn auto_height(max_lines: usize, cx: &mut ViewContext<Self>) -> Self {
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new()));
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
Self::new(EditorMode::AutoHeight { max_lines }, buffer, None, cx)
}
pub fn for_buffer(
buffer: Model<Buffer>,
@@ -8374,6 +8364,18 @@ impl Editor {
cx.notify();
}
pub fn set_style(&mut self, style: EditorStyle, cx: &mut ViewContext<Self>) {
let rem_size = cx.rem_size();
self.display_map.update(cx, |map, cx| {
map.set_font(
style.text.font(),
style.text.font_size.to_pixels(rem_size),
cx,
)
});
self.style = Some(style);
}
pub fn set_wrap_width(&self, width: Option<Pixels>, cx: &mut AppContext) -> bool {
self.display_map
.update(cx, |map, cx| map.set_wrap_width(width, cx))
@@ -9397,7 +9399,7 @@ impl Render for Editor {
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let settings = ThemeSettings::get_global(cx);
let text_style = match self.mode {
EditorMode::SingleLine => TextStyle {
EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle {
color: cx.theme().colors().text,
font_family: settings.ui_font.family.clone(),
font_features: settings.ui_font.features,
@@ -9410,8 +9412,6 @@ impl Render for Editor {
white_space: WhiteSpace::Normal,
},
EditorMode::AutoHeight { max_lines } => todo!(),
EditorMode::Full => TextStyle {
color: cx.theme().colors().text,
font_family: settings.buffer_font.family.clone(),
+95 -635
View File
@@ -20,9 +20,9 @@ use crate::{
use anyhow::Result;
use collections::{BTreeMap, HashMap};
use gpui::{
div, point, px, relative, size, transparent_black, Action, AnyElement, AvailableSpace,
BorrowWindow, Bounds, ContentMask, Corners, DispatchPhase, Edges, Element, ElementId,
ElementInputHandler, Entity, EntityId, Hsla, InteractiveBounds, InteractiveElement,
div, point, px, relative, size, transparent_black, Action, AnyElement, AsyncWindowContext,
AvailableSpace, BorrowWindow, Bounds, ContentMask, Corners, DispatchPhase, Edges, Element,
ElementId, ElementInputHandler, Entity, EntityId, Hsla, InteractiveBounds, InteractiveElement,
IntoElement, LineLayout, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent,
ParentElement, Pixels, RenderOnce, ScrollWheelEvent, ShapedLine, SharedString, Size,
StackingOrder, StatefulInteractiveElement, Style, Styled, TextRun, TextStyle, View,
@@ -1662,11 +1662,6 @@ impl EditorElement {
cx: &mut WindowContext,
) -> LayoutState {
self.editor.update(cx, |editor, cx| {
// let mut size = constraint.max;
// if size.x.is_infinite() {
// unimplemented!("we don't yet handle an infinite width constraint on buffer elements");
// }
let snapshot = editor.snapshot(cx);
let style = self.style.clone();
@@ -1702,6 +1697,7 @@ impl EditorElement {
};
editor.gutter_width = gutter_width;
let text_width = bounds.size.width - gutter_width;
let overscroll = size(em_width, px(0.));
let snapshot = {
@@ -1728,25 +1724,6 @@ impl EditorElement {
.collect::<SmallVec<[_; 2]>>();
let scroll_height = Pixels::from(snapshot.max_point().row() + 1) * line_height;
// todo!("this should happen during layout")
let editor_mode = snapshot.mode;
if let EditorMode::AutoHeight { max_lines } = editor_mode {
todo!()
// size.set_y(
// scroll_height
// .min(constraint.max_along(Axis::Vertical))
// .max(constraint.min_along(Axis::Vertical))
// .max(line_height)
// .min(line_height * max_lines as f32),
// )
} else if let EditorMode::SingleLine = editor_mode {
bounds.size.height = line_height.min(bounds.size.height);
}
// todo!()
// else if size.y.is_infinite() {
// // size.set_y(scroll_height);
// }
//
let gutter_size = size(gutter_width, bounds.size.height);
let text_size = size(text_width, bounds.size.height);
@@ -2064,7 +2041,7 @@ impl EditorElement {
.unwrap();
LayoutState {
mode: editor_mode,
mode: snapshot.mode,
position_map: Arc::new(PositionMap {
size: bounds.size,
scroll_position: point(
@@ -2617,19 +2594,44 @@ impl Element for EditorElement {
cx: &mut gpui::WindowContext,
) -> (gpui::LayoutId, Self::State) {
self.editor.update(cx, |editor, cx| {
editor.style = Some(self.style.clone()); // Long-term, we'd like to eliminate this.
editor.set_style(self.style.clone(), cx);
let rem_size = cx.rem_size();
let mut style = Style::default();
style.size.width = relative(1.).into();
style.size.height = match editor.mode {
let layout_id = match editor.mode {
EditorMode::SingleLine => {
self.style.text.line_height_in_pixels(cx.rem_size()).into()
let rem_size = cx.rem_size();
let mut style = Style::default();
style.size.width = relative(1.).into();
style.size.height = self.style.text.line_height_in_pixels(rem_size).into();
cx.request_layout(&style, None)
}
EditorMode::AutoHeight { max_lines } => {
let editor_handle = cx.view().clone();
let max_line_number_width =
self.max_line_number_width(&editor.snapshot(cx), cx);
cx.request_measured_layout(
Style::default(),
move |known_dimensions, available_space, cx| {
editor_handle
.update(cx, |editor, cx| {
compute_auto_height_layout(
editor,
max_lines,
max_line_number_width,
known_dimensions,
cx,
)
})
.unwrap_or_default()
},
)
}
EditorMode::Full => {
let mut style = Style::default();
style.size.width = relative(1.).into();
style.size.height = relative(1.).into();
cx.request_layout(&style, None)
}
EditorMode::AutoHeight { .. } => todo!(),
EditorMode::Full => relative(1.).into(),
};
let layout_id = cx.request_layout(&style, None);
(layout_id, ())
})
@@ -2698,604 +2700,6 @@ impl IntoElement for EditorElement {
}
}
// impl EditorElement {
// type LayoutState = LayoutState;
// type PaintState = ();
// fn layout(
// &mut self,
// constraint: SizeConstraint,
// editor: &mut Editor,
// cx: &mut ViewContext<Editor>,
// ) -> (gpui::Point<Pixels>, Self::LayoutState) {
// let mut size = constraint.max;
// if size.x.is_infinite() {
// unimplemented!("we don't yet handle an infinite width constraint on buffer elements");
// }
// let snapshot = editor.snapshot(cx);
// let style = self.style.clone();
// let line_height = (style.text.font_size * style.line_height_scalar).round();
// let gutter_padding;
// let gutter_width;
// let gutter_margin;
// if snapshot.show_gutter {
// let em_width = style.text.em_width(cx.font_cache());
// gutter_padding = (em_width * style.gutter_padding_factor).round();
// gutter_width = self.max_line_number_width(&snapshot, cx) + gutter_padding * 2.0;
// gutter_margin = -style.text.descent(cx.font_cache());
// } else {
// gutter_padding = 0.0;
// gutter_width = 0.0;
// gutter_margin = 0.0;
// };
// let text_width = size.x - gutter_width;
// let em_width = style.text.em_width(cx.font_cache());
// let em_advance = style.text.em_advance(cx.font_cache());
// let overscroll = point(em_width, 0.);
// let snapshot = {
// editor.set_visible_line_count(size.y / line_height, cx);
// let editor_width = text_width - gutter_margin - overscroll.x - em_width;
// let wrap_width = match editor.soft_wrap_mode(cx) {
// SoftWrap::None => (MAX_LINE_LEN / 2) as f32 * em_advance,
// SoftWrap::EditorWidth => editor_width,
// SoftWrap::Column(column) => editor_width.min(column as f32 * em_advance),
// };
// if editor.set_wrap_width(Some(wrap_width), cx) {
// editor.snapshot(cx)
// } else {
// snapshot
// }
// };
// let wrap_guides = editor
// .wrap_guides(cx)
// .iter()
// .map(|(guide, active)| (self.column_pixels(*guide, cx), *active))
// .collect();
// let scroll_height = (snapshot.max_point().row() + 1) as f32 * line_height;
// if let EditorMode::AutoHeight { max_lines } = snapshot.mode {
// size.set_y(
// scroll_height
// .min(constraint.max_along(Axis::Vertical))
// .max(constraint.min_along(Axis::Vertical))
// .max(line_height)
// .min(line_height * max_lines as f32),
// )
// } else if let EditorMode::SingleLine = snapshot.mode {
// size.set_y(line_height.max(constraint.min_along(Axis::Vertical)))
// } else if size.y.is_infinite() {
// size.set_y(scroll_height);
// }
// let gutter_size = point(gutter_width, size.y);
// let text_size = point(text_width, size.y);
// let autoscroll_horizontally = editor.autoscroll_vertically(size.y, line_height, cx);
// let mut snapshot = editor.snapshot(cx);
// let scroll_position = snapshot.scroll_position();
// // The scroll position is a fractional point, the whole number of which represents
// // the top of the window in terms of display rows.
// let start_row = scroll_position.y as u32;
// let height_in_lines = size.y / line_height;
// let max_row = snapshot.max_point().row();
// // Add 1 to ensure selections bleed off screen
// let end_row = 1 + cmp::min(
// (scroll_position.y + height_in_lines).ceil() as u32,
// max_row,
// );
// let start_anchor = if start_row == 0 {
// Anchor::min()
// } else {
// snapshot
// .buffer_snapshot
// .anchor_before(DisplayPoint::new(start_row, 0).to_offset(&snapshot, Bias::Left))
// };
// let end_anchor = if end_row > max_row {
// Anchor::max
// } else {
// snapshot
// .buffer_snapshot
// .anchor_before(DisplayPoint::new(end_row, 0).to_offset(&snapshot, Bias::Right))
// };
// let mut selections: Vec<(SelectionStyle, Vec<SelectionLayout>)> = Vec::new();
// let mut active_rows = BTreeMap::new();
// let mut fold_ranges = Vec::new();
// let is_singleton = editor.is_singleton(cx);
// let highlighted_rows = editor.highlighted_rows();
// let theme = theme::current(cx);
// let highlighted_ranges = editor.background_highlights_in_range(
// start_anchor..end_anchor,
// &snapshot.display_snapshot,
// theme.as_ref(),
// );
// fold_ranges.extend(
// snapshot
// .folds_in_range(start_anchor..end_anchor)
// .map(|anchor| {
// let start = anchor.start.to_point(&snapshot.buffer_snapshot);
// (
// start.row,
// start.to_display_point(&snapshot.display_snapshot)
// ..anchor.end.to_display_point(&snapshot),
// )
// }),
// );
// let mut newest_selection_head = None;
// if editor.show_local_selections {
// let mut local_selections: Vec<Selection<Point>> = editor
// .selections
// .disjoint_in_range(start_anchor..end_anchor, cx);
// local_selections.extend(editor.selections.pending(cx));
// let mut layouts = Vec::new();
// let newest = editor.selections.newest(cx);
// for selection in local_selections.drain(..) {
// let is_empty = selection.start == selection.end;
// let is_newest = selection == newest;
// let layout = SelectionLayout::new(
// selection,
// editor.selections.line_mode,
// editor.cursor_shape,
// &snapshot.display_snapshot,
// is_newest,
// true,
// );
// if is_newest {
// newest_selection_head = Some(layout.head);
// }
// for row in cmp::max(layout.active_rows.start, start_row)
// ..=cmp::min(layout.active_rows.end, end_row)
// {
// let contains_non_empty_selection = active_rows.entry(row).or_insert(!is_empty);
// *contains_non_empty_selection |= !is_empty;
// }
// layouts.push(layout);
// }
// selections.push((style.selection, layouts));
// }
// if let Some(collaboration_hub) = &editor.collaboration_hub {
// // When following someone, render the local selections in their color.
// if let Some(leader_id) = editor.leader_peer_id {
// if let Some(collaborator) = collaboration_hub.collaborators(cx).get(&leader_id) {
// if let Some(participant_index) = collaboration_hub
// .user_participant_indices(cx)
// .get(&collaborator.user_id)
// {
// if let Some((local_selection_style, _)) = selections.first_mut() {
// *local_selection_style =
// style.selection_style_for_room_participant(participant_index.0);
// }
// }
// }
// }
// let mut remote_selections = HashMap::default();
// for selection in snapshot.remote_selections_in_range(
// &(start_anchor..end_anchor),
// collaboration_hub.as_ref(),
// cx,
// ) {
// let selection_style = if let Some(participant_index) = selection.participant_index {
// style.selection_style_for_room_participant(participant_index.0)
// } else {
// style.absent_selection
// };
// // Don't re-render the leader's selections, since the local selections
// // match theirs.
// if Some(selection.peer_id) == editor.leader_peer_id {
// continue;
// }
// remote_selections
// .entry(selection.replica_id)
// .or_insert((selection_style, Vec::new()))
// .1
// .push(SelectionLayout::new(
// selection.selection,
// selection.line_mode,
// selection.cursor_shape,
// &snapshot.display_snapshot,
// false,
// false,
// ));
// }
// selections.extend(remote_selections.into_values());
// }
// let scrollbar_settings = &settings::get::<EditorSettings>(cx).scrollbar;
// let show_scrollbars = match scrollbar_settings.show {
// ShowScrollbar::Auto => {
// // Git
// (is_singleton && scrollbar_settings.git_diff && snapshot.buffer_snapshot.has_git_diffs())
// ||
// // Selections
// (is_singleton && scrollbar_settings.selections && !highlighted_ranges.is_empty)
// // Scrollmanager
// || editor.scroll_manager.scrollbars_visible()
// }
// ShowScrollbar::System => editor.scroll_manager.scrollbars_visible(),
// ShowScrollbar::Always => true,
// ShowScrollbar::Never => false,
// };
// let fold_ranges: Vec<(BufferRow, Range<DisplayPoint>, Color)> = fold_ranges
// .into_iter()
// .map(|(id, fold)| {
// let color = self
// .style
// .folds
// .ellipses
// .background
// .style_for(&mut cx.mouse_state::<FoldMarkers>(id as usize))
// .color;
// (id, fold, color)
// })
// .collect();
// let head_for_relative = newest_selection_head.unwrap_or_else(|| {
// let newest = editor.selections.newest::<Point>(cx);
// SelectionLayout::new(
// newest,
// editor.selections.line_mode,
// editor.cursor_shape,
// &snapshot.display_snapshot,
// true,
// true,
// )
// .head
// });
// let (line_number_layouts, fold_statuses) = self.layout_line_numbers(
// start_row..end_row,
// &active_rows,
// head_for_relative,
// is_singleton,
// &snapshot,
// cx,
// );
// let display_hunks = self.layout_git_gutters(start_row..end_row, &snapshot);
// let scrollbar_row_range = scroll_position.y..(scroll_position.y + height_in_lines);
// let mut max_visible_line_width = 0.0;
// let line_layouts =
// self.layout_lines(start_row..end_row, &line_number_layouts, &snapshot, cx);
// for line_with_invisibles in &line_layouts {
// if line_with_invisibles.line.width() > max_visible_line_width {
// max_visible_line_width = line_with_invisibles.line.width();
// }
// }
// let style = self.style.clone();
// let longest_line_width = layout_line(
// snapshot.longest_row(),
// &snapshot,
// &style,
// cx.text_layout_cache(),
// )
// .width();
// let scroll_width = longest_line_width.max(max_visible_line_width) + overscroll.x;
// let em_width = style.text.em_width(cx.font_cache());
// 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_max = point(
// ((scroll_width - text_size.x) / em_width).max(0.0),
// max_row as f32,
// );
// let clamped = editor.scroll_manager.clamp_scroll_left(scroll_max.x);
// let autoscrolled = if autoscroll_horizontally {
// editor.autoscroll_horizontally(
// start_row,
// text_size.x,
// scroll_width,
// em_width,
// &line_layouts,
// cx,
// )
// } else {
// false
// };
// if clamped || autoscrolled {
// snapshot = editor.snapshot(cx);
// }
// let style = editor.style(cx);
// let mut context_menu = None;
// let mut code_actions_indicator = None;
// if let Some(newest_selection_head) = newest_selection_head {
// if (start_row..end_row).contains(&newest_selection_head.row()) {
// if editor.context_menu_visible() {
// context_menu =
// editor.render_context_menu(newest_selection_head, style.clone(), cx);
// }
// let active = matches!(
// editor.context_menu.read().as_ref(),
// Some(crate::ContextMenu::CodeActions(_))
// );
// code_actions_indicator = editor
// .render_code_actions_indicator(&style, active, cx)
// .map(|indicator| (newest_selection_head.row(), indicator));
// }
// }
// let visible_rows = start_row..start_row + line_layouts.len() as u32;
// let mut hover = editor.hover_state.render(
// &snapshot,
// &style,
// visible_rows,
// editor.workspace.as_ref().map(|(w, _)| w.clone()),
// cx,
// );
// let mode = editor.mode;
// let mut fold_indicators = editor.render_fold_indicators(
// fold_statuses,
// &style,
// editor.gutter_hovered,
// line_height,
// gutter_margin,
// cx,
// );
// if let Some((_, context_menu)) = context_menu.as_mut() {
// context_menu.layout(
// SizeConstraint {
// min: gpui::Point::<Pixels>::zero(),
// max: point(
// cx.window_size().x * 0.7,
// (12. * line_height).min((size.y - line_height) / 2.),
// ),
// },
// editor,
// cx,
// );
// }
// if let Some((_, indicator)) = code_actions_indicator.as_mut() {
// indicator.layout(
// SizeConstraint::strict_along(
// Axis::Vertical,
// line_height * style.code_actions.vertical_scale,
// ),
// editor,
// cx,
// );
// }
// for fold_indicator in fold_indicators.iter_mut() {
// if let Some(indicator) = fold_indicator.as_mut() {
// indicator.layout(
// SizeConstraint::strict_along(
// Axis::Vertical,
// line_height * style.code_actions.vertical_scale,
// ),
// editor,
// cx,
// );
// }
// }
// if let Some((_, hover_popovers)) = hover.as_mut() {
// for hover_popover in hover_popovers.iter_mut() {
// hover_popover.layout(
// SizeConstraint {
// min: gpui::Point::<Pixels>::zero(),
// max: point(
// (120. * em_width) // Default size
// .min(size.x / 2.) // Shrink to half of the editor width
// .max(MIN_POPOVER_CHARACTER_WIDTH * em_width), // Apply minimum width of 20 characters
// (16. * line_height) // Default size
// .min(size.y / 2.) // Shrink to half of the editor height
// .max(MIN_POPOVER_LINE_HEIGHT * line_height), // Apply minimum height of 4 lines
// ),
// },
// editor,
// cx,
// );
// }
// }
// let invisible_symbol_font_size = self.style.text.font_size / 2.0;
// let invisible_symbol_style = RunStyle {
// color: self.style.whitespace,
// font_id: self.style.text.font_id,
// underline: Default::default(),
// };
// (
// size,
// LayoutState {
// mode,
// position_map: Arc::new(PositionMap {
// size,
// scroll_max,
// line_layouts,
// line_height,
// em_width,
// em_advance,
// snapshot,
// }),
// visible_display_row_range: start_row..end_row,
// wrap_guides,
// gutter_size,
// gutter_padding,
// text_size,
// scrollbar_row_range,
// show_scrollbars,
// is_singleton,
// max_row,
// gutter_margin,
// active_rows,
// highlighted_rows,
// highlighted_ranges,
// fold_ranges,
// line_number_layouts,
// display_hunks,
// blocks,
// selections,
// context_menu,
// code_actions_indicator,
// fold_indicators,
// tab_invisible: cx.text_layout_cache().layout_str(
// "→",
// invisible_symbol_font_size,
// &[("→".len(), invisible_symbol_style)],
// ),
// space_invisible: cx.text_layout_cache().layout_str(
// "•",
// invisible_symbol_font_size,
// &[("•".len(), invisible_symbol_style)],
// ),
// hover_popovers: hover,
// },
// )
// }
// fn paint(
// &mut self,
// bounds: Bounds<Pixels>,
// visible_bounds: Bounds<Pixels>,
// layout: &mut Self::LayoutState,
// editor: &mut Editor,
// cx: &mut ViewContext<Editor>,
// ) -> Self::PaintState {
// let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
// cx.scene().push_layer(Some(visible_bounds));
// let gutter_bounds = Bounds::<Pixels>::new(bounds.origin, layout.gutter_size);
// let text_bounds = Bounds::<Pixels>::new(
// bounds.origin + point(layout.gutter_size.x, 0.0),
// layout.text_size,
// );
// Self::attach_mouse_handlers(
// &layout.position_map,
// layout.hover_popovers.is_some(),
// visible_bounds,
// text_bounds,
// gutter_bounds,
// bounds,
// cx,
// );
// self.paint_background(gutter_bounds, text_bounds, layout, cx);
// if layout.gutter_size.x > 0. {
// self.paint_gutter(gutter_bounds, visible_bounds, layout, editor, cx);
// }
// self.paint_text(text_bounds, visible_bounds, layout, editor, cx);
// cx.scene().push_layer(Some(bounds));
// if !layout.blocks.is_empty {
// self.paint_blocks(bounds, visible_bounds, layout, editor, cx);
// }
// self.paint_scrollbar(bounds, layout, &editor, cx);
// cx.scene().pop_layer();
// cx.scene().pop_layer();
// }
// fn rect_for_text_range(
// &self,
// range_utf16: Range<usize>,
// bounds: Bounds<Pixels>,
// _: Bounds<Pixels>,
// layout: &Self::LayoutState,
// _: &Self::PaintState,
// _: &Editor,
// _: &ViewContext<Editor>,
// ) -> Option<Bounds<Pixels>> {
// let text_bounds = Bounds::<Pixels>::new(
// bounds.origin + point(layout.gutter_size.x, 0.0),
// layout.text_size,
// );
// let content_origin = text_bounds.origin + point(layout.gutter_margin, 0.);
// let scroll_position = layout.position_map.snapshot.scroll_position();
// let start_row = scroll_position.y as u32;
// let scroll_top = scroll_position.y * layout.position_map.line_height;
// let scroll_left = scroll_position.x * layout.position_map.em_width;
// let range_start = OffsetUtf16(range_utf16.start)
// .to_display_point(&layout.position_map.snapshot.display_snapshot);
// if range_start.row() < start_row {
// return None;
// }
// let line = &layout
// .position_map
// .line_layouts
// .get((range_start.row() - start_row) as usize)?
// .line;
// let range_start_x = line.x_for_index(range_start.column() as usize);
// let range_start_y = range_start.row() as f32 * layout.position_map.line_height;
// Some(Bounds::<Pixels>::new(
// content_origin
// + point(
// range_start_x,
// range_start_y + layout.position_map.line_height,
// )
// - point(scroll_left, scroll_top),
// point(
// layout.position_map.em_width,
// layout.position_map.line_height,
// ),
// ))
// }
// fn debug(
// &self,
// bounds: Bounds<Pixels>,
// _: &Self::LayoutState,
// _: &Self::PaintState,
// _: &Editor,
// _: &ViewContext<Editor>,
// ) -> json::Value {
// json!({
// "type": "BufferElement",
// "bounds": bounds.to_json()
// })
// }
// }
type BufferRow = u32;
pub struct LayoutState {
@@ -4134,3 +3538,59 @@ pub fn register_action<T: Action>(
}
})
}
fn compute_auto_height_layout(
editor: &mut Editor,
max_lines: usize,
max_line_number_width: Pixels,
known_dimensions: Size<Option<Pixels>>,
cx: &mut ViewContext<Editor>,
) -> Option<Size<Pixels>> {
let mut width = known_dimensions.width?;
if let Some(height) = known_dimensions.height {
return Some(size(width, height));
}
let style = editor.style.as_ref().unwrap();
let font_id = cx.text_system().font_id(&style.text.font()).unwrap();
let font_size = style.text.font_size.to_pixels(cx.rem_size());
let line_height = style.text.line_height_in_pixels(cx.rem_size());
let em_width = cx
.text_system()
.typographic_bounds(font_id, font_size, 'm')
.unwrap()
.size
.width;
let mut snapshot = editor.snapshot(cx);
let gutter_padding;
let gutter_width;
let gutter_margin;
if snapshot.show_gutter {
let descent = cx.text_system().descent(font_id, font_size).unwrap();
let gutter_padding_factor = 3.5;
gutter_padding = (em_width * gutter_padding_factor).round();
gutter_width = max_line_number_width + gutter_padding * 2.0;
gutter_margin = -descent;
} else {
gutter_padding = Pixels::ZERO;
gutter_width = Pixels::ZERO;
gutter_margin = Pixels::ZERO;
};
editor.gutter_width = gutter_width;
let text_width = width - gutter_width;
let overscroll = size(em_width, px(0.));
let editor_width = text_width - gutter_margin - overscroll.width - em_width;
if editor.set_wrap_width(Some(editor_width), cx) {
snapshot = editor.snapshot(cx);
}
let scroll_height = Pixels::from(snapshot.max_point().row() + 1) * line_height;
let height = scroll_height
.max(line_height)
.min(line_height * max_lines as f32);
Some(size(width, height))
}
@@ -315,14 +315,11 @@ impl SelectionsCollection {
let line = display_map.layout_row(row, &text_layout_details);
dbg!("****START COL****");
let start_col = line.closest_index_for_x(positions.start) as u32;
if start_col < line_len || (is_empty && positions.start == line.width) {
let start = DisplayPoint::new(row, start_col);
dbg!("****END COL****");
let end_col = line.closest_index_for_x(positions.end) as u32;
let end = DisplayPoint::new(row, end_col);
dbg!(start_col, end_col);
Some(Selection {
id: post_inc(&mut self.next_selection_id),