WIP
This commit is contained in:
parent
2733f91d8c
commit
c42da5c9b9
6 changed files with 77 additions and 80 deletions
|
@ -62,7 +62,7 @@ use std::{
|
|||
},
|
||||
time::Instant,
|
||||
};
|
||||
use terminal::Terminal;
|
||||
use terminal::{Terminal, TerminalBuilder};
|
||||
use thiserror::Error;
|
||||
use util::{defer, post_inc, ResultExt, TryFutureExt as _};
|
||||
|
||||
|
@ -1196,14 +1196,29 @@ impl Project {
|
|||
|
||||
pub fn create_terminal_connection(
|
||||
&mut self,
|
||||
_cx: &mut ModelContext<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 {
|
||||
unimplemented!()
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -221,6 +221,12 @@ pub enum WorkingDirectory {
|
|||
Always { directory: String },
|
||||
}
|
||||
|
||||
impl Default for WorkingDirectory {
|
||||
fn default() -> Self {
|
||||
Self::CurrentProjectDirectory
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Default, Copy, Clone, Hash, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DockAnchor {
|
||||
|
@ -473,30 +479,30 @@ impl Settings {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn terminal_scroll(&self) -> AlternateScroll {
|
||||
*self.terminal_overrides.alternate_scroll.as_ref().unwrap_or(
|
||||
self.terminal_defaults
|
||||
.alternate_scroll
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| &AlternateScroll::On),
|
||||
)
|
||||
fn terminal_setting<F, R: Default + Clone>(&self, f: F) -> R
|
||||
where
|
||||
F: Fn(&TerminalSettings) -> Option<&R>,
|
||||
{
|
||||
f(&self.terminal_overrides)
|
||||
.or_else(|| f(&self.terminal_defaults))
|
||||
.cloned()
|
||||
.unwrap_or_else(|| R::default())
|
||||
}
|
||||
|
||||
pub fn terminal_shell(&self) -> Option<Shell> {
|
||||
self.terminal_overrides
|
||||
.shell
|
||||
.as_ref()
|
||||
.or(self.terminal_defaults.shell.as_ref())
|
||||
.cloned()
|
||||
pub fn terminal_scroll(&self) -> AlternateScroll {
|
||||
self.terminal_setting(|terminal_setting| terminal_setting.alternate_scroll.as_ref())
|
||||
}
|
||||
|
||||
pub fn terminal_shell(&self) -> Shell {
|
||||
self.terminal_setting(|terminal_setting| terminal_setting.shell.as_ref())
|
||||
}
|
||||
|
||||
pub fn terminal_env(&self) -> HashMap<String, String> {
|
||||
self.terminal_overrides.env.clone().unwrap_or_else(|| {
|
||||
self.terminal_defaults
|
||||
.env
|
||||
.clone()
|
||||
.unwrap_or_else(|| HashMap::default())
|
||||
})
|
||||
self.terminal_setting(|terminal_setting| terminal_setting.env.as_ref())
|
||||
}
|
||||
|
||||
pub fn terminal_strategy(&self) -> WorkingDirectory {
|
||||
self.terminal_setting(|terminal_setting| terminal_setting.working_directory.as_ref())
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
|
|
|
@ -198,7 +198,7 @@ impl Dimensions for TerminalSize {
|
|||
#[derive(Error, Debug)]
|
||||
pub struct TerminalError {
|
||||
pub directory: Option<PathBuf>,
|
||||
pub shell: Option<Shell>,
|
||||
pub shell: Shell,
|
||||
pub source: std::io::Error,
|
||||
}
|
||||
|
||||
|
@ -226,24 +226,20 @@ impl TerminalError {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn shell_to_string(&self) -> Option<String> {
|
||||
self.shell.as_ref().map(|shell| match shell {
|
||||
pub fn shell_to_string(&self) -> String {
|
||||
match &self.shell {
|
||||
Shell::System => "<system shell>".to_string(),
|
||||
Shell::Program(p) => p.to_string(),
|
||||
Shell::WithArguments { program, args } => format!("{} {}", program, args.join(" ")),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fmt_shell(&self) -> String {
|
||||
self.shell
|
||||
.clone()
|
||||
.map(|shell| match shell {
|
||||
Shell::System => "<system defined shell>".to_string(),
|
||||
|
||||
Shell::Program(s) => s,
|
||||
Shell::WithArguments { program, args } => format!("{} {}", program, args.join(" ")),
|
||||
})
|
||||
.unwrap_or_else(|| "<none specified, using system defined shell>".to_string())
|
||||
match &self.shell {
|
||||
Shell::System => "<system defined shell>".to_string(),
|
||||
Shell::Program(s) => s.to_string(),
|
||||
Shell::WithArguments { program, args } => format!("{} {}", program, args.join(" ")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,18 +264,18 @@ pub struct TerminalBuilder {
|
|||
impl TerminalBuilder {
|
||||
pub fn new(
|
||||
working_directory: Option<PathBuf>,
|
||||
shell: Option<Shell>,
|
||||
shell: Shell,
|
||||
mut env: HashMap<String, String>,
|
||||
blink_settings: Option<TerminalBlink>,
|
||||
alternate_scroll: AlternateScroll,
|
||||
window_id: usize,
|
||||
) -> Result<TerminalBuilder> {
|
||||
let pty_config = {
|
||||
let alac_shell = shell.clone().and_then(|shell| match shell {
|
||||
let alac_shell = match shell.clone() {
|
||||
Shell::System => None,
|
||||
Shell::Program(program) => Some(Program::Just(program)),
|
||||
Shell::WithArguments { program, args } => Some(Program::WithArgs { program, args }),
|
||||
});
|
||||
};
|
||||
|
||||
PtyConfig {
|
||||
shell: alac_shell,
|
||||
|
|
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
path = "src/terminal_container_view.rs"
|
||||
path = "src/terminal_view.rs"
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
mod persistence;
|
||||
pub mod terminal_element;
|
||||
pub mod terminal_view;
|
||||
|
||||
use crate::persistence::TERMINAL_DB;
|
||||
use crate::terminal_view::TerminalView;
|
||||
use crate::TerminalView;
|
||||
use terminal::alacritty_terminal::index::Point;
|
||||
use terminal::{Event, TerminalBuilder, TerminalError};
|
||||
use terminal::{Event, Terminal, TerminalError};
|
||||
|
||||
use crate::regex_search_for_query;
|
||||
use dirs::home_dir;
|
||||
use gpui::{
|
||||
actions, elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MutableAppContext, Task,
|
||||
View, ViewContext, ViewHandle, WeakViewHandle,
|
||||
};
|
||||
use terminal_view::regex_search_for_query;
|
||||
use util::{truncate_and_trailoff, ResultExt};
|
||||
use workspace::searchable::{SearchEvent, SearchOptions, SearchableItem, SearchableItemHandle};
|
||||
use workspace::{
|
||||
|
@ -36,7 +32,7 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||
|
||||
register_deserializable_item::<TerminalContainer>(cx);
|
||||
|
||||
terminal_view::init(cx);
|
||||
// terminal_view::init(cx);
|
||||
}
|
||||
|
||||
//Make terminal view an enum, that can give you views for the error and non-error states
|
||||
|
@ -81,47 +77,31 @@ impl TerminalContainer {
|
|||
_: &workspace::NewTerminal,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
let strategy = cx
|
||||
.global::<Settings>()
|
||||
.terminal_overrides
|
||||
.working_directory
|
||||
.clone()
|
||||
.unwrap_or(WorkingDirectory::CurrentProjectDirectory);
|
||||
let strategy = cx.global::<Settings>().terminal_strategy();
|
||||
|
||||
let working_directory = get_working_directory(workspace, cx, strategy);
|
||||
let view = cx.add_view(|cx| {
|
||||
TerminalContainer::new(working_directory, false, workspace.database_id(), cx)
|
||||
|
||||
let window_id = cx.window_id();
|
||||
let terminal = workspace.project().update(cx, |project, cx| {
|
||||
project.create_terminal_connection(working_directory, window_id, cx)
|
||||
});
|
||||
|
||||
let view = cx.add_view(|cx| TerminalContainer::new(terminal, workspace.database_id(), cx));
|
||||
workspace.add_item(Box::new(view), cx);
|
||||
}
|
||||
|
||||
///Create a new Terminal view. This spawns a task, a thread, and opens the TTY devices
|
||||
pub fn new(
|
||||
working_directory: Option<PathBuf>,
|
||||
modal: bool,
|
||||
model: anyhow::Result<ModelHandle<Terminal>>,
|
||||
workspace_id: WorkspaceId,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let settings = cx.global::<Settings>();
|
||||
let shell = settings.terminal_shell();
|
||||
let envs = settings.terminal_env();
|
||||
let scroll = settings.terminal_scroll();
|
||||
|
||||
let content = match TerminalBuilder::new(
|
||||
working_directory.clone(),
|
||||
shell,
|
||||
envs,
|
||||
settings.terminal_overrides.blinking.clone(),
|
||||
scroll,
|
||||
cx.window_id(),
|
||||
) {
|
||||
let content = match model {
|
||||
Ok(terminal) => {
|
||||
let terminal = cx.add_model(|cx| terminal.subscribe(cx));
|
||||
let item_id = cx.view_id();
|
||||
let view = cx.add_view(|cx| {
|
||||
TerminalView::from_terminal(terminal, modal, workspace_id, item_id, cx)
|
||||
TerminalView::from_terminal(terminal, false, workspace_id, item_id, cx)
|
||||
});
|
||||
|
||||
cx.subscribe(&view, |_this, _content, event, cx| cx.emit(*event))
|
||||
.detach();
|
||||
TerminalContainerContent::Connected(view)
|
||||
|
@ -136,7 +116,7 @@ impl TerminalContainer {
|
|||
|
||||
TerminalContainer {
|
||||
content,
|
||||
associated_directory: working_directory,
|
||||
associated_directory: None, //working_directory,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,12 +163,7 @@ impl View for ErrorView {
|
|||
//We want to be able to select the text
|
||||
//Want to be able to scroll if the error message is massive somehow (resiliency)
|
||||
|
||||
let program_text = {
|
||||
match self.error.shell_to_string() {
|
||||
Some(shell_txt) => format!("Shell Program: `{}`", shell_txt),
|
||||
None => "No program specified".to_string(),
|
||||
}
|
||||
};
|
||||
let program_text = format!("Shell Program: `{}`", self.error.shell_to_string());
|
||||
|
||||
let directory_text = {
|
||||
match self.error.directory.as_ref() {
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
mod persistence;
|
||||
pub mod terminal_container_view;
|
||||
pub mod terminal_element;
|
||||
|
||||
use std::{ops::RangeInclusive, time::Duration};
|
||||
|
||||
use context_menu::{ContextMenu, ContextMenuItem};
|
||||
|
@ -52,6 +56,7 @@ impl_actions!(terminal, [SendText, SendKeystroke]);
|
|||
impl_internal_actions!(project_panel, [DeployContextMenu]);
|
||||
|
||||
pub fn init(cx: &mut MutableAppContext) {
|
||||
terminal_container_view::init(cx);
|
||||
//Useful terminal views
|
||||
cx.add_action(TerminalView::send_text);
|
||||
cx.add_action(TerminalView::send_keystroke);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue