Merge branch 'main' into elevations

This commit is contained in:
K Simmons 2022-10-18 12:47:15 -07:00
commit b0ddbeb0ad
273 changed files with 26504 additions and 15624 deletions

View file

@ -7,15 +7,17 @@ use alacritty_terminal::{
use editor::{Cursor, CursorShape, HighlightedRange, HighlightedRangeLine};
use gpui::{
color::Color,
fonts::{Properties, Style::Italic, TextStyle, Underline, Weight},
elements::{Empty, Overlay},
fonts::{HighlightStyle, Properties, Style::Italic, TextStyle, Underline, Weight},
geometry::{
rect::RectF,
vector::{vec2f, Vector2F},
},
serde_json::json,
text_layout::{Line, RunStyle},
Element, Event, EventContext, FontCache, KeyDownEvent, ModelContext, MouseButton, MouseRegion,
PaintContext, Quad, TextLayoutCache, WeakModelHandle, WeakViewHandle,
Element, ElementBox, Event, EventContext, FontCache, KeyDownEvent, ModelContext, MouseButton,
MouseRegion, PaintContext, Quad, SizeConstraint, TextLayoutCache, WeakModelHandle,
WeakViewHandle,
};
use itertools::Itertools;
use ordered_float::OrderedFloat;
@ -42,6 +44,7 @@ pub struct LayoutState {
size: TerminalSize,
mode: TermMode,
display_offset: usize,
hyperlink_tooltip: Option<ElementBox>,
}
///Helper struct for converting data between alacritty's cursor points, and displayed cursor points
@ -176,6 +179,7 @@ impl TerminalElement {
terminal_theme: &TerminalStyle,
text_layout_cache: &TextLayoutCache,
font_cache: &FontCache,
hyperlink: Option<(HighlightStyle, &RangeInclusive<Point>)>,
) -> (Vec<LayoutCell>, Vec<LayoutRect>) {
let mut cells = vec![];
let mut rects = vec![];
@ -233,13 +237,14 @@ impl TerminalElement {
//Layout current cell text
{
let cell_text = &cell.c.to_string();
if cell_text != " " {
if !is_blank(&cell) {
let cell_style = TerminalElement::cell_style(
&cell,
fg,
terminal_theme,
text_style,
font_cache,
hyperlink,
);
let layout_cell = text_layout_cache.layout_str(
@ -252,8 +257,8 @@ impl TerminalElement {
Point::new(line_index as i32, cell.point.column.0 as i32),
layout_cell,
))
}
};
};
}
}
if cur_rect.is_some() {
@ -298,11 +303,12 @@ impl TerminalElement {
style: &TerminalStyle,
text_style: &TextStyle,
font_cache: &FontCache,
hyperlink: Option<(HighlightStyle, &RangeInclusive<Point>)>,
) -> RunStyle {
let flags = indexed.cell.flags;
let fg = convert_color(&fg, &style);
let underline = flags
let mut underline = flags
.intersects(Flags::ALL_UNDERLINES)
.then(|| Underline {
color: Some(fg),
@ -311,14 +317,17 @@ impl TerminalElement {
})
.unwrap_or_default();
if indexed.cell.hyperlink().is_some() {
if underline.thickness == OrderedFloat(0.) {
underline.thickness = OrderedFloat(1.);
}
}
let mut properties = Properties::new();
if indexed
.flags
.intersects(Flags::BOLD | Flags::BOLD_ITALIC | Flags::DIM_BOLD)
{
if indexed.flags.intersects(Flags::BOLD | Flags::DIM_BOLD) {
properties = *properties.weight(Weight::BOLD);
}
if indexed.flags.intersects(Flags::ITALIC | Flags::BOLD_ITALIC) {
if indexed.flags.intersects(Flags::ITALIC) {
properties = *properties.style(Italic);
}
@ -326,11 +335,25 @@ impl TerminalElement {
.select_font(text_style.font_family_id, &properties)
.unwrap_or(text_style.font_id);
RunStyle {
let mut result = RunStyle {
color: fg,
font_id,
underline,
};
if let Some((style, range)) = hyperlink {
if range.contains(&indexed.point) {
if let Some(underline) = style.underline {
result.underline = underline;
}
if let Some(color) = style.color {
result.color = color;
}
}
}
result
}
fn generic_button_handler<E>(
@ -360,7 +383,7 @@ impl TerminalElement {
) {
let connection = self.terminal;
let mut region = MouseRegion::new::<Self>(view_id, view_id, visible_bounds);
let mut region = MouseRegion::new::<Self>(view_id, 0, visible_bounds);
// Terminal Emulator controlled behavior:
region = region
@ -392,19 +415,8 @@ impl TerminalElement {
TerminalElement::generic_button_handler(
connection,
origin,
move |terminal, origin, e, _cx| {
terminal.mouse_up(&e, origin);
},
),
)
// Handle click based selections
.on_click(
MouseButton::Left,
TerminalElement::generic_button_handler(
connection,
origin,
move |terminal, origin, e, _cx| {
terminal.left_click(&e, origin);
move |terminal, origin, e, cx| {
terminal.mouse_up(&e, origin, cx);
},
),
)
@ -422,13 +434,25 @@ impl TerminalElement {
});
}
})
.on_scroll(TerminalElement::generic_button_handler(
connection,
origin,
move |terminal, origin, e, _cx| {
terminal.scroll_wheel(e, origin);
},
));
.on_move(move |event, cx| {
if cx.is_parent_view_focused() {
if let Some(conn_handle) = connection.upgrade(cx.app) {
conn_handle.update(cx.app, |terminal, cx| {
terminal.mouse_move(&event, origin);
cx.notify();
})
}
}
})
.on_scroll(move |event, cx| {
// cx.focus_parent_view();
if let Some(conn_handle) = connection.upgrade(cx.app) {
conn_handle.update(cx.app, |terminal, cx| {
terminal.scroll_wheel(event, origin);
cx.notify();
})
}
});
// Mouse mode handlers:
// All mouse modes need the extra click handlers
@ -459,8 +483,8 @@ impl TerminalElement {
TerminalElement::generic_button_handler(
connection,
origin,
move |terminal, origin, e, _cx| {
terminal.mouse_up(&e, origin);
move |terminal, origin, e, cx| {
terminal.mouse_up(&e, origin, cx);
},
),
)
@ -469,27 +493,12 @@ impl TerminalElement {
TerminalElement::generic_button_handler(
connection,
origin,
move |terminal, origin, e, _cx| {
terminal.mouse_up(&e, origin);
move |terminal, origin, e, cx| {
terminal.mouse_up(&e, origin, cx);
},
),
)
}
//Mouse move manages both dragging and motion events
if mode.intersects(TermMode::MOUSE_DRAG | TermMode::MOUSE_MOTION) {
region = region
//TODO: This does not fire on right-mouse-down-move events.
.on_move(move |event, cx| {
if cx.is_parent_view_focused() {
if let Some(conn_handle) = connection.upgrade(cx.app) {
conn_handle.update(cx.app, |terminal, cx| {
terminal.mouse_move(&event, origin);
cx.notify();
})
}
}
})
}
cx.scene.push_mouse_region(region);
}
@ -541,6 +550,9 @@ impl Element for TerminalElement {
//Setup layout information
let terminal_theme = settings.theme.terminal.clone(); //TODO: Try to minimize this clone.
let link_style = settings.theme.editor.link_definition;
let tooltip_style = settings.theme.tooltip.clone();
let text_style = TerminalElement::make_text_style(font_cache, settings);
let selection_color = settings.theme.editor.selection.selection;
let match_color = settings.theme.search.match_background;
@ -559,9 +571,34 @@ impl Element for TerminalElement {
let background_color = terminal_theme.background;
let terminal_handle = self.terminal.upgrade(cx).unwrap();
terminal_handle.update(cx.app, |terminal, cx| {
let last_hovered_hyperlink = terminal_handle.update(cx.app, |terminal, cx| {
terminal.set_size(dimensions);
terminal.try_sync(cx)
terminal.try_sync(cx);
terminal.last_content.last_hovered_hyperlink.clone()
});
let view_handle = self.view.clone();
let hyperlink_tooltip = last_hovered_hyperlink.and_then(|(uri, _, id)| {
// last_mouse.and_then(|_last_mouse| {
view_handle.upgrade(cx).map(|handle| {
let mut tooltip = cx.render(&handle, |_, cx| {
Overlay::new(
Empty::new()
.contained()
.constrained()
.with_width(dimensions.width())
.with_height(dimensions.height())
.with_tooltip::<TerminalElement, _>(id, uri, None, tooltip_style, cx)
.boxed(),
)
.with_position_mode(gpui::elements::OverlayPositionMode::Local)
.boxed()
});
tooltip.layout(SizeConstraint::new(Vector2F::zero(), cx.window_size), cx);
tooltip
})
// })
});
let TerminalContent {
@ -571,8 +608,9 @@ impl Element for TerminalElement {
cursor_char,
selection,
cursor,
last_hovered_hyperlink,
..
} = &terminal_handle.read(cx).last_content;
} = { &terminal_handle.read(cx).last_content };
// searches, highlights to a single range representations
let mut relative_highlighted_ranges = Vec::new();
@ -591,6 +629,9 @@ impl Element for TerminalElement {
&terminal_theme,
cx.text_layout_cache,
cx.font_cache(),
last_hovered_hyperlink
.as_ref()
.map(|(_, range, _)| (link_style, range)),
);
//Layout cursor. Rectangle is used for IME, so we should lay it out even
@ -622,14 +663,15 @@ impl Element for TerminalElement {
)
};
let focused = self.focused;
TerminalElement::shape_cursor(cursor_point, dimensions, &cursor_text).map(
move |(cursor_position, block_width)| {
let shape = match cursor.shape {
AlacCursorShape::Block if !self.focused => CursorShape::Hollow,
AlacCursorShape::Block => CursorShape::Block,
AlacCursorShape::Underline => CursorShape::Underscore,
AlacCursorShape::Beam => CursorShape::Bar,
AlacCursorShape::HollowBlock => CursorShape::Hollow,
let (shape, text) = match cursor.shape {
AlacCursorShape::Block if !focused => (CursorShape::Hollow, None),
AlacCursorShape::Block => (CursorShape::Block, Some(cursor_text)),
AlacCursorShape::Underline => (CursorShape::Underscore, None),
AlacCursorShape::Beam => (CursorShape::Bar, None),
AlacCursorShape::HollowBlock => (CursorShape::Hollow, None),
//This case is handled in the if wrapping the whole cursor layout
AlacCursorShape::Hidden => unreachable!(),
};
@ -640,7 +682,7 @@ impl Element for TerminalElement {
dimensions.line_height,
terminal_theme.cursor,
shape,
Some(cursor_text),
text,
)
},
)
@ -658,6 +700,7 @@ impl Element for TerminalElement {
relative_highlighted_ranges,
mode: *mode,
display_offset: *display_offset,
hyperlink_tooltip,
},
)
}
@ -669,6 +712,8 @@ impl Element for TerminalElement {
layout: &mut Self::LayoutState,
cx: &mut gpui::PaintContext,
) -> Self::PaintState {
let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
//Setup element stuff
let clip_bounds = Some(visible_bounds);
@ -680,7 +725,11 @@ impl Element for TerminalElement {
cx.scene.push_cursor_region(gpui::CursorRegion {
bounds,
style: gpui::CursorStyle::IBeam,
style: if layout.hyperlink_tooltip.is_some() {
gpui::CursorStyle::PointingHand
} else {
gpui::CursorStyle::IBeam
},
});
cx.paint_layer(clip_bounds, |cx| {
@ -732,6 +781,10 @@ impl Element for TerminalElement {
})
}
}
if let Some(element) = &mut layout.hyperlink_tooltip {
element.paint(origin, visible_bounds, cx)
}
});
}
@ -813,6 +866,29 @@ impl Element for TerminalElement {
}
}
fn is_blank(cell: &IndexedCell) -> bool {
if cell.c != ' ' {
return false;
}
if cell.bg != AnsiColor::Named(NamedColor::Background) {
return false;
}
if cell.hyperlink().is_some() {
return false;
}
if cell
.flags
.intersects(Flags::ALL_UNDERLINES | Flags::INVERSE | Flags::STRIKEOUT)
{
return false;
}
return true;
}
fn to_highlighted_range_lines(
range: &RangeInclusive<Point>,
layout: &LayoutState,