Merge branch 'main' into elevations
This commit is contained in:
commit
b0ddbeb0ad
273 changed files with 26504 additions and 15624 deletions
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue