More compilation fixes

This commit is contained in:
Kirill Bulatov 2023-11-14 17:40:29 +02:00
parent 61d6cb880c
commit a238368296
6 changed files with 244 additions and 205 deletions

View File

@ -1,4 +1,4 @@
use gpui::{AppContext, FontFeatures};
use gpui::{AppContext, FontFeatures, Pixels};
use schemars::JsonSchema;
use serde_derive::{Deserialize, Serialize};
use std::{collections::HashMap, path::PathBuf};
@ -15,7 +15,7 @@ pub enum TerminalDockPosition {
pub struct TerminalSettings {
pub shell: Shell,
pub working_directory: WorkingDirectory,
font_size: Option<f32>,
pub font_size: Option<Pixels>,
pub font_family: Option<String>,
pub line_height: TerminalLineHeight,
pub font_features: Option<FontFeatures>,
@ -90,14 +90,6 @@ pub struct TerminalSettingsContent {
pub detect_venv: Option<VenvSettings>,
}
impl TerminalSettings {
// todo!("move to terminal element")
// pub fn font_size(&self, cx: &AppContext) -> Option<f32> {
// self.font_size
// .map(|size| theme2::adjusted_font_size(size, cx))
// }
}
impl settings::Settings for TerminalSettings {
const KEY: Option<&'static str> = Some("terminal");

View File

@ -1,11 +1,13 @@
use editor::{Cursor, HighlightedRange, HighlightedRangeLine};
use gpui::{
serde_json::json, AnyElement, Bounds, HighlightStyle, Hsla, Line, ModelContext, MouseButton,
Pixels, Point, TextStyle, ViewContext, WeakModel, WindowContext,
AnyElement, AppContext, Bounds, Component, Element, HighlightStyle, Hsla, LayoutId, Line,
ModelContext, MouseButton, Pixels, Point, TextStyle, Underline, ViewContext, WeakModel,
WindowContext,
};
use itertools::Itertools;
use language::CursorShape;
use ordered_float::OrderedFloat;
use settings::Settings;
use terminal::{
alacritty_terminal::{
ansi::{Color as AnsiColor, Color::Named, CursorShape as AlacCursorShape, NamedColor},
@ -21,10 +23,9 @@ use terminal::{
TerminalSize,
};
use theme::ThemeSettings;
use util::ResultExt;
use std::mem;
use std::{fmt::Debug, ops::RangeInclusive};
use std::{mem, ops::Range};
use crate::TerminalView;
@ -143,7 +144,7 @@ impl LayoutRect {
cx.paint_quad(
Bounds::new(position, size),
Default::default(),
Some(self.color),
self.color,
Default::default(),
Default::default(),
);
@ -282,10 +283,10 @@ impl TerminalElement {
text_fragment: &Line,
) -> Option<(Vector2F, f32)> {
if cursor_point.line() < size.total_lines() as i32 {
let cursor_width = if text_fragment.width() == 0. {
let cursor_width = if text_fragment.width == 0. {
size.cell_width()
} else {
text_fragment.width()
text_fragment.width
};
//Cursor should always surround as much of the text as possible,
@ -339,7 +340,7 @@ impl TerminalElement {
let font_id = font_cache
.select_font(text_style.font_family_id, &properties)
.unwrap_or(text_style.font_id);
.unwrap_or(8text_style.font_id);
let mut result = RunStyle {
color: fg,
@ -369,7 +370,7 @@ impl TerminalElement {
) -> impl Fn(E, &mut TerminalView, &mut EventContext<TerminalView>) {
move |event, _: &mut TerminalView, cx| {
cx.focus_parent();
if let Some(conn_handle) = connection.upgrade(cx) {
if let Some(conn_handle) = connection.upgrade() {
conn_handle.update(cx, |terminal, cx| {
f(terminal, origin, event, cx);
@ -382,7 +383,7 @@ impl TerminalElement {
fn attach_mouse_handlers(
&self,
origin: Point<Pixels>,
visible_bounds: Bounds,
visible_bounds: Bounds<Pixels>,
mode: TermMode,
cx: &mut ViewContext<TerminalView>,
) {
@ -397,7 +398,7 @@ impl TerminalElement {
let terminal_view = cx.handle();
cx.focus(&terminal_view);
v.context_menu.update(cx, |menu, _cx| menu.delay_cancel());
if let Some(conn_handle) = connection.upgrade(cx) {
if let Some(conn_handle) = connection.upgrade() {
conn_handle.update(cx, |terminal, cx| {
terminal.mouse_down(&event, origin);
@ -412,7 +413,7 @@ impl TerminalElement {
}
if cx.is_self_focused() {
if let Some(conn_handle) = connection.upgrade(cx) {
if let Some(conn_handle) = connection.upgrade() {
conn_handle.update(cx, |terminal, cx| {
terminal.mouse_drag(event, origin);
cx.notify();
@ -435,7 +436,7 @@ impl TerminalElement {
.on_click(
MouseButton::Right,
move |event, view: &mut TerminalView, cx| {
let mouse_mode = if let Some(conn_handle) = connection.upgrade(cx) {
let mouse_mode = if let Some(conn_handle) = connection.upgrade() {
conn_handle.update(cx, |terminal, _cx| terminal.mouse_mode(event.shift))
} else {
// If we can't get the model handle, probably can't deploy the context menu
@ -448,7 +449,7 @@ impl TerminalElement {
)
.on_move(move |event, _: &mut TerminalView, cx| {
if cx.is_self_focused() {
if let Some(conn_handle) = connection.upgrade(cx) {
if let Some(conn_handle) = connection.upgrade() {
conn_handle.update(cx, |terminal, cx| {
terminal.mouse_move(&event, origin);
cx.notify();
@ -457,7 +458,7 @@ impl TerminalElement {
}
})
.on_scroll(move |event, _: &mut TerminalView, cx| {
if let Some(conn_handle) = connection.upgrade(cx) {
if let Some(conn_handle) = connection.upgrade() {
conn_handle.update(cx, |terminal, cx| {
terminal.scroll_wheel(event, origin);
cx.notify();
@ -516,17 +517,16 @@ impl TerminalElement {
}
impl Element<TerminalView> for TerminalElement {
type LayoutState = LayoutState;
type PaintState = ();
type ElementState = LayoutState;
fn layout(
&mut self,
constraint: gpui::SizeConstraint,
view: &mut TerminalView,
view_state: &mut TerminalView,
element_state: &mut Self::ElementState,
cx: &mut ViewContext<TerminalView>,
) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
let settings = settings::get::<ThemeSettings>(cx);
let terminal_settings = settings::get::<TerminalSettings>(cx);
) -> LayoutId {
let settings = ThemeSettings::get_global(cx);
let terminal_settings = TerminalSettings::get_global(cx);
//Setup layout information
let terminal_theme = settings.theme.terminal.clone(); //TODO: Try to minimize this clone.
@ -534,9 +534,7 @@ impl Element<TerminalView> for TerminalElement {
let tooltip_style = settings.theme.tooltip.clone();
let font_cache = cx.font_cache();
let font_size = terminal_settings
.font_size(cx)
.unwrap_or(settings.buffer_font_size(cx));
let font_size = font_size(&terminal_settings, cx).unwrap_or(settings.buffer_font_size(cx));
let font_family_name = terminal_settings
.font_family
.as_ref()
@ -575,14 +573,14 @@ impl Element<TerminalView> for TerminalElement {
TerminalSize::new(line_height, cell_width, size)
};
let search_matches = if let Some(terminal_model) = self.terminal.upgrade(cx) {
let search_matches = if let Some(terminal_model) = self.terminal.upgrade() {
terminal_model.read(cx).matches.clone()
} else {
Default::default()
};
let background_color = terminal_theme.background;
let terminal_handle = self.terminal.upgrade(cx).unwrap();
let terminal_handle = self.terminal.upgrade().unwrap();
let last_hovered_word = terminal_handle.update(cx, |terminal, cx| {
terminal.set_size(dimensions);
@ -614,7 +612,7 @@ impl Element<TerminalView> for TerminalElement {
tooltip.layout(
SizeConstraint::new(Vector2F::zero(), cx.window_size()),
view,
view_state,
cx,
);
tooltip
@ -709,7 +707,7 @@ impl Element<TerminalView> for TerminalElement {
//Done!
(
constraint.max,
LayoutState {
Self::ElementState {
cells,
cursor,
background_color,
@ -726,26 +724,25 @@ impl Element<TerminalView> for TerminalElement {
fn paint(
&mut self,
bounds: Bounds,
visible_bounds: Bounds,
layout: &mut Self::LayoutState,
view: &mut TerminalView,
bounds: Bounds<Pixels>,
view_state: &mut TerminalView,
element_state: &mut Self::ElementState,
cx: &mut ViewContext<TerminalView>,
) -> Self::PaintState {
) {
let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
//Setup element stuff
let clip_bounds = Some(visible_bounds);
cx.paint_layer(clip_bounds, |cx| {
let origin = bounds.origin() + vec2f(layout.gutter, 0.);
let origin = bounds.origin() + vec2f(element_state.gutter, 0.);
// Elements are ephemeral, only at paint time do we know what could be clicked by a mouse
self.attach_mouse_handlers(origin, visible_bounds, layout.mode, cx);
self.attach_mouse_handlers(origin, visible_bounds, element_state.mode, cx);
cx.scene().push_cursor_region(gpui::CursorRegion {
bounds,
style: if layout.hyperlink_tooltip.is_some() {
style: if element_state.hyperlink_tooltip.is_some() {
CursorStyle::AlacPointingHand
} else {
CursorStyle::IBeam
@ -755,31 +752,34 @@ impl Element<TerminalView> for TerminalElement {
cx.paint_layer(clip_bounds, |cx| {
//Start with a background color
cx.scene().push_quad(Quad {
bounds: RectF::new(bounds.origin(), bounds.size()),
background: Some(layout.background_color),
bounds,
background: Some(element_state.background_color),
border: Default::default(),
corner_radii: Default::default(),
});
for rect in &layout.rects {
rect.paint(origin, layout, view, cx);
for rect in &element_state.rects {
rect.paint(origin, element_state, view_state, cx);
}
});
//Draw Highlighted Backgrounds
cx.paint_layer(clip_bounds, |cx| {
for (relative_highlighted_range, color) in layout.relative_highlighted_ranges.iter()
for (relative_highlighted_range, color) in
element_state.relative_highlighted_ranges.iter()
{
if let Some((start_y, highlighted_range_lines)) =
to_highlighted_range_lines(relative_highlighted_range, layout, origin)
{
if let Some((start_y, highlighted_range_lines)) = to_highlighted_range_lines(
relative_highlighted_range,
element_state,
origin,
) {
let hr = HighlightedRange {
start_y, //Need to change this
line_height: layout.size.line_height,
line_height: element_state.size.line_height,
lines: highlighted_range_lines,
color: color.clone(),
//Copied from editor. TODO: move to theme or something
corner_radius: 0.15 * layout.size.line_height,
corner_radius: 0.15 * element_state.size.line_height,
};
hr.paint(bounds, cx);
}
@ -788,63 +788,83 @@ impl Element<TerminalView> for TerminalElement {
//Draw the text cells
cx.paint_layer(clip_bounds, |cx| {
for cell in &layout.cells {
cell.paint(origin, layout, visible_bounds, view, cx);
for cell in &element_state.cells {
cell.paint(origin, element_state, visible_bounds, view_state, cx);
}
});
//Draw cursor
if self.cursor_visible {
if let Some(cursor) = &layout.cursor {
if let Some(cursor) = &element_state.cursor {
cx.paint_layer(clip_bounds, |cx| {
cursor.paint(origin, cx);
})
}
}
if let Some(element) = &mut layout.hyperlink_tooltip {
element.paint(origin, visible_bounds, view, cx)
if let Some(element) = &mut element_state.hyperlink_tooltip {
element.paint(origin, visible_bounds, view_state, cx)
}
});
}
fn metadata(&self) -> Option<&dyn std::any::Any> {
None
fn id(&self) -> Option<gpui::ElementId> {
todo!()
}
fn debug(
&self,
_: Bounds,
_: &Self::LayoutState,
_: &Self::PaintState,
_: &TerminalView,
_: &gpui::ViewContext<TerminalView>,
) -> gpui::serde_json::Value {
json!({
"type": "TerminalElement",
})
fn initialize(
&mut self,
view_state: &mut TerminalView,
element_state: Option<Self::ElementState>,
cx: &mut ViewContext<TerminalView>,
) -> Self::ElementState {
todo!()
}
fn rect_for_text_range(
&self,
_: Range<usize>,
bounds: Bounds,
_: Bounds,
layout: &Self::LayoutState,
_: &Self::PaintState,
_: &TerminalView,
_: &gpui::ViewContext<TerminalView>,
) -> Option<RectF> {
// Use the same origin that's passed to `Cursor::paint` in the paint
// method bove.
let mut origin = bounds.origin() + vec2f(layout.size.cell_width, 0.);
// todo!() remove?
// fn metadata(&self) -> Option<&dyn std::any::Any> {
// None
// }
// TODO - Why is it necessary to move downward one line to get correct
// positioning? I would think that we'd want the same rect that is
// painted for the cursor.
origin += vec2f(0., layout.size.line_height);
// fn debug(
// &self,
// _: Bounds<Pixels>,
// _: &Self::ElementState,
// _: &Self::PaintState,
// _: &TerminalView,
// _: &gpui::ViewContext<TerminalView>,
// ) -> gpui::serde_json::Value {
// json!({
// "type": "TerminalElement",
// })
// }
Some(layout.cursor.as_ref()?.bounding_rect(origin))
// fn rect_for_text_range(
// &self,
// _: Range<usize>,
// bounds: Bounds<Pixels>,
// _: Bounds<Pixels>,
// layout: &Self::ElementState,
// _: &Self::PaintState,
// _: &TerminalView,
// _: &gpui::ViewContext<TerminalView>,
// ) -> Option<Bounds<Pixels>> {
// // Use the same origin that's passed to `Cursor::paint` in the paint
// // method bove.
// let mut origin = bounds.origin() + vec2f(layout.size.cell_width, 0.);
// // TODO - Why is it necessary to move downward one line to get correct
// // positioning? I would think that we'd want the same rect that is
// // painted for the cursor.
// origin += vec2f(0., layout.size.line_height);
// Some(layout.cursor.as_ref()?.bounding_rect(origin))
// }
}
impl Component<TerminalView> for TerminalElement {
fn render(self) -> AnyElement<TerminalView> {
todo!()
}
}
@ -933,3 +953,9 @@ fn to_highlighted_range_lines(
Some((start_y, highlighted_range_lines))
}
fn font_size(terminal_settings: &TerminalSettings, cx: &mut AppContext) -> Option<Pixels> {
terminal_settings
.font_size
.map(|size| theme::adjusted_font_size(size, cx))
}

View File

@ -3,27 +3,34 @@ use std::{path::PathBuf, sync::Arc};
use crate::TerminalView;
use db::kvp::KEY_VALUE_STORE;
use gpui::{
actions, anyhow::Result, elements::*, serde_json, Action, AppContext, AsyncAppContext, Entity,
Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext,
actions, serde_json, Action, AppContext, AsyncAppContext, Entity, EventEmitter, Render,
Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
};
use project::Fs;
use serde::{Deserialize, Serialize};
use settings::SettingsStore;
use settings::{Settings, SettingsStore};
use terminal::terminal_settings::{TerminalDockPosition, TerminalSettings};
use util::{ResultExt, TryFutureExt};
use workspace::{
dock::{DockPosition, Panel},
dock::{DockPosition, Panel, PanelEvent},
item::Item,
pane, DraggedItem, Pane, Workspace,
pane, Pane, Workspace,
};
use anyhow::Result;
const TERMINAL_PANEL_KEY: &'static str = "TerminalPanel";
actions!(terminal_panel, [ToggleFocus]);
actions!(ToggleFocus);
pub fn init(cx: &mut AppContext) {
cx.add_action(TerminalPanel::new_terminal);
cx.add_action(TerminalPanel::open_terminal);
cx.observe_new_views(
|workspace: &mut Workspace, _: &mut ViewContext<Workspace>| {
workspace.register_action(TerminalPanel::new_terminal);
workspace.register_action(TerminalPanel::open_terminal);
},
)
.detach();
}
#[derive(Debug)]
@ -36,9 +43,9 @@ pub enum Event {
}
pub struct TerminalPanel {
pane: ViewHandle<Pane>,
pane: View<Pane>,
fs: Arc<dyn Fs>,
workspace: WeakViewHandle<Workspace>,
workspace: WeakView<Workspace>,
width: Option<f32>,
height: Option<f32>,
pending_serialization: Task<Option<()>>,
@ -48,12 +55,11 @@ pub struct TerminalPanel {
impl TerminalPanel {
fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
let weak_self = cx.weak_handle();
let pane = cx.add_view(|cx| {
let window = cx.window();
let pane = cx.build_view(|cx| {
let window = cx.window_handle();
let mut pane = Pane::new(
workspace.weak_handle(),
workspace.project().clone(),
workspace.app_state().background_actions,
Default::default(),
cx,
);
@ -78,7 +84,7 @@ impl TerminalPanel {
move |_, cx| {
let this = this.clone();
cx.window_context().defer(move |cx| {
if let Some(this) = this.upgrade(cx) {
if let Some(this) = this.upgrade() {
this.update(cx, |this, cx| {
this.add_terminal(None, cx);
});
@ -104,7 +110,7 @@ impl TerminalPanel {
))
.into_any()
});
let buffer_search_bar = cx.add_view(search::BufferSearchBar::new);
let buffer_search_bar = cx.build_view(search::BufferSearchBar::new);
pane.toolbar()
.update(cx, |toolbar, cx| toolbar.add_item(buffer_search_bar, cx));
pane
@ -123,7 +129,7 @@ impl TerminalPanel {
_subscriptions: subscriptions,
};
let mut old_dock_position = this.position(cx);
cx.observe_global::<SettingsStore, _>(move |this, cx| {
cx.observe_global::<SettingsStore>(move |this, cx| {
let new_dock_position = this.position(cx);
if new_dock_position != old_dock_position {
old_dock_position = new_dock_position;
@ -134,13 +140,10 @@ impl TerminalPanel {
this
}
pub fn load(
workspace: WeakViewHandle<Workspace>,
cx: AsyncAppContext,
) -> Task<Result<ViewHandle<Self>>> {
pub fn load(workspace: WeakView<Workspace>, cx: AsyncAppContext) -> Task<Result<View<Self>>> {
cx.spawn(|mut cx| async move {
let serialized_panel = if let Some(panel) = cx
.background()
.background_executor()
.spawn(async move { KEY_VALUE_STORE.read_kvp(TERMINAL_PANEL_KEY) })
.await
.log_err()
@ -151,7 +154,7 @@ impl TerminalPanel {
None
};
let (panel, pane, items) = workspace.update(&mut cx, |workspace, cx| {
let panel = cx.add_view(|cx| TerminalPanel::new(workspace, cx));
let panel = cx.build_view(|cx| TerminalPanel::new(workspace, cx));
let items = if let Some(serialized_panel) = serialized_panel.as_ref() {
panel.update(cx, |panel, cx| {
cx.notify();
@ -189,7 +192,7 @@ impl TerminalPanel {
let mut active_ix = None;
for item in items {
if let Some(item) = item.log_err() {
let item_id = item.id();
let item_id = item.entity_id().as_u64();
pane.add_item(Box::new(item), false, false, None, cx);
if Some(item_id) == active_item_id {
active_ix = Some(pane.items_len() - 1);
@ -208,7 +211,7 @@ impl TerminalPanel {
fn handle_pane_event(
&mut self,
_pane: ViewHandle<Pane>,
_pane: View<Pane>,
event: &pane::Event,
cx: &mut ViewContext<Self>,
) {
@ -221,7 +224,7 @@ impl TerminalPanel {
pane::Event::Focus => cx.emit(Event::Focus),
pane::Event::AddItem { item } => {
if let Some(workspace) = self.workspace.upgrade(cx) {
if let Some(workspace) = self.workspace.upgrade() {
let pane = self.pane.clone();
workspace.update(cx, |workspace, cx| item.added_to_pane(workspace, pane, cx))
}
@ -261,24 +264,23 @@ impl TerminalPanel {
fn add_terminal(&mut self, working_directory: Option<PathBuf>, cx: &mut ViewContext<Self>) {
let workspace = self.workspace.clone();
cx.spawn(|this, mut cx| async move {
let pane = this.read_with(&cx, |this, _| this.pane.clone())?;
let pane = this.update(&mut cx, |this, _| this.pane.clone())?;
workspace.update(&mut cx, |workspace, cx| {
let working_directory = if let Some(working_directory) = working_directory {
Some(working_directory)
} else {
let working_directory_strategy = settings::get::<TerminalSettings>(cx)
.working_directory
.clone();
let working_directory_strategy =
TerminalSettings::get_global(cx).working_directory.clone();
crate::get_working_directory(workspace, cx, working_directory_strategy)
};
let window = cx.window();
let window = cx.window_handle();
if let Some(terminal) = workspace.project().update(cx, |project, cx| {
project
.create_terminal(working_directory, window, cx)
.log_err()
}) {
let terminal = Box::new(cx.add_view(|cx| {
let terminal = Box::new(cx.build_view(|cx| {
TerminalView::new(
terminal,
workspace.weak_handle(),
@ -287,7 +289,7 @@ impl TerminalPanel {
)
}));
pane.update(cx, |pane, cx| {
let focus = pane.has_focus();
let focus = pane.has_focus(cx);
pane.add_item(terminal, true, focus, None, cx);
});
}
@ -303,12 +305,16 @@ impl TerminalPanel {
.pane
.read(cx)
.items()
.map(|item| item.id())
.map(|item| item.id().as_u64())
.collect::<Vec<_>>();
let active_item_id = self.pane.read(cx).active_item().map(|item| item.id());
let active_item_id = self
.pane
.read(cx)
.active_item()
.map(|item| item.id().as_u64());
let height = self.height;
let width = self.width;
self.pending_serialization = cx.background().spawn(
self.pending_serialization = cx.background_executor().spawn(
async move {
KEY_VALUE_STORE
.write_kvp(
@ -328,29 +334,25 @@ impl TerminalPanel {
}
}
impl Entity for TerminalPanel {
type Event = Event;
}
impl View for TerminalPanel {
fn ui_name() -> &'static str {
"TerminalPanel"
}
impl EventEmitter<Event> for TerminalPanel {}
impl EventEmitter<PanelEvent> for TerminalPanel {}
impl Render for TerminalPanel {
fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::AnyElement<Self> {
ChildView::new(&self.pane, cx).into_any()
}
fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
if cx.is_self_focused() {
cx.focus(&self.pane);
}
}
// todo!()
// fn focus_in(&mut self, _: gpui::AnyView, cx: &mut ViewContext<Self>) {
// if cx.is_self_focused() {
// cx.focus(&self.pane);
// }
// }
}
impl Panel for TerminalPanel {
fn position(&self, cx: &WindowContext) -> DockPosition {
match settings::get::<TerminalSettings>(cx).dock {
match TerminalSettings::get_global(cx).dock {
TerminalDockPosition::Left => DockPosition::Left,
TerminalDockPosition::Bottom => DockPosition::Bottom,
TerminalDockPosition::Right => DockPosition::Right,
@ -373,7 +375,7 @@ impl Panel for TerminalPanel {
}
fn size(&self, cx: &WindowContext) -> f32 {
let settings = settings::get::<TerminalSettings>(cx);
let settings = TerminalSettings::get_global(cx);
match self.position(cx) {
DockPosition::Left | DockPosition::Right => {
self.width.unwrap_or_else(|| settings.default_width)
@ -391,14 +393,6 @@ impl Panel for TerminalPanel {
cx.notify();
}
fn should_zoom_in_on_event(event: &Event) -> bool {
matches!(event, Event::ZoomIn)
}
fn should_zoom_out_on_event(event: &Event) -> bool {
matches!(event, Event::ZoomOut)
}
fn is_zoomed(&self, cx: &WindowContext) -> bool {
self.pane.read(cx).is_zoomed()
}
@ -430,31 +424,44 @@ impl Panel for TerminalPanel {
}
}
fn should_change_position_on_event(event: &Self::Event) -> bool {
matches!(event, Event::DockPositionChanged)
}
fn should_activate_on_event(_: &Self::Event) -> bool {
false
}
fn should_close_on_event(event: &Event) -> bool {
matches!(event, Event::Close)
}
fn has_focus(&self, cx: &WindowContext) -> bool {
self.pane.read(cx).has_focus()
self.pane.read(cx).has_focus(cx)
}
fn is_focus_event(event: &Self::Event) -> bool {
matches!(event, Event::Focus)
fn persistent_name(&self) -> &'static str {
todo!()
}
// todo!() is it needed?
// fn should_change_position_on_event(event: &Self::Event) -> bool {
// matches!(event, Event::DockPositionChanged)
// }
// fn should_activate_on_event(_: &Self::Event) -> bool {
// false
// }
// fn should_close_on_event(event: &Event) -> bool {
// matches!(event, Event::Close)
// }
// fn is_focus_event(event: &Self::Event) -> bool {
// matches!(event, Event::Focus)
// }
// fn should_zoom_in_on_event(event: &Event) -> bool {
// matches!(event, Event::ZoomIn)
// }
// fn should_zoom_out_on_event(event: &Event) -> bool {
// matches!(event, Event::ZoomOut)
// }
}
#[derive(Serialize, Deserialize)]
struct SerializedTerminalPanel {
items: Vec<usize>,
active_item_id: Option<usize>,
items: Vec<u64>,
active_item_id: Option<u64>,
width: Option<f32>,
height: Option<f32>,
}

View File

@ -10,10 +10,11 @@ use anyhow::Context;
use dirs::home_dir;
use editor::{scroll::autoscroll::Autoscroll, Editor};
use gpui::{
actions, div, img, red, register_action, AnyElement, AppContext, Component, Div, EventEmitter,
FocusEvent, FocusHandle, Focusable, FocusableKeyDispatch, InputHandler, KeyDownEvent,
Keystroke, Model, ParentElement, Pixels, Render, StatefulInteractivity, StatelessInteractive,
Styled, Task, View, ViewContext, VisualContext, WeakView,
actions, div, img, red, register_action, AnyElement, AppContext, Component, DispatchPhase, Div,
EventEmitter, FocusEvent, FocusHandle, Focusable, FocusableKeyDispatch, InputHandler,
KeyDownEvent, Keystroke, Model, ParentElement, Pixels, Render, SharedString,
StatefulInteractivity, StatelessInteractive, Styled, Task, View, ViewContext, VisualContext,
WeakView,
};
use language::Bias;
use project::{search::SearchQuery, LocalWorktree, Project};
@ -21,7 +22,6 @@ use serde::Deserialize;
use settings::Settings;
use smol::Timer;
use std::{
borrow::Cow,
ops::RangeInclusive,
path::{Path, PathBuf},
sync::Arc,
@ -40,7 +40,7 @@ use workspace::{
item::{BreadcrumbText, Item, ItemEvent},
notifications::NotifyResultExt,
register_deserializable_item,
searchable::{SearchEvent, SearchOptions, SearchableItem, SearchableItemHandle},
searchable::{SearchEvent, SearchOptions, SearchableItem},
NewCenterTerminal, Pane, ToolbarItemLocation, Workspace, WorkspaceId,
};
@ -51,11 +51,11 @@ const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
pub struct ScrollTerminal(pub i32);
#[register_action]
#[derive(Clone, Default, Deserialize, PartialEq)]
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
pub struct SendText(String);
#[register_action]
#[derive(Clone, Default, Deserialize, PartialEq)]
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
pub struct SendKeystroke(String);
actions!(Clear, Copy, Paste, ShowCharacterPalette, SearchTest);
@ -260,7 +260,7 @@ impl TerminalView {
has_bell: false,
focus_handle: cx.focus_handle(),
// todo!()
// context_menu: cx.add_view(|cx| ContextMenu::new(view_id, cx)),
// context_menu: cx.build_view(|cx| ContextMenu::new(view_id, cx)),
blink_state: true,
blinking_on: false,
blinking_paused: false,
@ -493,7 +493,12 @@ pub fn regex_search_for_query(query: &project::search::SearchQuery) -> Option<Re
}
impl TerminalView {
fn key_down(&mut self, event: &KeyDownEvent, cx: &mut ViewContext<Self>) -> bool {
fn key_down(
&mut self,
event: &KeyDownEvent,
_dispatch_phase: DispatchPhase,
cx: &mut ViewContext<Self>,
) {
self.clear_bel(cx);
self.pause_cursor_blinking(cx);
@ -502,7 +507,7 @@ impl TerminalView {
&event.keystroke,
TerminalSettings::get_global(cx).option_as_meta,
)
})
});
}
fn focus_in(&mut self, event: &FocusEvent, cx: &mut ViewContext<Self>) {
@ -652,7 +657,10 @@ impl InputHandler for TerminalView {
todo!()
}
fn selected_text_range(&self, cx: &AppContext) -> Option<std::ops::Range<usize>> {
fn selected_text_range(
&mut self,
cx: &mut ViewContext<Self>,
) -> Option<std::ops::Range<usize>> {
if self
.terminal
.read(cx)
@ -706,7 +714,7 @@ impl InputHandler for TerminalView {
}
impl Item for TerminalView {
fn tab_tooltip_text(&self, cx: &AppContext) -> Option<Cow<str>> {
fn tab_tooltip_text(&self, cx: &AppContext) -> Option<SharedString> {
Some(self.terminal().read(cx).title().into())
}
@ -727,7 +735,7 @@ impl Item for TerminalView {
&self,
_workspace_id: WorkspaceId,
_cx: &mut ViewContext<Self>,
) -> Option<Self> {
) -> Option<View<Self>> {
//From what I can tell, there's no way to tell the current working
//Directory of the terminal from outside the shell. There might be
//solutions to this, but they are non-trivial and require more IPC
@ -789,7 +797,7 @@ impl Item for TerminalView {
// cx.read(|cx| {
// let strategy = TerminalSettings::get_global(cx).working_directory.clone();
// workspace
// .upgrade(cx)
// .upgrade()
// .map(|workspace| {
// get_working_directory(workspace.read(cx), cx, strategy)
// })
@ -817,6 +825,10 @@ impl Item for TerminalView {
// .detach();
self.workspace_id = workspace.database_id();
}
fn focus_handle(&self) -> FocusHandle {
self.focus_handle.clone()
}
}
impl SearchableItem for TerminalView {
@ -1098,7 +1110,8 @@ mod tests {
let project = Project::test(params.fs.clone(), [], cx).await;
let workspace = cx
.add_window(|cx| Workspace::test_new(project.clone(), cx))
.root_view(cx);
.root_view(cx)
.unwrap();
(project, workspace)
}

View File

@ -179,7 +179,7 @@ pub struct Pane {
workspace: WeakView<Workspace>,
project: Model<Project>,
// can_drop: Rc<dyn Fn(&DragAndDrop<Workspace>, &WindowContext) -> bool>,
// can_split: bool,
can_split: bool,
// render_tab_bar_buttons: Rc<dyn Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement<Pane>>,
}
@ -347,7 +347,7 @@ impl Pane {
workspace,
project,
// can_drop: Rc::new(|_, _| true),
// can_split: true,
can_split: true,
// render_tab_bar_buttons: Rc::new(move |pane, cx| {
// Flex::row()
// // New menu
@ -427,17 +427,17 @@ impl Pane {
// self.can_drop = Rc::new(can_drop);
// }
// pub fn set_can_split(&mut self, can_split: bool, cx: &mut ViewContext<Self>) {
// self.can_split = can_split;
// cx.notify();
// }
pub fn set_can_split(&mut self, can_split: bool, cx: &mut ViewContext<Self>) {
self.can_split = can_split;
cx.notify();
}
// pub fn set_can_navigate(&mut self, can_navigate: bool, cx: &mut ViewContext<Self>) {
// self.toolbar.update(cx, |toolbar, cx| {
// toolbar.set_can_navigate(can_navigate, cx);
// });
// cx.notify();
// }
pub fn set_can_navigate(&mut self, can_navigate: bool, cx: &mut ViewContext<Self>) {
self.toolbar.update(cx, |toolbar, cx| {
toolbar.set_can_navigate(can_navigate, cx);
});
cx.notify();
}
// pub fn set_render_tab_bar_buttons<F>(&mut self, cx: &mut ViewContext<Self>, render: F)
// where

View File

@ -36,11 +36,12 @@ use futures::{
Future, FutureExt, StreamExt,
};
use gpui::{
actions, div, point, prelude::*, size, Action, AnyModel, AnyView, AnyWeakView, AppContext,
actions, div, point, register_action, size, Action, AnyModel, AnyView, AnyWeakView, AppContext,
AsyncAppContext, AsyncWindowContext, Bounds, Div, Entity, EntityId, EventEmitter, FocusHandle,
FocusableView, GlobalPixels, KeyContext, Model, ModelContext, ParentComponent, Point, Render,
Size, Styled, Subscription, Task, View, ViewContext, WeakView, WindowBounds, WindowContext,
WindowHandle, WindowOptions,
FocusableView, GlobalPixels, KeyContext, Model, ModelContext, ParentElement, Point, Render,
Size, StatefulInteractive, StatelessInteractive, StatelessInteractivity, Styled, Subscription,
Task, View, ViewContext, VisualContext, WeakView, WindowBounds, WindowContext, WindowHandle,
WindowOptions,
};
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem};
use itertools::Itertools;
@ -193,10 +194,11 @@ impl Clone for Toast {
}
}
// #[derive(Clone, Deserialize, PartialEq)]
// pub struct OpenTerminal {
// pub working_directory: PathBuf,
// }
#[register_action]
#[derive(Debug, Default, Clone, Deserialize, PartialEq)]
pub struct OpenTerminal {
pub working_directory: PathBuf,
}
// impl_actions!(
// workspace,
@ -206,7 +208,6 @@ impl Clone for Toast {
// SwapPaneInDirection,
// NewFileInDirection,
// Toast,
// OpenTerminal,
// SaveAll,
// Save,
// CloseAllItemsAndPanes,