mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-19 18:41:56 +03:00
More compilation fixes
This commit is contained in:
parent
61d6cb880c
commit
a238368296
@ -1,4 +1,4 @@
|
|||||||
use gpui::{AppContext, FontFeatures};
|
use gpui::{AppContext, FontFeatures, Pixels};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::{collections::HashMap, path::PathBuf};
|
use std::{collections::HashMap, path::PathBuf};
|
||||||
@ -15,7 +15,7 @@ pub enum TerminalDockPosition {
|
|||||||
pub struct TerminalSettings {
|
pub struct TerminalSettings {
|
||||||
pub shell: Shell,
|
pub shell: Shell,
|
||||||
pub working_directory: WorkingDirectory,
|
pub working_directory: WorkingDirectory,
|
||||||
font_size: Option<f32>,
|
pub font_size: Option<Pixels>,
|
||||||
pub font_family: Option<String>,
|
pub font_family: Option<String>,
|
||||||
pub line_height: TerminalLineHeight,
|
pub line_height: TerminalLineHeight,
|
||||||
pub font_features: Option<FontFeatures>,
|
pub font_features: Option<FontFeatures>,
|
||||||
@ -90,14 +90,6 @@ pub struct TerminalSettingsContent {
|
|||||||
pub detect_venv: Option<VenvSettings>,
|
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 {
|
impl settings::Settings for TerminalSettings {
|
||||||
const KEY: Option<&'static str> = Some("terminal");
|
const KEY: Option<&'static str> = Some("terminal");
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use editor::{Cursor, HighlightedRange, HighlightedRangeLine};
|
use editor::{Cursor, HighlightedRange, HighlightedRangeLine};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
serde_json::json, AnyElement, Bounds, HighlightStyle, Hsla, Line, ModelContext, MouseButton,
|
AnyElement, AppContext, Bounds, Component, Element, HighlightStyle, Hsla, LayoutId, Line,
|
||||||
Pixels, Point, TextStyle, ViewContext, WeakModel, WindowContext,
|
ModelContext, MouseButton, Pixels, Point, TextStyle, Underline, ViewContext, WeakModel,
|
||||||
|
WindowContext,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::CursorShape;
|
use language::CursorShape;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
|
use settings::Settings;
|
||||||
use terminal::{
|
use terminal::{
|
||||||
alacritty_terminal::{
|
alacritty_terminal::{
|
||||||
ansi::{Color as AnsiColor, Color::Named, CursorShape as AlacCursorShape, NamedColor},
|
ansi::{Color as AnsiColor, Color::Named, CursorShape as AlacCursorShape, NamedColor},
|
||||||
@ -21,10 +23,9 @@ use terminal::{
|
|||||||
TerminalSize,
|
TerminalSize,
|
||||||
};
|
};
|
||||||
use theme::ThemeSettings;
|
use theme::ThemeSettings;
|
||||||
use util::ResultExt;
|
|
||||||
|
|
||||||
|
use std::mem;
|
||||||
use std::{fmt::Debug, ops::RangeInclusive};
|
use std::{fmt::Debug, ops::RangeInclusive};
|
||||||
use std::{mem, ops::Range};
|
|
||||||
|
|
||||||
use crate::TerminalView;
|
use crate::TerminalView;
|
||||||
|
|
||||||
@ -143,7 +144,7 @@ impl LayoutRect {
|
|||||||
cx.paint_quad(
|
cx.paint_quad(
|
||||||
Bounds::new(position, size),
|
Bounds::new(position, size),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
Some(self.color),
|
self.color,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
);
|
);
|
||||||
@ -282,10 +283,10 @@ impl TerminalElement {
|
|||||||
text_fragment: &Line,
|
text_fragment: &Line,
|
||||||
) -> Option<(Vector2F, f32)> {
|
) -> Option<(Vector2F, f32)> {
|
||||||
if cursor_point.line() < size.total_lines() as i32 {
|
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()
|
size.cell_width()
|
||||||
} else {
|
} else {
|
||||||
text_fragment.width()
|
text_fragment.width
|
||||||
};
|
};
|
||||||
|
|
||||||
//Cursor should always surround as much of the text as possible,
|
//Cursor should always surround as much of the text as possible,
|
||||||
@ -339,7 +340,7 @@ impl TerminalElement {
|
|||||||
|
|
||||||
let font_id = font_cache
|
let font_id = font_cache
|
||||||
.select_font(text_style.font_family_id, &properties)
|
.select_font(text_style.font_family_id, &properties)
|
||||||
.unwrap_or(text_style.font_id);
|
.unwrap_or(8text_style.font_id);
|
||||||
|
|
||||||
let mut result = RunStyle {
|
let mut result = RunStyle {
|
||||||
color: fg,
|
color: fg,
|
||||||
@ -369,7 +370,7 @@ impl TerminalElement {
|
|||||||
) -> impl Fn(E, &mut TerminalView, &mut EventContext<TerminalView>) {
|
) -> impl Fn(E, &mut TerminalView, &mut EventContext<TerminalView>) {
|
||||||
move |event, _: &mut TerminalView, cx| {
|
move |event, _: &mut TerminalView, cx| {
|
||||||
cx.focus_parent();
|
cx.focus_parent();
|
||||||
if let Some(conn_handle) = connection.upgrade(cx) {
|
if let Some(conn_handle) = connection.upgrade() {
|
||||||
conn_handle.update(cx, |terminal, cx| {
|
conn_handle.update(cx, |terminal, cx| {
|
||||||
f(terminal, origin, event, cx);
|
f(terminal, origin, event, cx);
|
||||||
|
|
||||||
@ -382,7 +383,7 @@ impl TerminalElement {
|
|||||||
fn attach_mouse_handlers(
|
fn attach_mouse_handlers(
|
||||||
&self,
|
&self,
|
||||||
origin: Point<Pixels>,
|
origin: Point<Pixels>,
|
||||||
visible_bounds: Bounds,
|
visible_bounds: Bounds<Pixels>,
|
||||||
mode: TermMode,
|
mode: TermMode,
|
||||||
cx: &mut ViewContext<TerminalView>,
|
cx: &mut ViewContext<TerminalView>,
|
||||||
) {
|
) {
|
||||||
@ -397,7 +398,7 @@ impl TerminalElement {
|
|||||||
let terminal_view = cx.handle();
|
let terminal_view = cx.handle();
|
||||||
cx.focus(&terminal_view);
|
cx.focus(&terminal_view);
|
||||||
v.context_menu.update(cx, |menu, _cx| menu.delay_cancel());
|
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| {
|
conn_handle.update(cx, |terminal, cx| {
|
||||||
terminal.mouse_down(&event, origin);
|
terminal.mouse_down(&event, origin);
|
||||||
|
|
||||||
@ -412,7 +413,7 @@ impl TerminalElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cx.is_self_focused() {
|
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| {
|
conn_handle.update(cx, |terminal, cx| {
|
||||||
terminal.mouse_drag(event, origin);
|
terminal.mouse_drag(event, origin);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
@ -435,7 +436,7 @@ impl TerminalElement {
|
|||||||
.on_click(
|
.on_click(
|
||||||
MouseButton::Right,
|
MouseButton::Right,
|
||||||
move |event, view: &mut TerminalView, cx| {
|
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))
|
conn_handle.update(cx, |terminal, _cx| terminal.mouse_mode(event.shift))
|
||||||
} else {
|
} else {
|
||||||
// If we can't get the model handle, probably can't deploy the context menu
|
// 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| {
|
.on_move(move |event, _: &mut TerminalView, cx| {
|
||||||
if cx.is_self_focused() {
|
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| {
|
conn_handle.update(cx, |terminal, cx| {
|
||||||
terminal.mouse_move(&event, origin);
|
terminal.mouse_move(&event, origin);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
@ -457,7 +458,7 @@ impl TerminalElement {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on_scroll(move |event, _: &mut TerminalView, cx| {
|
.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| {
|
conn_handle.update(cx, |terminal, cx| {
|
||||||
terminal.scroll_wheel(event, origin);
|
terminal.scroll_wheel(event, origin);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
@ -516,17 +517,16 @@ impl TerminalElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Element<TerminalView> for TerminalElement {
|
impl Element<TerminalView> for TerminalElement {
|
||||||
type LayoutState = LayoutState;
|
type ElementState = LayoutState;
|
||||||
type PaintState = ();
|
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
constraint: gpui::SizeConstraint,
|
view_state: &mut TerminalView,
|
||||||
view: &mut TerminalView,
|
element_state: &mut Self::ElementState,
|
||||||
cx: &mut ViewContext<TerminalView>,
|
cx: &mut ViewContext<TerminalView>,
|
||||||
) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
|
) -> LayoutId {
|
||||||
let settings = settings::get::<ThemeSettings>(cx);
|
let settings = ThemeSettings::get_global(cx);
|
||||||
let terminal_settings = settings::get::<TerminalSettings>(cx);
|
let terminal_settings = TerminalSettings::get_global(cx);
|
||||||
|
|
||||||
//Setup layout information
|
//Setup layout information
|
||||||
let terminal_theme = settings.theme.terminal.clone(); //TODO: Try to minimize this clone.
|
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 tooltip_style = settings.theme.tooltip.clone();
|
||||||
|
|
||||||
let font_cache = cx.font_cache();
|
let font_cache = cx.font_cache();
|
||||||
let font_size = terminal_settings
|
let font_size = font_size(&terminal_settings, cx).unwrap_or(settings.buffer_font_size(cx));
|
||||||
.font_size(cx)
|
|
||||||
.unwrap_or(settings.buffer_font_size(cx));
|
|
||||||
let font_family_name = terminal_settings
|
let font_family_name = terminal_settings
|
||||||
.font_family
|
.font_family
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@ -575,14 +573,14 @@ impl Element<TerminalView> for TerminalElement {
|
|||||||
TerminalSize::new(line_height, cell_width, size)
|
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()
|
terminal_model.read(cx).matches.clone()
|
||||||
} else {
|
} else {
|
||||||
Default::default()
|
Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let background_color = terminal_theme.background;
|
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| {
|
let last_hovered_word = terminal_handle.update(cx, |terminal, cx| {
|
||||||
terminal.set_size(dimensions);
|
terminal.set_size(dimensions);
|
||||||
@ -614,7 +612,7 @@ impl Element<TerminalView> for TerminalElement {
|
|||||||
|
|
||||||
tooltip.layout(
|
tooltip.layout(
|
||||||
SizeConstraint::new(Vector2F::zero(), cx.window_size()),
|
SizeConstraint::new(Vector2F::zero(), cx.window_size()),
|
||||||
view,
|
view_state,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
tooltip
|
tooltip
|
||||||
@ -709,7 +707,7 @@ impl Element<TerminalView> for TerminalElement {
|
|||||||
//Done!
|
//Done!
|
||||||
(
|
(
|
||||||
constraint.max,
|
constraint.max,
|
||||||
LayoutState {
|
Self::ElementState {
|
||||||
cells,
|
cells,
|
||||||
cursor,
|
cursor,
|
||||||
background_color,
|
background_color,
|
||||||
@ -726,26 +724,25 @@ impl Element<TerminalView> for TerminalElement {
|
|||||||
|
|
||||||
fn paint(
|
fn paint(
|
||||||
&mut self,
|
&mut self,
|
||||||
bounds: Bounds,
|
bounds: Bounds<Pixels>,
|
||||||
visible_bounds: Bounds,
|
view_state: &mut TerminalView,
|
||||||
layout: &mut Self::LayoutState,
|
element_state: &mut Self::ElementState,
|
||||||
view: &mut TerminalView,
|
|
||||||
cx: &mut ViewContext<TerminalView>,
|
cx: &mut ViewContext<TerminalView>,
|
||||||
) -> Self::PaintState {
|
) {
|
||||||
let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
|
let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
|
||||||
|
|
||||||
//Setup element stuff
|
//Setup element stuff
|
||||||
let clip_bounds = Some(visible_bounds);
|
let clip_bounds = Some(visible_bounds);
|
||||||
|
|
||||||
cx.paint_layer(clip_bounds, |cx| {
|
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
|
// 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 {
|
cx.scene().push_cursor_region(gpui::CursorRegion {
|
||||||
bounds,
|
bounds,
|
||||||
style: if layout.hyperlink_tooltip.is_some() {
|
style: if element_state.hyperlink_tooltip.is_some() {
|
||||||
CursorStyle::AlacPointingHand
|
CursorStyle::AlacPointingHand
|
||||||
} else {
|
} else {
|
||||||
CursorStyle::IBeam
|
CursorStyle::IBeam
|
||||||
@ -755,31 +752,34 @@ impl Element<TerminalView> for TerminalElement {
|
|||||||
cx.paint_layer(clip_bounds, |cx| {
|
cx.paint_layer(clip_bounds, |cx| {
|
||||||
//Start with a background color
|
//Start with a background color
|
||||||
cx.scene().push_quad(Quad {
|
cx.scene().push_quad(Quad {
|
||||||
bounds: RectF::new(bounds.origin(), bounds.size()),
|
bounds,
|
||||||
background: Some(layout.background_color),
|
background: Some(element_state.background_color),
|
||||||
border: Default::default(),
|
border: Default::default(),
|
||||||
corner_radii: Default::default(),
|
corner_radii: Default::default(),
|
||||||
});
|
});
|
||||||
|
|
||||||
for rect in &layout.rects {
|
for rect in &element_state.rects {
|
||||||
rect.paint(origin, layout, view, cx);
|
rect.paint(origin, element_state, view_state, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Draw Highlighted Backgrounds
|
//Draw Highlighted Backgrounds
|
||||||
cx.paint_layer(clip_bounds, |cx| {
|
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)) =
|
if let Some((start_y, highlighted_range_lines)) = to_highlighted_range_lines(
|
||||||
to_highlighted_range_lines(relative_highlighted_range, layout, origin)
|
relative_highlighted_range,
|
||||||
{
|
element_state,
|
||||||
|
origin,
|
||||||
|
) {
|
||||||
let hr = HighlightedRange {
|
let hr = HighlightedRange {
|
||||||
start_y, //Need to change this
|
start_y, //Need to change this
|
||||||
line_height: layout.size.line_height,
|
line_height: element_state.size.line_height,
|
||||||
lines: highlighted_range_lines,
|
lines: highlighted_range_lines,
|
||||||
color: color.clone(),
|
color: color.clone(),
|
||||||
//Copied from editor. TODO: move to theme or something
|
//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);
|
hr.paint(bounds, cx);
|
||||||
}
|
}
|
||||||
@ -788,63 +788,83 @@ impl Element<TerminalView> for TerminalElement {
|
|||||||
|
|
||||||
//Draw the text cells
|
//Draw the text cells
|
||||||
cx.paint_layer(clip_bounds, |cx| {
|
cx.paint_layer(clip_bounds, |cx| {
|
||||||
for cell in &layout.cells {
|
for cell in &element_state.cells {
|
||||||
cell.paint(origin, layout, visible_bounds, view, cx);
|
cell.paint(origin, element_state, visible_bounds, view_state, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Draw cursor
|
//Draw cursor
|
||||||
if self.cursor_visible {
|
if self.cursor_visible {
|
||||||
if let Some(cursor) = &layout.cursor {
|
if let Some(cursor) = &element_state.cursor {
|
||||||
cx.paint_layer(clip_bounds, |cx| {
|
cx.paint_layer(clip_bounds, |cx| {
|
||||||
cursor.paint(origin, cx);
|
cursor.paint(origin, cx);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(element) = &mut layout.hyperlink_tooltip {
|
if let Some(element) = &mut element_state.hyperlink_tooltip {
|
||||||
element.paint(origin, visible_bounds, view, cx)
|
element.paint(origin, visible_bounds, view_state, cx)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Option<&dyn std::any::Any> {
|
fn id(&self) -> Option<gpui::ElementId> {
|
||||||
None
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug(
|
fn initialize(
|
||||||
&self,
|
&mut self,
|
||||||
_: Bounds,
|
view_state: &mut TerminalView,
|
||||||
_: &Self::LayoutState,
|
element_state: Option<Self::ElementState>,
|
||||||
_: &Self::PaintState,
|
cx: &mut ViewContext<TerminalView>,
|
||||||
_: &TerminalView,
|
) -> Self::ElementState {
|
||||||
_: &gpui::ViewContext<TerminalView>,
|
todo!()
|
||||||
) -> gpui::serde_json::Value {
|
|
||||||
json!({
|
|
||||||
"type": "TerminalElement",
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rect_for_text_range(
|
// todo!() remove?
|
||||||
&self,
|
// fn metadata(&self) -> Option<&dyn std::any::Any> {
|
||||||
_: Range<usize>,
|
// None
|
||||||
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 - Why is it necessary to move downward one line to get correct
|
// fn debug(
|
||||||
// positioning? I would think that we'd want the same rect that is
|
// &self,
|
||||||
// painted for the cursor.
|
// _: Bounds<Pixels>,
|
||||||
origin += vec2f(0., layout.size.line_height);
|
// _: &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))
|
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))
|
||||||
|
}
|
||||||
|
@ -3,27 +3,34 @@ use std::{path::PathBuf, sync::Arc};
|
|||||||
use crate::TerminalView;
|
use crate::TerminalView;
|
||||||
use db::kvp::KEY_VALUE_STORE;
|
use db::kvp::KEY_VALUE_STORE;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, anyhow::Result, elements::*, serde_json, Action, AppContext, AsyncAppContext, Entity,
|
actions, serde_json, Action, AppContext, AsyncAppContext, Entity, EventEmitter, Render,
|
||||||
Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext,
|
Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
|
||||||
};
|
};
|
||||||
use project::Fs;
|
use project::Fs;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use settings::SettingsStore;
|
use settings::{Settings, SettingsStore};
|
||||||
use terminal::terminal_settings::{TerminalDockPosition, TerminalSettings};
|
use terminal::terminal_settings::{TerminalDockPosition, TerminalSettings};
|
||||||
use util::{ResultExt, TryFutureExt};
|
use util::{ResultExt, TryFutureExt};
|
||||||
use workspace::{
|
use workspace::{
|
||||||
dock::{DockPosition, Panel},
|
dock::{DockPosition, Panel, PanelEvent},
|
||||||
item::Item,
|
item::Item,
|
||||||
pane, DraggedItem, Pane, Workspace,
|
pane, Pane, Workspace,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
const TERMINAL_PANEL_KEY: &'static str = "TerminalPanel";
|
const TERMINAL_PANEL_KEY: &'static str = "TerminalPanel";
|
||||||
|
|
||||||
actions!(terminal_panel, [ToggleFocus]);
|
actions!(ToggleFocus);
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
cx.add_action(TerminalPanel::new_terminal);
|
cx.observe_new_views(
|
||||||
cx.add_action(TerminalPanel::open_terminal);
|
|workspace: &mut Workspace, _: &mut ViewContext<Workspace>| {
|
||||||
|
workspace.register_action(TerminalPanel::new_terminal);
|
||||||
|
workspace.register_action(TerminalPanel::open_terminal);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -36,9 +43,9 @@ pub enum Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct TerminalPanel {
|
pub struct TerminalPanel {
|
||||||
pane: ViewHandle<Pane>,
|
pane: View<Pane>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakView<Workspace>,
|
||||||
width: Option<f32>,
|
width: Option<f32>,
|
||||||
height: Option<f32>,
|
height: Option<f32>,
|
||||||
pending_serialization: Task<Option<()>>,
|
pending_serialization: Task<Option<()>>,
|
||||||
@ -48,12 +55,11 @@ pub struct TerminalPanel {
|
|||||||
impl TerminalPanel {
|
impl TerminalPanel {
|
||||||
fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
|
fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
|
||||||
let weak_self = cx.weak_handle();
|
let weak_self = cx.weak_handle();
|
||||||
let pane = cx.add_view(|cx| {
|
let pane = cx.build_view(|cx| {
|
||||||
let window = cx.window();
|
let window = cx.window_handle();
|
||||||
let mut pane = Pane::new(
|
let mut pane = Pane::new(
|
||||||
workspace.weak_handle(),
|
workspace.weak_handle(),
|
||||||
workspace.project().clone(),
|
workspace.project().clone(),
|
||||||
workspace.app_state().background_actions,
|
|
||||||
Default::default(),
|
Default::default(),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
@ -78,7 +84,7 @@ impl TerminalPanel {
|
|||||||
move |_, cx| {
|
move |_, cx| {
|
||||||
let this = this.clone();
|
let this = this.clone();
|
||||||
cx.window_context().defer(move |cx| {
|
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.update(cx, |this, cx| {
|
||||||
this.add_terminal(None, cx);
|
this.add_terminal(None, cx);
|
||||||
});
|
});
|
||||||
@ -104,7 +110,7 @@ impl TerminalPanel {
|
|||||||
))
|
))
|
||||||
.into_any()
|
.into_any()
|
||||||
});
|
});
|
||||||
let buffer_search_bar = cx.add_view(search::BufferSearchBar::new);
|
let buffer_search_bar = cx.build_view(search::BufferSearchBar::new);
|
||||||
pane.toolbar()
|
pane.toolbar()
|
||||||
.update(cx, |toolbar, cx| toolbar.add_item(buffer_search_bar, cx));
|
.update(cx, |toolbar, cx| toolbar.add_item(buffer_search_bar, cx));
|
||||||
pane
|
pane
|
||||||
@ -123,7 +129,7 @@ impl TerminalPanel {
|
|||||||
_subscriptions: subscriptions,
|
_subscriptions: subscriptions,
|
||||||
};
|
};
|
||||||
let mut old_dock_position = this.position(cx);
|
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);
|
let new_dock_position = this.position(cx);
|
||||||
if new_dock_position != old_dock_position {
|
if new_dock_position != old_dock_position {
|
||||||
old_dock_position = new_dock_position;
|
old_dock_position = new_dock_position;
|
||||||
@ -134,13 +140,10 @@ impl TerminalPanel {
|
|||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(
|
pub fn load(workspace: WeakView<Workspace>, cx: AsyncAppContext) -> Task<Result<View<Self>>> {
|
||||||
workspace: WeakViewHandle<Workspace>,
|
|
||||||
cx: AsyncAppContext,
|
|
||||||
) -> Task<Result<ViewHandle<Self>>> {
|
|
||||||
cx.spawn(|mut cx| async move {
|
cx.spawn(|mut cx| async move {
|
||||||
let serialized_panel = if let Some(panel) = cx
|
let serialized_panel = if let Some(panel) = cx
|
||||||
.background()
|
.background_executor()
|
||||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(TERMINAL_PANEL_KEY) })
|
.spawn(async move { KEY_VALUE_STORE.read_kvp(TERMINAL_PANEL_KEY) })
|
||||||
.await
|
.await
|
||||||
.log_err()
|
.log_err()
|
||||||
@ -151,7 +154,7 @@ impl TerminalPanel {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
let (panel, pane, items) = workspace.update(&mut cx, |workspace, cx| {
|
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() {
|
let items = if let Some(serialized_panel) = serialized_panel.as_ref() {
|
||||||
panel.update(cx, |panel, cx| {
|
panel.update(cx, |panel, cx| {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
@ -189,7 +192,7 @@ impl TerminalPanel {
|
|||||||
let mut active_ix = None;
|
let mut active_ix = None;
|
||||||
for item in items {
|
for item in items {
|
||||||
if let Some(item) = item.log_err() {
|
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);
|
pane.add_item(Box::new(item), false, false, None, cx);
|
||||||
if Some(item_id) == active_item_id {
|
if Some(item_id) == active_item_id {
|
||||||
active_ix = Some(pane.items_len() - 1);
|
active_ix = Some(pane.items_len() - 1);
|
||||||
@ -208,7 +211,7 @@ impl TerminalPanel {
|
|||||||
|
|
||||||
fn handle_pane_event(
|
fn handle_pane_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
_pane: ViewHandle<Pane>,
|
_pane: View<Pane>,
|
||||||
event: &pane::Event,
|
event: &pane::Event,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
@ -221,7 +224,7 @@ impl TerminalPanel {
|
|||||||
pane::Event::Focus => cx.emit(Event::Focus),
|
pane::Event::Focus => cx.emit(Event::Focus),
|
||||||
|
|
||||||
pane::Event::AddItem { item } => {
|
pane::Event::AddItem { item } => {
|
||||||
if let Some(workspace) = self.workspace.upgrade(cx) {
|
if let Some(workspace) = self.workspace.upgrade() {
|
||||||
let pane = self.pane.clone();
|
let pane = self.pane.clone();
|
||||||
workspace.update(cx, |workspace, cx| item.added_to_pane(workspace, pane, cx))
|
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>) {
|
fn add_terminal(&mut self, working_directory: Option<PathBuf>, cx: &mut ViewContext<Self>) {
|
||||||
let workspace = self.workspace.clone();
|
let workspace = self.workspace.clone();
|
||||||
cx.spawn(|this, mut cx| async move {
|
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| {
|
workspace.update(&mut cx, |workspace, cx| {
|
||||||
let working_directory = if let Some(working_directory) = working_directory {
|
let working_directory = if let Some(working_directory) = working_directory {
|
||||||
Some(working_directory)
|
Some(working_directory)
|
||||||
} else {
|
} else {
|
||||||
let working_directory_strategy = settings::get::<TerminalSettings>(cx)
|
let working_directory_strategy =
|
||||||
.working_directory
|
TerminalSettings::get_global(cx).working_directory.clone();
|
||||||
.clone();
|
|
||||||
crate::get_working_directory(workspace, cx, working_directory_strategy)
|
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| {
|
if let Some(terminal) = workspace.project().update(cx, |project, cx| {
|
||||||
project
|
project
|
||||||
.create_terminal(working_directory, window, cx)
|
.create_terminal(working_directory, window, cx)
|
||||||
.log_err()
|
.log_err()
|
||||||
}) {
|
}) {
|
||||||
let terminal = Box::new(cx.add_view(|cx| {
|
let terminal = Box::new(cx.build_view(|cx| {
|
||||||
TerminalView::new(
|
TerminalView::new(
|
||||||
terminal,
|
terminal,
|
||||||
workspace.weak_handle(),
|
workspace.weak_handle(),
|
||||||
@ -287,7 +289,7 @@ impl TerminalPanel {
|
|||||||
)
|
)
|
||||||
}));
|
}));
|
||||||
pane.update(cx, |pane, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
let focus = pane.has_focus();
|
let focus = pane.has_focus(cx);
|
||||||
pane.add_item(terminal, true, focus, None, cx);
|
pane.add_item(terminal, true, focus, None, cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -303,12 +305,16 @@ impl TerminalPanel {
|
|||||||
.pane
|
.pane
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.items()
|
.items()
|
||||||
.map(|item| item.id())
|
.map(|item| item.id().as_u64())
|
||||||
.collect::<Vec<_>>();
|
.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 height = self.height;
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
self.pending_serialization = cx.background().spawn(
|
self.pending_serialization = cx.background_executor().spawn(
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
@ -328,29 +334,25 @@ impl TerminalPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for TerminalPanel {
|
impl EventEmitter<Event> for TerminalPanel {}
|
||||||
type Event = Event;
|
impl EventEmitter<PanelEvent> for TerminalPanel {}
|
||||||
}
|
|
||||||
|
|
||||||
impl View for TerminalPanel {
|
|
||||||
fn ui_name() -> &'static str {
|
|
||||||
"TerminalPanel"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
impl Render for TerminalPanel {
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::AnyElement<Self> {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::AnyElement<Self> {
|
||||||
ChildView::new(&self.pane, cx).into_any()
|
ChildView::new(&self.pane, cx).into_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
|
// todo!()
|
||||||
if cx.is_self_focused() {
|
// fn focus_in(&mut self, _: gpui::AnyView, cx: &mut ViewContext<Self>) {
|
||||||
cx.focus(&self.pane);
|
// if cx.is_self_focused() {
|
||||||
}
|
// cx.focus(&self.pane);
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Panel for TerminalPanel {
|
impl Panel for TerminalPanel {
|
||||||
fn position(&self, cx: &WindowContext) -> DockPosition {
|
fn position(&self, cx: &WindowContext) -> DockPosition {
|
||||||
match settings::get::<TerminalSettings>(cx).dock {
|
match TerminalSettings::get_global(cx).dock {
|
||||||
TerminalDockPosition::Left => DockPosition::Left,
|
TerminalDockPosition::Left => DockPosition::Left,
|
||||||
TerminalDockPosition::Bottom => DockPosition::Bottom,
|
TerminalDockPosition::Bottom => DockPosition::Bottom,
|
||||||
TerminalDockPosition::Right => DockPosition::Right,
|
TerminalDockPosition::Right => DockPosition::Right,
|
||||||
@ -373,7 +375,7 @@ impl Panel for TerminalPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self, cx: &WindowContext) -> f32 {
|
fn size(&self, cx: &WindowContext) -> f32 {
|
||||||
let settings = settings::get::<TerminalSettings>(cx);
|
let settings = TerminalSettings::get_global(cx);
|
||||||
match self.position(cx) {
|
match self.position(cx) {
|
||||||
DockPosition::Left | DockPosition::Right => {
|
DockPosition::Left | DockPosition::Right => {
|
||||||
self.width.unwrap_or_else(|| settings.default_width)
|
self.width.unwrap_or_else(|| settings.default_width)
|
||||||
@ -391,14 +393,6 @@ impl Panel for TerminalPanel {
|
|||||||
cx.notify();
|
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 {
|
fn is_zoomed(&self, cx: &WindowContext) -> bool {
|
||||||
self.pane.read(cx).is_zoomed()
|
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 {
|
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 {
|
fn persistent_name(&self) -> &'static str {
|
||||||
matches!(event, Event::Focus)
|
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)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct SerializedTerminalPanel {
|
struct SerializedTerminalPanel {
|
||||||
items: Vec<usize>,
|
items: Vec<u64>,
|
||||||
active_item_id: Option<usize>,
|
active_item_id: Option<u64>,
|
||||||
width: Option<f32>,
|
width: Option<f32>,
|
||||||
height: Option<f32>,
|
height: Option<f32>,
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,11 @@ use anyhow::Context;
|
|||||||
use dirs::home_dir;
|
use dirs::home_dir;
|
||||||
use editor::{scroll::autoscroll::Autoscroll, Editor};
|
use editor::{scroll::autoscroll::Autoscroll, Editor};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, img, red, register_action, AnyElement, AppContext, Component, Div, EventEmitter,
|
actions, div, img, red, register_action, AnyElement, AppContext, Component, DispatchPhase, Div,
|
||||||
FocusEvent, FocusHandle, Focusable, FocusableKeyDispatch, InputHandler, KeyDownEvent,
|
EventEmitter, FocusEvent, FocusHandle, Focusable, FocusableKeyDispatch, InputHandler,
|
||||||
Keystroke, Model, ParentElement, Pixels, Render, StatefulInteractivity, StatelessInteractive,
|
KeyDownEvent, Keystroke, Model, ParentElement, Pixels, Render, SharedString,
|
||||||
Styled, Task, View, ViewContext, VisualContext, WeakView,
|
StatefulInteractivity, StatelessInteractive, Styled, Task, View, ViewContext, VisualContext,
|
||||||
|
WeakView,
|
||||||
};
|
};
|
||||||
use language::Bias;
|
use language::Bias;
|
||||||
use project::{search::SearchQuery, LocalWorktree, Project};
|
use project::{search::SearchQuery, LocalWorktree, Project};
|
||||||
@ -21,7 +22,6 @@ use serde::Deserialize;
|
|||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use smol::Timer;
|
use smol::Timer;
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
|
||||||
ops::RangeInclusive,
|
ops::RangeInclusive,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
@ -40,7 +40,7 @@ use workspace::{
|
|||||||
item::{BreadcrumbText, Item, ItemEvent},
|
item::{BreadcrumbText, Item, ItemEvent},
|
||||||
notifications::NotifyResultExt,
|
notifications::NotifyResultExt,
|
||||||
register_deserializable_item,
|
register_deserializable_item,
|
||||||
searchable::{SearchEvent, SearchOptions, SearchableItem, SearchableItemHandle},
|
searchable::{SearchEvent, SearchOptions, SearchableItem},
|
||||||
NewCenterTerminal, Pane, ToolbarItemLocation, Workspace, WorkspaceId,
|
NewCenterTerminal, Pane, ToolbarItemLocation, Workspace, WorkspaceId,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,11 +51,11 @@ const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
|
|||||||
pub struct ScrollTerminal(pub i32);
|
pub struct ScrollTerminal(pub i32);
|
||||||
|
|
||||||
#[register_action]
|
#[register_action]
|
||||||
#[derive(Clone, Default, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
|
||||||
pub struct SendText(String);
|
pub struct SendText(String);
|
||||||
|
|
||||||
#[register_action]
|
#[register_action]
|
||||||
#[derive(Clone, Default, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
|
||||||
pub struct SendKeystroke(String);
|
pub struct SendKeystroke(String);
|
||||||
|
|
||||||
actions!(Clear, Copy, Paste, ShowCharacterPalette, SearchTest);
|
actions!(Clear, Copy, Paste, ShowCharacterPalette, SearchTest);
|
||||||
@ -260,7 +260,7 @@ impl TerminalView {
|
|||||||
has_bell: false,
|
has_bell: false,
|
||||||
focus_handle: cx.focus_handle(),
|
focus_handle: cx.focus_handle(),
|
||||||
// todo!()
|
// 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,
|
blink_state: true,
|
||||||
blinking_on: false,
|
blinking_on: false,
|
||||||
blinking_paused: false,
|
blinking_paused: false,
|
||||||
@ -493,7 +493,12 @@ pub fn regex_search_for_query(query: &project::search::SearchQuery) -> Option<Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TerminalView {
|
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.clear_bel(cx);
|
||||||
self.pause_cursor_blinking(cx);
|
self.pause_cursor_blinking(cx);
|
||||||
|
|
||||||
@ -502,7 +507,7 @@ impl TerminalView {
|
|||||||
&event.keystroke,
|
&event.keystroke,
|
||||||
TerminalSettings::get_global(cx).option_as_meta,
|
TerminalSettings::get_global(cx).option_as_meta,
|
||||||
)
|
)
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus_in(&mut self, event: &FocusEvent, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, event: &FocusEvent, cx: &mut ViewContext<Self>) {
|
||||||
@ -652,7 +657,10 @@ impl InputHandler for TerminalView {
|
|||||||
todo!()
|
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
|
if self
|
||||||
.terminal
|
.terminal
|
||||||
.read(cx)
|
.read(cx)
|
||||||
@ -706,7 +714,7 @@ impl InputHandler for TerminalView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Item 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())
|
Some(self.terminal().read(cx).title().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,7 +735,7 @@ impl Item for TerminalView {
|
|||||||
&self,
|
&self,
|
||||||
_workspace_id: WorkspaceId,
|
_workspace_id: WorkspaceId,
|
||||||
_cx: &mut ViewContext<Self>,
|
_cx: &mut ViewContext<Self>,
|
||||||
) -> Option<Self> {
|
) -> Option<View<Self>> {
|
||||||
//From what I can tell, there's no way to tell the current working
|
//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
|
//Directory of the terminal from outside the shell. There might be
|
||||||
//solutions to this, but they are non-trivial and require more IPC
|
//solutions to this, but they are non-trivial and require more IPC
|
||||||
@ -789,7 +797,7 @@ impl Item for TerminalView {
|
|||||||
// cx.read(|cx| {
|
// cx.read(|cx| {
|
||||||
// let strategy = TerminalSettings::get_global(cx).working_directory.clone();
|
// let strategy = TerminalSettings::get_global(cx).working_directory.clone();
|
||||||
// workspace
|
// workspace
|
||||||
// .upgrade(cx)
|
// .upgrade()
|
||||||
// .map(|workspace| {
|
// .map(|workspace| {
|
||||||
// get_working_directory(workspace.read(cx), cx, strategy)
|
// get_working_directory(workspace.read(cx), cx, strategy)
|
||||||
// })
|
// })
|
||||||
@ -817,6 +825,10 @@ impl Item for TerminalView {
|
|||||||
// .detach();
|
// .detach();
|
||||||
self.workspace_id = workspace.database_id();
|
self.workspace_id = workspace.database_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn focus_handle(&self) -> FocusHandle {
|
||||||
|
self.focus_handle.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SearchableItem for TerminalView {
|
impl SearchableItem for TerminalView {
|
||||||
@ -1098,7 +1110,8 @@ mod tests {
|
|||||||
let project = Project::test(params.fs.clone(), [], cx).await;
|
let project = Project::test(params.fs.clone(), [], cx).await;
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
.add_window(|cx| Workspace::test_new(project.clone(), cx))
|
||||||
.root_view(cx);
|
.root_view(cx)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
(project, workspace)
|
(project, workspace)
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ pub struct Pane {
|
|||||||
workspace: WeakView<Workspace>,
|
workspace: WeakView<Workspace>,
|
||||||
project: Model<Project>,
|
project: Model<Project>,
|
||||||
// can_drop: Rc<dyn Fn(&DragAndDrop<Workspace>, &WindowContext) -> bool>,
|
// 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>>,
|
// render_tab_bar_buttons: Rc<dyn Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement<Pane>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ impl Pane {
|
|||||||
workspace,
|
workspace,
|
||||||
project,
|
project,
|
||||||
// can_drop: Rc::new(|_, _| true),
|
// can_drop: Rc::new(|_, _| true),
|
||||||
// can_split: true,
|
can_split: true,
|
||||||
// render_tab_bar_buttons: Rc::new(move |pane, cx| {
|
// render_tab_bar_buttons: Rc::new(move |pane, cx| {
|
||||||
// Flex::row()
|
// Flex::row()
|
||||||
// // New menu
|
// // New menu
|
||||||
@ -427,17 +427,17 @@ impl Pane {
|
|||||||
// self.can_drop = Rc::new(can_drop);
|
// self.can_drop = Rc::new(can_drop);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn set_can_split(&mut self, can_split: bool, cx: &mut ViewContext<Self>) {
|
pub fn set_can_split(&mut self, can_split: bool, cx: &mut ViewContext<Self>) {
|
||||||
// self.can_split = can_split;
|
self.can_split = can_split;
|
||||||
// cx.notify();
|
cx.notify();
|
||||||
// }
|
}
|
||||||
|
|
||||||
// pub fn set_can_navigate(&mut self, can_navigate: bool, cx: &mut ViewContext<Self>) {
|
pub fn set_can_navigate(&mut self, can_navigate: bool, cx: &mut ViewContext<Self>) {
|
||||||
// self.toolbar.update(cx, |toolbar, cx| {
|
self.toolbar.update(cx, |toolbar, cx| {
|
||||||
// toolbar.set_can_navigate(can_navigate, cx);
|
toolbar.set_can_navigate(can_navigate, cx);
|
||||||
// });
|
});
|
||||||
// cx.notify();
|
cx.notify();
|
||||||
// }
|
}
|
||||||
|
|
||||||
// pub fn set_render_tab_bar_buttons<F>(&mut self, cx: &mut ViewContext<Self>, render: F)
|
// pub fn set_render_tab_bar_buttons<F>(&mut self, cx: &mut ViewContext<Self>, render: F)
|
||||||
// where
|
// where
|
||||||
|
@ -36,11 +36,12 @@ use futures::{
|
|||||||
Future, FutureExt, StreamExt,
|
Future, FutureExt, StreamExt,
|
||||||
};
|
};
|
||||||
use gpui::{
|
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,
|
AsyncAppContext, AsyncWindowContext, Bounds, Div, Entity, EntityId, EventEmitter, FocusHandle,
|
||||||
FocusableView, GlobalPixels, KeyContext, Model, ModelContext, ParentComponent, Point, Render,
|
FocusableView, GlobalPixels, KeyContext, Model, ModelContext, ParentElement, Point, Render,
|
||||||
Size, Styled, Subscription, Task, View, ViewContext, WeakView, WindowBounds, WindowContext,
|
Size, StatefulInteractive, StatelessInteractive, StatelessInteractivity, Styled, Subscription,
|
||||||
WindowHandle, WindowOptions,
|
Task, View, ViewContext, VisualContext, WeakView, WindowBounds, WindowContext, WindowHandle,
|
||||||
|
WindowOptions,
|
||||||
};
|
};
|
||||||
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem};
|
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
@ -193,10 +194,11 @@ impl Clone for Toast {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[derive(Clone, Deserialize, PartialEq)]
|
#[register_action]
|
||||||
// pub struct OpenTerminal {
|
#[derive(Debug, Default, Clone, Deserialize, PartialEq)]
|
||||||
// pub working_directory: PathBuf,
|
pub struct OpenTerminal {
|
||||||
// }
|
pub working_directory: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
// impl_actions!(
|
// impl_actions!(
|
||||||
// workspace,
|
// workspace,
|
||||||
@ -206,7 +208,6 @@ impl Clone for Toast {
|
|||||||
// SwapPaneInDirection,
|
// SwapPaneInDirection,
|
||||||
// NewFileInDirection,
|
// NewFileInDirection,
|
||||||
// Toast,
|
// Toast,
|
||||||
// OpenTerminal,
|
|
||||||
// SaveAll,
|
// SaveAll,
|
||||||
// Save,
|
// Save,
|
||||||
// CloseAllItemsAndPanes,
|
// CloseAllItemsAndPanes,
|
||||||
|
Loading…
Reference in New Issue
Block a user