mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-06 02:37:21 +00:00
Merge pull request #2243 from zed-industries/joseph/z-225-track-open-terminals
Keep track of open terminals
This commit is contained in:
commit
b9573872e1
3 changed files with 76 additions and 30 deletions
|
@ -1,6 +1,7 @@
|
||||||
mod ignore;
|
mod ignore;
|
||||||
mod lsp_command;
|
mod lsp_command;
|
||||||
pub mod search;
|
pub mod search;
|
||||||
|
pub mod terminals;
|
||||||
pub mod worktree;
|
pub mod worktree;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -61,7 +62,8 @@ use std::{
|
||||||
},
|
},
|
||||||
time::{Duration, Instant, SystemTime},
|
time::{Duration, Instant, SystemTime},
|
||||||
};
|
};
|
||||||
use terminal::{Terminal, TerminalBuilder};
|
use terminals::Terminals;
|
||||||
|
|
||||||
use util::{debug_panic, defer, post_inc, ResultExt, TryFutureExt as _};
|
use util::{debug_panic, defer, post_inc, ResultExt, TryFutureExt as _};
|
||||||
|
|
||||||
pub use fs::*;
|
pub use fs::*;
|
||||||
|
@ -123,6 +125,7 @@ pub struct Project {
|
||||||
buffers_being_formatted: HashSet<usize>,
|
buffers_being_formatted: HashSet<usize>,
|
||||||
nonce: u128,
|
nonce: u128,
|
||||||
_maintain_buffer_languages: Task<()>,
|
_maintain_buffer_languages: Task<()>,
|
||||||
|
terminals: Terminals,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum OpenBuffer {
|
enum OpenBuffer {
|
||||||
|
@ -439,6 +442,9 @@ impl Project {
|
||||||
buffers_being_formatted: Default::default(),
|
buffers_being_formatted: Default::default(),
|
||||||
next_language_server_id: 0,
|
next_language_server_id: 0,
|
||||||
nonce: StdRng::from_entropy().gen(),
|
nonce: StdRng::from_entropy().gen(),
|
||||||
|
terminals: Terminals {
|
||||||
|
local_handles: Vec::new(),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,6 +522,9 @@ impl Project {
|
||||||
buffers_being_formatted: Default::default(),
|
buffers_being_formatted: Default::default(),
|
||||||
buffer_snapshots: Default::default(),
|
buffer_snapshots: Default::default(),
|
||||||
nonce: StdRng::from_entropy().gen(),
|
nonce: StdRng::from_entropy().gen(),
|
||||||
|
terminals: Terminals {
|
||||||
|
local_handles: Vec::new(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
for worktree in worktrees {
|
for worktree in worktrees {
|
||||||
let _ = this.add_worktree(&worktree, cx);
|
let _ = this.add_worktree(&worktree, cx);
|
||||||
|
@ -1184,34 +1193,6 @@ impl Project {
|
||||||
!self.is_local()
|
!self.is_local()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_terminal(
|
|
||||||
&mut self,
|
|
||||||
working_directory: Option<PathBuf>,
|
|
||||||
window_id: usize,
|
|
||||||
cx: &mut ModelContext<Self>,
|
|
||||||
) -> Result<ModelHandle<Terminal>> {
|
|
||||||
if self.is_remote() {
|
|
||||||
return Err(anyhow!(
|
|
||||||
"creating terminals as a guest is not supported yet"
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
let settings = cx.global::<Settings>();
|
|
||||||
let shell = settings.terminal_shell();
|
|
||||||
let envs = settings.terminal_env();
|
|
||||||
let scroll = settings.terminal_scroll();
|
|
||||||
|
|
||||||
TerminalBuilder::new(
|
|
||||||
working_directory.clone(),
|
|
||||||
shell,
|
|
||||||
envs,
|
|
||||||
settings.terminal_overrides.blinking.clone(),
|
|
||||||
scroll,
|
|
||||||
window_id,
|
|
||||||
)
|
|
||||||
.map(|builder| cx.add_model(|cx| builder.subscribe(cx)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_buffer(
|
pub fn create_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
text: &str,
|
text: &str,
|
||||||
|
|
63
crates/project/src/terminals.rs
Normal file
63
crates/project/src/terminals.rs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use gpui::{ModelContext, ModelHandle, WeakModelHandle};
|
||||||
|
use settings::Settings;
|
||||||
|
use terminal::{Terminal, TerminalBuilder};
|
||||||
|
|
||||||
|
use crate::Project;
|
||||||
|
|
||||||
|
pub struct Terminals {
|
||||||
|
pub(crate) local_handles: Vec<WeakModelHandle<terminal::Terminal>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Project {
|
||||||
|
pub fn create_terminal(
|
||||||
|
&mut self,
|
||||||
|
working_directory: Option<PathBuf>,
|
||||||
|
window_id: usize,
|
||||||
|
cx: &mut ModelContext<Self>,
|
||||||
|
) -> anyhow::Result<ModelHandle<Terminal>> {
|
||||||
|
if self.is_remote() {
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"creating terminals as a guest is not supported yet"
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
let settings = cx.global::<Settings>();
|
||||||
|
let shell = settings.terminal_shell();
|
||||||
|
let envs = settings.terminal_env();
|
||||||
|
let scroll = settings.terminal_scroll();
|
||||||
|
|
||||||
|
let terminal = TerminalBuilder::new(
|
||||||
|
working_directory.clone(),
|
||||||
|
shell,
|
||||||
|
envs,
|
||||||
|
settings.terminal_overrides.blinking.clone(),
|
||||||
|
scroll,
|
||||||
|
window_id,
|
||||||
|
)
|
||||||
|
.map(|builder| {
|
||||||
|
let terminal_handle = cx.add_model(|cx| builder.subscribe(cx));
|
||||||
|
|
||||||
|
self.terminals
|
||||||
|
.local_handles
|
||||||
|
.push(terminal_handle.downgrade());
|
||||||
|
|
||||||
|
let id = terminal_handle.id();
|
||||||
|
cx.observe_release(&terminal_handle, move |project, _terminal, _cx| {
|
||||||
|
let handles = &mut project.terminals.local_handles;
|
||||||
|
|
||||||
|
if let Some(index) = handles.iter().position(|terminal| terminal.id() == id) {
|
||||||
|
handles.remove(index);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
|
||||||
|
terminal_handle
|
||||||
|
});
|
||||||
|
|
||||||
|
terminal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add a few tests for adding and removing terminal tabs
|
|
@ -11,9 +11,10 @@ pub struct TerminalButton {
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Rename this to `DeployTerminalButton`
|
||||||
impl TerminalButton {
|
impl TerminalButton {
|
||||||
pub fn new(workspace: ViewHandle<Workspace>, cx: &mut ViewContext<Self>) -> Self {
|
pub fn new(workspace: ViewHandle<Workspace>, cx: &mut ViewContext<Self>) -> Self {
|
||||||
// When dock moves, redraw so that the icon and toggle status matches.
|
// When terminal moves, redraw so that the icon and toggle status matches.
|
||||||
cx.subscribe(&workspace, |_, _, _, cx| cx.notify()).detach();
|
cx.subscribe(&workspace, |_, _, _, cx| cx.notify()).detach();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -63,6 +64,7 @@ impl View for TerminalButton {
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_up(MouseButton::Left, move |_, _| {
|
.on_up(MouseButton::Left, move |_, _| {
|
||||||
|
// TODO: Do we need this stuff?
|
||||||
// let dock_pane = workspace.read(cx.app).dock_pane();
|
// let dock_pane = workspace.read(cx.app).dock_pane();
|
||||||
// let drop_index = dock_pane.read(cx.app).items_len() + 1;
|
// let drop_index = dock_pane.read(cx.app).items_len() + 1;
|
||||||
// handle_dropped_item(event, &dock_pane.downgrade(), drop_index, false, None, cx);
|
// handle_dropped_item(event, &dock_pane.downgrade(), drop_index, false, None, cx);
|
||||||
|
|
Loading…
Reference in a new issue