Merge branch 'main' into terminal-hyperlinks
This commit is contained in:
commit
a686a9f1d2
102 changed files with 5848 additions and 1966 deletions
|
@ -6,6 +6,7 @@ use alacritty_terminal::grid::Dimensions;
|
|||
/// with modifications for our circumstances
|
||||
use alacritty_terminal::index::{Column as GridCol, Line as GridLine, Point, Side};
|
||||
use alacritty_terminal::term::TermMode;
|
||||
use gpui::scene::ScrollWheelRegionEvent;
|
||||
use gpui::{geometry::vector::Vector2F, MouseButtonEvent, MouseMovedEvent, ScrollWheelEvent};
|
||||
|
||||
use crate::TerminalSize;
|
||||
|
@ -114,7 +115,7 @@ impl MouseButton {
|
|||
pub fn scroll_report(
|
||||
point: Point,
|
||||
scroll_lines: i32,
|
||||
e: &ScrollWheelEvent,
|
||||
e: &ScrollWheelRegionEvent,
|
||||
mode: TermMode,
|
||||
) -> Option<impl Iterator<Item = Vec<u8>>> {
|
||||
if mode.intersects(TermMode::MOUSE_MODE) {
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
use gpui::{ModelHandle, ViewContext};
|
||||
use settings::{Settings, WorkingDirectory};
|
||||
use workspace::{programs::ProgramManager, Workspace};
|
||||
|
||||
use crate::{
|
||||
terminal_container_view::{
|
||||
get_working_directory, DeployModal, TerminalContainer, TerminalContainerContent,
|
||||
},
|
||||
Event, Terminal,
|
||||
};
|
||||
|
||||
pub fn deploy_modal(workspace: &mut Workspace, _: &DeployModal, cx: &mut ViewContext<Workspace>) {
|
||||
let window = cx.window_id();
|
||||
|
||||
// Pull the terminal connection out of the global if it has been stored
|
||||
let possible_terminal = ProgramManager::remove::<Terminal, _>(window, cx);
|
||||
|
||||
if let Some(terminal_handle) = possible_terminal {
|
||||
workspace.toggle_modal(cx, |_, cx| {
|
||||
// Create a view from the stored connection if the terminal modal is not already shown
|
||||
cx.add_view(|cx| TerminalContainer::from_terminal(terminal_handle.clone(), true, cx))
|
||||
});
|
||||
// Toggle Modal will dismiss the terminal modal if it is currently shown, so we must
|
||||
// store the terminal back in the global
|
||||
ProgramManager::insert_or_replace::<Terminal, _>(window, terminal_handle, cx);
|
||||
} else {
|
||||
// No connection was stored, create a new terminal
|
||||
if let Some(closed_terminal_handle) = workspace.toggle_modal(cx, |workspace, cx| {
|
||||
// No terminal modal visible, construct a new one.
|
||||
let wd_strategy = cx
|
||||
.global::<Settings>()
|
||||
.terminal_overrides
|
||||
.working_directory
|
||||
.clone()
|
||||
.unwrap_or(WorkingDirectory::CurrentProjectDirectory);
|
||||
|
||||
let working_directory = get_working_directory(workspace, cx, wd_strategy);
|
||||
|
||||
let this = cx.add_view(|cx| TerminalContainer::new(working_directory, true, cx));
|
||||
|
||||
if let TerminalContainerContent::Connected(connected) = &this.read(cx).content {
|
||||
let terminal_handle = connected.read(cx).handle();
|
||||
cx.subscribe(&terminal_handle, on_event).detach();
|
||||
// Set the global immediately if terminal construction was successful,
|
||||
// in case the user opens the command palette
|
||||
ProgramManager::insert_or_replace::<Terminal, _>(window, terminal_handle, cx);
|
||||
}
|
||||
|
||||
this
|
||||
}) {
|
||||
// Terminal modal was dismissed and the terminal view is connected, store the terminal
|
||||
if let TerminalContainerContent::Connected(connected) =
|
||||
&closed_terminal_handle.read(cx).content
|
||||
{
|
||||
let terminal_handle = connected.read(cx).handle();
|
||||
// Set the global immediately if terminal construction was successful,
|
||||
// in case the user opens the command palette
|
||||
ProgramManager::insert_or_replace::<Terminal, _>(window, terminal_handle, cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_event(
|
||||
workspace: &mut Workspace,
|
||||
_: ModelHandle<Terminal>,
|
||||
event: &Event,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
// Dismiss the modal if the terminal quit
|
||||
if let Event::CloseTerminal = event {
|
||||
ProgramManager::remove::<Terminal, _>(cx.window_id(), cx);
|
||||
|
||||
if workspace.modal::<TerminalContainer>().is_some() {
|
||||
workspace.dismiss_modal(cx)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
pub mod mappings;
|
||||
pub mod modal;
|
||||
pub mod terminal_container_view;
|
||||
pub mod terminal_element;
|
||||
pub mod terminal_view;
|
||||
|
@ -32,7 +31,6 @@ use futures::{
|
|||
use mappings::mouse::{
|
||||
alt_scroll, grid_point, mouse_button_report, mouse_moved_report, mouse_side, scroll_report,
|
||||
};
|
||||
use modal::deploy_modal;
|
||||
|
||||
use procinfo::LocalProcessInfo;
|
||||
use settings::{AlternateScroll, Settings, Shell, TerminalBlink};
|
||||
|
@ -55,9 +53,10 @@ use thiserror::Error;
|
|||
use gpui::{
|
||||
geometry::vector::{vec2f, Vector2F},
|
||||
keymap::Keystroke,
|
||||
scene::{ClickRegionEvent, DownRegionEvent, DragRegionEvent, UpRegionEvent},
|
||||
ClipboardItem, Entity, ModelContext, MouseButton, MouseMovedEvent, MutableAppContext,
|
||||
ScrollWheelEvent, Task,
|
||||
scene::{
|
||||
ClickRegionEvent, DownRegionEvent, DragRegionEvent, ScrollWheelRegionEvent, UpRegionEvent,
|
||||
},
|
||||
ClipboardItem, Entity, ModelContext, MouseButton, MouseMovedEvent, MutableAppContext, Task,
|
||||
};
|
||||
|
||||
use crate::mappings::{
|
||||
|
@ -68,8 +67,6 @@ use lazy_static::lazy_static;
|
|||
|
||||
///Initialize and register all of our action handlers
|
||||
pub fn init(cx: &mut MutableAppContext) {
|
||||
cx.add_action(deploy_modal);
|
||||
|
||||
terminal_view::init(cx);
|
||||
terminal_container_view::init(cx);
|
||||
}
|
||||
|
@ -1016,10 +1013,10 @@ impl Terminal {
|
|||
}
|
||||
|
||||
///Scroll the terminal
|
||||
pub fn scroll_wheel(&mut self, e: &ScrollWheelEvent, origin: Vector2F) {
|
||||
pub fn scroll_wheel(&mut self, e: ScrollWheelRegionEvent, origin: Vector2F) {
|
||||
let mouse_mode = self.mouse_mode(e.shift);
|
||||
|
||||
if let Some(scroll_lines) = self.determine_scroll_lines(e, mouse_mode) {
|
||||
if let Some(scroll_lines) = self.determine_scroll_lines(&e, mouse_mode) {
|
||||
if mouse_mode {
|
||||
let point = grid_point(
|
||||
e.position.sub(origin),
|
||||
|
@ -1028,7 +1025,7 @@ impl Terminal {
|
|||
);
|
||||
|
||||
if let Some(scrolls) =
|
||||
scroll_report(point, scroll_lines as i32, e, self.last_content.mode)
|
||||
scroll_report(point, scroll_lines as i32, &e, self.last_content.mode)
|
||||
{
|
||||
for scroll in scrolls {
|
||||
self.pty_tx.notify(scroll);
|
||||
|
@ -1051,7 +1048,11 @@ impl Terminal {
|
|||
}
|
||||
}
|
||||
|
||||
fn determine_scroll_lines(&mut self, e: &ScrollWheelEvent, mouse_mode: bool) -> Option<i32> {
|
||||
fn determine_scroll_lines(
|
||||
&mut self,
|
||||
e: &ScrollWheelRegionEvent,
|
||||
mouse_mode: bool,
|
||||
) -> Option<i32> {
|
||||
let scroll_multiplier = if mouse_mode { 1. } else { SCROLL_MULTIPLIER };
|
||||
|
||||
match e.phase {
|
||||
|
|
|
@ -373,7 +373,7 @@ impl TerminalElement {
|
|||
) {
|
||||
let connection = self.terminal;
|
||||
|
||||
let mut region = MouseRegion::new(view_id, None, visible_bounds);
|
||||
let mut region = MouseRegion::new::<Self>(view_id, view_id, visible_bounds);
|
||||
|
||||
// Terminal Emulator controlled behavior:
|
||||
region = region
|
||||
|
@ -444,7 +444,14 @@ impl TerminalElement {
|
|||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.on_scroll(TerminalElement::generic_button_handler(
|
||||
connection,
|
||||
origin,
|
||||
move |terminal, origin, e, _cx| {
|
||||
terminal.scroll_wheel(e, origin);
|
||||
},
|
||||
));
|
||||
|
||||
// Mouse mode handlers:
|
||||
// All mouse modes need the extra click handlers
|
||||
|
@ -745,52 +752,40 @@ impl Element for TerminalElement {
|
|||
fn dispatch_event(
|
||||
&mut self,
|
||||
event: &gpui::Event,
|
||||
bounds: gpui::geometry::rect::RectF,
|
||||
visible_bounds: gpui::geometry::rect::RectF,
|
||||
layout: &mut Self::LayoutState,
|
||||
_bounds: gpui::geometry::rect::RectF,
|
||||
_visible_bounds: gpui::geometry::rect::RectF,
|
||||
_layout: &mut Self::LayoutState,
|
||||
_paint: &mut Self::PaintState,
|
||||
cx: &mut gpui::EventContext,
|
||||
) -> bool {
|
||||
match event {
|
||||
Event::ScrollWheel(e) => visible_bounds
|
||||
.contains_point(e.position)
|
||||
.then(|| {
|
||||
let origin = bounds.origin() + vec2f(layout.size.cell_width, 0.);
|
||||
|
||||
if let Some(terminal) = self.terminal.upgrade(cx.app) {
|
||||
terminal.update(cx.app, |term, _| term.scroll_wheel(e, origin));
|
||||
cx.notify();
|
||||
}
|
||||
})
|
||||
.is_some(),
|
||||
Event::KeyDown(KeyDownEvent { keystroke, .. }) => {
|
||||
if !cx.is_parent_view_focused() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if let Some(view) = self.view.upgrade(cx.app) {
|
||||
view.update(cx.app, |view, cx| {
|
||||
view.clear_bel(cx);
|
||||
view.pause_cursor_blinking(cx);
|
||||
})
|
||||
}
|
||||
|
||||
self.terminal
|
||||
.upgrade(cx.app)
|
||||
.map(|model_handle| {
|
||||
model_handle.update(cx.app, |term, cx| {
|
||||
term.try_keystroke(
|
||||
keystroke,
|
||||
cx.global::<Settings>()
|
||||
.terminal_overrides
|
||||
.option_as_meta
|
||||
.unwrap_or(false),
|
||||
)
|
||||
})
|
||||
})
|
||||
.unwrap_or(false)
|
||||
if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = event {
|
||||
if !cx.is_parent_view_focused() {
|
||||
return false;
|
||||
}
|
||||
_ => false,
|
||||
|
||||
if let Some(view) = self.view.upgrade(cx.app) {
|
||||
view.update(cx.app, |view, cx| {
|
||||
view.clear_bel(cx);
|
||||
view.pause_cursor_blinking(cx);
|
||||
})
|
||||
}
|
||||
|
||||
self.terminal
|
||||
.upgrade(cx.app)
|
||||
.map(|model_handle| {
|
||||
model_handle.update(cx.app, |term, cx| {
|
||||
term.try_keystroke(
|
||||
keystroke,
|
||||
cx.global::<Settings>()
|
||||
.terminal_overrides
|
||||
.option_as_meta
|
||||
.unwrap_or(false),
|
||||
)
|
||||
})
|
||||
})
|
||||
.unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use alacritty_terminal::{index::Point, term::TermMode};
|
|||
use context_menu::{ContextMenu, ContextMenuItem};
|
||||
use gpui::{
|
||||
actions,
|
||||
elements::{ChildView, ParentElement, Stack},
|
||||
elements::{AnchorCorner, ChildView, ParentElement, Stack},
|
||||
geometry::vector::Vector2F,
|
||||
impl_internal_actions,
|
||||
keymap::Keystroke,
|
||||
|
@ -139,8 +139,9 @@ impl TerminalView {
|
|||
ContextMenuItem::item("Close Terminal", pane::CloseActiveItem),
|
||||
];
|
||||
|
||||
self.context_menu
|
||||
.update(cx, |menu, cx| menu.show(action.position, menu_entries, cx));
|
||||
self.context_menu.update(cx, |menu, cx| {
|
||||
menu.show(action.position, AnchorCorner::TopLeft, menu_entries, cx)
|
||||
});
|
||||
|
||||
cx.notify();
|
||||
}
|
||||
|
|
|
@ -28,7 +28,9 @@ impl<'a> TerminalTestContext<'a> {
|
|||
let params = self.cx.update(AppState::test);
|
||||
|
||||
let project = Project::test(params.fs.clone(), [], self.cx).await;
|
||||
let (_, workspace) = self.cx.add_window(|cx| Workspace::new(project.clone(), cx));
|
||||
let (_, workspace) = self
|
||||
.cx
|
||||
.add_window(|cx| Workspace::new(project.clone(), |_, _| unimplemented!(), cx));
|
||||
|
||||
(project, workspace)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue